UNPKG

@future-grid/fgp-graph

Version:

fgp-graph is a chart lib based on Dygraphs

283 lines (242 loc) 11 kB
import { FilterType, GraphCollection, ViewConfig } from "../../../metadata/configurations"; import { Formatters } from "../../formatters"; import moment from "moment-timezone"; import { hsvToRGB } from "../../../services/colorService"; import Series from "./Series"; export default class Filter { private chosenCollection?: GraphCollection; private seriesWidget?: Series; constructor(public parentElement: Element, public viewConfig: ViewConfig, public g?: Dygraph, public lockColorListener?: (isLock: boolean) => void) { this.initDom(); } private setVisibility = (series: Array<string>) => { // set visibility let graphLabels: Array<string> = this.g?.getOption('labels'); let visibility: Array<boolean> = []; let labels = graphLabels.filter((element, index, array) => { if (index != 0) { visibility.push(true); return true; } return false; }); let formatters: Formatters = new Formatters(this.viewConfig.timezone ? this.viewConfig.timezone : moment.tz.guess()); // get current y and y2 axis scaling max and min let ranges: Array<Array<number>> = (<any>this.g).yAxisRanges(); labels.map((value, index, array) => { // never hide mark lines visibility[index] = series.includes(value) || value.indexOf("_markline") != -1; }); if (this.seriesWidget && this.chosenCollection) { // update visibility visibility.forEach((v, i) => { this.seriesWidget?.updateOption(v, i); }); } // set visibility this.g?.updateOptions({ visibility: visibility, axes: { x: { axisLabelFormatter: formatters.axisLabel }, y: { valueRange: ranges[0], axisLabelWidth: 80, labelsKMB: true }, y2: ranges.length > 1 ? { valueRange: ranges[1], axisLabelWidth: 80, labelsKMB: true } : undefined } }); }; private setColors = (colors: Array<string>) => { // check if length match or not let graphLabels = this.g?.getLabels(); let formatters: Formatters = new Formatters(this.viewConfig.timezone ? this.viewConfig.timezone : moment.tz.guess()); let sat = 1.0; let val = 0.5; // get current y and y2 axis scaling max and min let ranges: Array<Array<number>> = (<any>this.g).yAxisRanges(); if (graphLabels && graphLabels.length - 1 === colors.length) { if (this.lockColorListener) { this.lockColorListener(true); } this.g?.updateOptions({ colors: colors, axes: { x: { axisLabelFormatter: formatters.axisLabel }, y: { valueRange: ranges[0], axisLabelWidth: 80, labelsKMB: true }, y2: ranges.length > 1 ? { valueRange: ranges[1], axisLabelWidth: 80, labelsKMB: true } : undefined } }); } else { if (this.viewConfig.graphConfig.entities.length > 1) { if (this.lockColorListener) { this.lockColorListener(false); } this.g?.updateOptions({ colors: undefined, axes: { x: { axisLabelFormatter: formatters.axisLabel }, y: { valueRange: ranges[0], axisLabelWidth: 80, labelsKMB: true }, y2: ranges.length > 1 ? { valueRange: ranges[1], axisLabelWidth: 80, labelsKMB: true } : undefined } }); } else { if (this.chosenCollection) { if (this.lockColorListener) { this.lockColorListener(false); } let defaultColors: Array<string> = []; const num = this.chosenCollection.series.length; this.chosenCollection.series.forEach((series, i) => { let half = Math.ceil(num / 2); let idx = i % 2 ? (half + (i + 1) / 2) : Math.ceil((i + 1) / 2); let hue = (1.0 * idx / (1 + num)); let colorStr = hsvToRGB(hue, sat, val); defaultColors.push(series.color ? series.color : colorStr); }); this.g?.updateOptions({ colors: defaultColors, axes: { x: { axisLabelFormatter: formatters.axisLabel }, y: { valueRange: ranges[0], axisLabelWidth: 80, labelsKMB: true }, y2: ranges.length > 1 ? { valueRange: ranges[1], axisLabelWidth: 80, labelsKMB: true } : undefined } }); } } } }; private initDom = () => { // 2 div buttons and dropdown let filterContainer: HTMLDivElement = document.createElement('div'); filterContainer.setAttribute("class", "fgp-filter-container"); // check buttons if (this.viewConfig.graphConfig.filters && this.viewConfig.graphConfig.filters.buttons) { // create button area const buttons = document.createElement("div"); buttons.setAttribute("class", "fgp-filter-buttons"); // this.viewConfig.graphConfig.filters.buttons.forEach(filter => { let button: HTMLSpanElement = document.createElement("button"); button.className = "fgp-filter-button"; button.textContent = filter.label; button.addEventListener('click', (event) => { // call function and get series list back if (!filter.type || filter.type == FilterType.HIGHLIGHT) { const series: Array<string> = <Array<string>>filter.func(); this.setVisibility(series); } else if (filter.type == FilterType.COLORS) { // let labels: string[] = []; if (this.g) { labels = labels.concat(...this.g.getLabels()); labels = labels.slice(1); } const colors: Array<string> = <Array<string>>filter.func(labels); // update colors this.setColors(colors); } }); // add button buttons.appendChild(button); }); filterContainer.appendChild(buttons); } if (this.viewConfig.graphConfig.filters && this.viewConfig.graphConfig.filters.dropdown) { const select = document.createElement("select"); select.setAttribute("class", "fgp-filter-dropdown"); this.viewConfig.graphConfig.filters.dropdown.forEach(_drop => { // options const option = document.createElement('option'); option.text = _drop.label; option.value = _drop.label; select.add(option); }); select.addEventListener("change", (e: Event) => { if (this.viewConfig.graphConfig.filters && this.viewConfig.graphConfig.filters.dropdown) { const _conf = this.viewConfig.graphConfig.filters.dropdown[select.selectedIndex]; if (!_conf.type || _conf.type == FilterType.HIGHLIGHT) { const series: Array<string> = <Array<string>>_conf.func(); // find entity let finalSeries: Array<string> = []; series.forEach(_series => { let entity = this.viewConfig.graphConfig.entities.find(_entity => { return _entity.id === _series }); // put name into series if (entity) { finalSeries.push(entity.name); } }); // compare then update graph this.setVisibility(finalSeries); } else if (_conf.type == FilterType.COLORS) { let labels: string[] = []; // find entity let finalSeries: Array<string> = []; if (this.g) { labels = labels.concat(...this.g.getLabels()); labels = labels.slice(1); // get series name labels.forEach(_series => { let entity = this.viewConfig.graphConfig.entities.find(_entity => { return _entity.id === _series }); // put name into series if (entity) { finalSeries.push(entity.name); } }); } const colors: Array<string> = <Array<string>>_conf.func(finalSeries); this.setColors(colors); } } }); filterContainer.appendChild(select); } this.parentElement.appendChild(filterContainer); }; public setData = (collection: GraphCollection) => { this.chosenCollection = collection; }; public setSeriesWidget = (seriesWidget: Series) => { this.seriesWidget = seriesWidget; }; }