UNPKG

rms-sparklines

Version:
301 lines (257 loc) 9.66 kB
// Copyright 2018 Rodrigo Silveira // // Permission is hereby granted, free of charge, to any person obtaining a copy of // this software and associated documentation files (the "Software"), to deal in // the Software without restriction, including without limitation the rights to // use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of // the Software, and to permit persons to whom the Software is furnished to do so, // subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. import { html, render, TemplateResult } from 'lit-html'; import { BarChart } from '../../util-lib/src/bar-chart'; import { CssColorString } from '../../util-lib/src/valid-colors'; export class RmsSparklineBarChart extends HTMLElement { public barHeightsArray: number[] = []; VALID_CHART_TYPES: string = ['positive', 'negative', 'dual', 'tri'].join(); private cssColorString: CssColorString = null; private barChart: BarChart; VALID_TYPES: string[] = ['positive', 'negative', 'dual', 'tri']; POSITIVE = 0; NEGATIVE = 1; DUAL = 2; TRI = 3; constructor() { super(); this.attachShadow({ mode: 'open' }); this.cssColorString = new CssColorString(); } static get observedAttributes(): string[] { return ['barGap', 'barHeights', 'chartType', 'className', 'fillColorMinus', 'fillColorPlus', 'height', 'fillColorZero', 'minimumBarWidth', 'width']; } connectedCallback() { this.upgradeProperties(); this.render(); } disconnectedCallback() { } attributeChangedCallback(_name: string, _oldValue: any, _newValue: any) { this.render(); } private upgradeProperties() { // Support lazy properties https://developers.google.com/web/fundamentals/web-components/best-practices#lazy-properties (<any>this).constructor['observedAttributes'].forEach((prop: string) => { if (this.hasOwnProperty(prop)) { const value = (<any>this)[prop]; delete (<any>this)[prop]; (<any>this)[prop] = value; } }); } get barGap(): number { if (this.hasAttribute('barGap')) { return Number(this.getAttribute('barGap')); } else { return 0; } } set barGap(value: number) { if (value) { this.setAttribute('barGap', String(value)); } else { this.removeAttribute('barGap'); } } get barHeights(): string { return this.getAttribute('barHeights'); } set barHeights(value: string) { if (value) { this.setAttribute('barHeights', value); } else { this.removeAttribute('barHeights'); } } get chartType(): string { return this.getAttribute('chartType'); } set chartType(value: string) { if (value) { this.setAttribute('chartType', value); } else { this.removeAttribute('chartType'); } } get className(): string { return this.getAttribute('className'); } set className(value: string) { if (value) { this.setAttribute('className', value); } else { this.removeAttribute('className'); } } get fillColorMinus(): string { return this.getAttribute('fillColorMinus'); } set fillColorMinus(value: string) { if (value) { this.setAttribute('fillColorMinus', value); } else { this.removeAttribute('fillColorMinus'); } } get fillColorPlus(): string { return this.getAttribute('fillColorPlus'); } set fillColorPlus(value: string) { if (value) { this.setAttribute('fillColorPlus', value); } else { this.removeAttribute('fillColorPlus'); } } get fillColorZero(): string { return this.getAttribute('fillColorZero'); } set fillColorZero(value: string) { if (value) { this.setAttribute('fillColorZero', value); } else { this.removeAttribute('fillColorZero'); } } get height(): number { if (this.hasAttribute('height')) { return Number(this.getAttribute('height')); } else { return 0; } } set height(value: number) { if (value) { this.setAttribute('height', String(value)); } else { this.removeAttribute('height'); } } get minimumBarWidth(): number { if (this.hasAttribute('minimumBarWidth')) { return Number(this.getAttribute('minimumBarWidth')); } else { return 0; } } set minimumBarWidth(value: number) { if (value) { this.setAttribute('minimumBarWidth', String(value)); } else { this.removeAttribute('minimumBarWidth'); } } get width(): number { if (this.hasAttribute('width')) { return Number(this.getAttribute('width')); } else { return 0; } } set width(value: number) { if (value) { this.setAttribute('width', String(value)); } else { this.removeAttribute('width'); } } private get styles(): TemplateResult { return html` <style> :host { display: inline-block; verticalAlign: top; } :host([hidden]) { display: none; } .content { } </style> `; } private get template(): TemplateResult { // console.log('RmsSparklineBarChart::template'); const canvasEl = document.createElement('canvas') as HTMLCanvasElement; canvasEl.width = this.width; canvasEl.height = this.height; if (this.className && this.className !== ``) { canvasEl.classList.add(this.className); } this.barChart = new BarChart(canvasEl, this.chartType, this.barHeightsArray, this.minimumBarWidth, this.barGap, this.fillColorMinus, this.fillColorZero, this.fillColorPlus); this.barChart.draw(); return html` ${this.styles} <div class="content"> ${canvasEl} <slot></slot> </div> `; } render() { const __this: any = this; // console.log('RmsSparklineBarChart::render'); // Little debugging // // console.log('::render - chartType: ' + this.chartType); // console.log('::render - barHeights: ' + JSON.stringify(this.barHeights)); // console.log('::render - minimumBarWidth: ' + this.minimumBarWidth); // console.log('::render - barGap: ' + this.barGap); // console.log('::render - fillColorMinus: ' + this.fillColorMinus); // console.log('::render - fillColorZero: ' + this.fillColorZero); // console.log('::render - fillColorPlus: ' + this.fillColorPlus); // console.log('::render - width: ' + this.width); // console.log('::render - height: ' + this.height); // ensure attribute coherence // if (this.VALID_CHART_TYPES.indexOf(this.chartType) === -1) { return; } switch (this.chartType) { case this.VALID_TYPES[this.POSITIVE]: break; case this.VALID_TYPES[this.NEGATIVE]: break; case this.VALID_TYPES[this.DUAL]: break; case this.VALID_TYPES[this.TRI]: break; default: break; } if (!this.barHeights) { return; } this.barHeightsArray = JSON.parse(this.barHeights); if (this.barHeightsArray.length === 0) { return; } if (this.minimumBarWidth < 3) {return; } if (this.barGap < 1) { return; } if (!this.cssColorString.isValid(this.fillColorMinus)) { return; } if (!this.cssColorString.isValid(this.fillColorZero)) { return; } if (!this.cssColorString.isValid(this.fillColorPlus)) { return; } if (this.width === 0) { return; } if (this.height === 0) { return; } render(this.template, this.shadowRoot); this.addEventListener('mousemove', function(event: any) { // console.log(`RmsSparklineInlineNew::addEventListener`); // Note that when this function is called, this points to the target element! __this.barChart.handleMouseMove(event, this); }); this.addEventListener('mouseout', function() { // console.log(`RmsSparklineInlineNew::addEventListener`); __this.barChart.handleMouseOut(); }); } } window.customElements.define('rms-sparkline-bar-chart', RmsSparklineBarChart);