From 92263ae7ec36753cf9215a7579574eb183b1514c Mon Sep 17 00:00:00 2001 From: John Munsch Date: Fri, 19 Jul 2019 22:12:27 -0500 Subject: [PATCH] Added LitElement versions of the exact same components. --- app/js/litelement-peity.components.js | 235 ++++++++++++++++++ ...ponents.js => vanilla-peity.components.js} | 8 +- package-lock.json | 13 + package.json | 3 +- stories/peity.stories.js | 134 +++++++--- 5 files changed, 355 insertions(+), 38 deletions(-) create mode 100644 app/js/litelement-peity.components.js rename app/js/{peity.components.js => vanilla-peity.components.js} (97%) diff --git a/app/js/litelement-peity.components.js b/app/js/litelement-peity.components.js new file mode 100644 index 0000000..eecdc3d --- /dev/null +++ b/app/js/litelement-peity.components.js @@ -0,0 +1,235 @@ +import { LitElement, html } from 'lit-element'; +import * as d3 from 'd3'; + +class BaseElement extends LitElement { + constructor(delimiter) { + super(); + + this.delimiter = delimiter; + this.data = this._parseData(this.innerHTML); + } + + _parseData(value) { + // Process the data to get an array of numbers. There may be two items + // or many. + let temp = value.split(this.delimiter).map(val => parseFloat(val, 10)); + + // If that didn't result in multiple values, parse again using / + // as our delimiter and expect only two values. + if (temp.length === 1) { + temp = value.split('/'); + + // Create an array with two values. For example, if our two values were + // "1/7", then we create an array with [ 1/7, 6/7 ]. That gives us two + // data parts which make up a very simple pie or donut chart. + if (temp.length === 2) { + return [temp[0] / temp[1], (temp[1] - temp[0]) / temp[1]]; + } + } else { + return temp; + } + } +} + +class LitElementPieElement extends BaseElement { + static get properties() { + return { + data: Array, + delimiter: String, + fill: { + converter: { + fromAttribute: value => { + console.log(value); + return JSON.parse(value); + } + } + }, + height: Number, + innerRadius: Number, + radius: Number, + width: Number + }; + } + + constructor() { + super(','); + + this.fill = ['#ff9900', '#fff4dd', '#ffd592']; + this.innerRadius = 0; + this.radius = 8; + } + + get width() { + return this.radius * 2; + } + + get height() { + return this.radius * 2; + } + + render() { + if (this.data && this.data.length) { + let height = this.height !== undefined ? this.height : this.radius * 2; + let width = this.width !== undefined ? this.width : this.radius * 2; + + this.shadowRoot.innerHTML = ``; + + let svg = d3.select(this.shadowRoot).select('svg'), + g = svg + .append('g') + .attr('transform', `translate(${this.radius},${this.radius})`); + + var pie = d3.pie().sort(null); + + var path = d3 + .arc() + .outerRadius(this.radius) + .innerRadius(this.innerRadius); + + let data = this.data; + + var color = d3 + .scaleLinear() + .domain([0, data.length - 1]) + .range(this.fill); + + // Selects all the arcs in the graph and syncs them up with + // the data for the various slices. + var arc = g + .selectAll('.arc') + .data(pie(data)) + .enter() + .append('g') + .attr('class', 'arc'); + + arc + .append('path') + .attr('d', path) + .attr('fill', function(d) { + return color(d.index); + }); + } + } +} + +class LitElementDonutElement extends LitElementPieElement { + static get properties() { + return Object.assign({}, LitElementPieElement.properties, { + innerRadius: { + type: Number, + attribute: 'inner-radius' + } + }); + } + + constructor() { + super(); + + this.innerRadius = 4; + } +} + +class LitElementLineElement extends BaseElement { + static get properties() { + return { + data: Array, + delimiter: String, + fill: Array, + height: Number, + max: Number, + min: Number, + stroke: String, + strokeWidth: Number, + width: Number + }; + } + + constructor() { + super(','); + + this.fill = ['#c6d9fd']; + this.height = 16; + this.min = 0; + this.stroke = '#4d89f9'; + this.strokeWidth = 1; + this.width = 32; + } + + render() { + if (this.data && this.data.length) { + this.shadowRoot.innerHTML = ``; + + d3.select(this.shadowRoot).select('svg'); + } + } +} + +class LitElementBarElement extends BaseElement { + static get properties() { + return { + data: Array, + delimiter: String, + fill: Array, + height: Number, + max: Number, + min: Number, + padding: Number, + width: Number + }; + } + + constructor() { + super(','); + + this.fill = ['#4d89f9']; + this.height = 16; + this.min = 0; + this.padding = 0.1; + this.width = 32; + } + + render() { + if (this.data && this.data.length) { + this.shadowRoot.innerHTML = ``; + + // Based upon the number of data points and the padding between bars, + // calculate bar width. + let barWidth = + (this.width - (this.data.length - 1) * 0.7) / this.data.length; + + var x = d3 + .scaleLinear() + .domain([0, this.data.length - 1]) + .range([0, (this.data.length - 1) * (barWidth + 0.7)]); + + var y = d3 + .scaleLinear() + .domain([Math.min(this.min, d3.min(this.data)), d3.max(this.data)]) + .range([this.height, 0]); + + // This chart draws from the y-axis upwards for positive values and from the + // y-axis downwards for negative values. + d3.select(this.shadowRoot) + .select('svg') + .selectAll('rect') + .data(this.data) + .enter() + .append('rect') + .attr('fill', this.fill[0]) + .attr('x', (d, i) => x(i)) + .attr('y', d => (d < 0 ? y(0) : y(d))) + .attr('width', barWidth) + .attr('height', d => (d < 0 ? y(d) - y(0) : y(0) - y(d))); + } + } +} + +// Register all of the custom elements for which we created classes. +customElements.define('litelement-pie', LitElementPieElement); +customElements.define('litelement-donut', LitElementDonutElement); +customElements.define('litelement-line', LitElementLineElement); +customElements.define('litelement-bar', LitElementBarElement); diff --git a/app/js/peity.components.js b/app/js/vanilla-peity.components.js similarity index 97% rename from app/js/peity.components.js rename to app/js/vanilla-peity.components.js index 67ff7ba..87bbd8d 100644 --- a/app/js/peity.components.js +++ b/app/js/vanilla-peity.components.js @@ -415,7 +415,7 @@ class BarElement extends BaseElement { } // Register all of the custom elements for which we created classes. -customElements.define('wc-pie', PieElement); -customElements.define('wc-donut', DonutElement); -customElements.define('wc-line', LineElement); -customElements.define('wc-bar', BarElement); +customElements.define('vanilla-pie', PieElement); +customElements.define('vanilla-donut', DonutElement); +customElements.define('vanilla-line', LineElement); +customElements.define('vanilla-bar', BarElement); diff --git a/package-lock.json b/package-lock.json index b7d89ee..ac623d9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6551,6 +6551,19 @@ } } }, + "lit-element": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/lit-element/-/lit-element-2.2.0.tgz", + "integrity": "sha512-Mzs3H7IO4wAnpzqreHw6dQqp9IG+h/oN8X9pgNbMZbE7x6B0aNOwP5Nveox/5HE+65ZfW2PeULEjoHkrwpTnuQ==", + "requires": { + "lit-html": "^1.0.0" + } + }, + "lit-html": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/lit-html/-/lit-html-1.1.1.tgz", + "integrity": "sha512-1WqhkPpj+CKwLRXCCbyRGnWkcFKE4ft2+j8C2zaXwFUK9I2vYDzTuDGPh0H9hZcDBEwoe6YpPC8AO5734EPORQ==" + }, "loader-runner": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-2.4.0.tgz", diff --git a/package.json b/package.json index ed29ae1..d010fa4 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,8 @@ "author": "", "license": "ISC", "dependencies": { - "d3": "^5.9.7" + "d3": "^5.9.7", + "lit-element": "^2.2.0" }, "devDependencies": { "@babel/core": "^7.5.5", diff --git a/stories/peity.stories.js b/stories/peity.stories.js index 7ce2077..d5be0f4 100644 --- a/stories/peity.stories.js +++ b/stories/peity.stories.js @@ -1,73 +1,141 @@ import { document, console } from 'global'; import { storiesOf } from '@storybook/html'; -import '../app/js/peity.components'; +import '../app/js/vanilla-peity.components'; +import '../app/js/litelement-peity.components'; storiesOf('Peity', module) .add( - 'Pie Charts', + 'Vanilla Pie Charts', () => /* html */ `

Pie Charts

- 1/5 - 226/360 - 0.52/1.561 - 1,4 - 226,134 - 0.52,1.041 - 1,2,3,2,2 + 1/5 + 226/360 + 0.52/1.561 + 1,4 + 226,134 + 0.52,1.041 + 1,2,3,2,2
` ) .add( - 'Donut Charts', + 'Vanilla Donut Charts', () => /* html */ `

Donut Charts

- 1/5 - 226/360 - 0.52/1.561 - 1,4 - 226,134 - 0.52,1.041 - 1,2,3,2,2 + 1/5 + 226/360 + 0.52/1.561 + 1,4 + 226,134 + 0.52,1.041 + 1,2,3,2,2
` ) .add( - 'Line Charts', + 'Vanilla Line Charts', () => /* html */ `

Line Charts

- 5,3,9,6,5,9,7,3,5,2 - 5,3,2,-1,-3,-2,2,3,5,2 - 0,-3,-6,-4,-5,-4,-7,-3,-5,-2 + 5,3,9,6,5,9,7,3,5,2 + 5,3,2,-1,-3,-2,2,3,5,2 + 0,-3,-6,-4,-5,-4,-7,-3,-5,-2
` ) .add( - 'Bar Charts', + 'Vanilla Bar Charts', () => /* html */ `

Bar Charts

- 5,3,9,6,5,9,7,3,5,2 - 5,3,2,-1,-3,-2,2,3,5,2 - 0,-3,-6,-4,-5,-4,-7,-3,-5,-2 + 5,3,9,6,5,9,7,3,5,2 + 5,3,2,-1,-3,-2,2,3,5,2 + 0,-3,-6,-4,-5,-4,-7,-3,-5,-2
` ) .add( - 'Attributes', + 'Vanilla Attributes', () => /* html */ `

Attributes

- 1/7 - 2/7 - 3/7 - 4/7 - 5/7 - 6/7 - 7/7 + 1/7 + 2/7 + 3/7 + 4/7 + 5/7 + 6/7 + 7/7 +
` + ) + .add( + 'LitElement Pie Charts', + () => /* html */ ` +

Pie Charts

+ +
+ 1/5 + 226/360 + 0.52/1.561 + 1,4 + 226,134 + 0.52,1.041 + 1,2,3,2,2 +
` + ) + .add( + 'LitElement Donut Charts', + () => /* html */ ` +

Donut Charts

+ +
+ 1/5 + 226/360 + 0.52/1.561 + 1,4 + 226,134 + 0.52,1.041 + 1,2,3,2,2 +
` + ) + .add( + 'LitElement Line Charts', + () => /* html */ ` +

Line Charts

+ +
+ 5,3,9,6,5,9,7,3,5,2 + 5,3,2,-1,-3,-2,2,3,5,2 + 0,-3,-6,-4,-5,-4,-7,-3,-5,-2 +
` + ) + .add( + 'LitElement Bar Charts', + () => /* html */ ` +

Bar Charts

+ +
+ 5,3,9,6,5,9,7,3,5,2 + 5,3,2,-1,-3,-2,2,3,5,2 + 0,-3,-6,-4,-5,-4,-7,-3,-5,-2 +
` + ) + .add( + 'LitElement Attributes', + () => /* html */ ` +

Attributes

+ +
+ 1/7 + 2/7 + 3/7 + 4/7 + 5/7 + 6/7 + 7/7
` );