@future-grid/fgp-graph
Version:
fgp-graph is a chart lib based on Dygraphs
263 lines (222 loc) • 9.59 kB
text/typescript
import {GraphCollection, GraphSeries, ViewConfig} from "../../../metadata/configurations";
export default class Series {
private checkBoxDiv?: HTMLDivElement;
private chosenCollection?: GraphCollection;
private currentGraphData?: Array<any>;
private labels?: string[];
private isInit: boolean = true;
private options: Array<HTMLInputElement>;
constructor(public parentElement: Element, public viewConfig: ViewConfig, public g?: Dygraph, onChangeListener?: () => void) {
this.initDom();
this.options = [];
}
private initDom = () => {
let dropdownContainer: HTMLDivElement = document.createElement('div');
dropdownContainer.setAttribute("class", "fgp-series-dropdown");
const multiSelectDiv = document.createElement("div");
multiSelectDiv.setAttribute("class", "graph-series-multi-select");
//------------ select -----------------//
const selectBoxDiv = document.createElement("div");
selectBoxDiv.setAttribute("class", "select-box");
let expanded = false;
selectBoxDiv.addEventListener("click", (e: MouseEvent) => {
// show content
if (!expanded && this.checkBoxDiv) {
this.checkBoxDiv.style.display = "block";
expanded = true;
} else if (expanded && this.checkBoxDiv) {
this.checkBoxDiv.style.display = "none";
expanded = false;
}
});
// create select and put it into div
const select = document.createElement("select");
const placeholder = document.createElement("option");
placeholder.text = "series";
select.add(placeholder);
selectBoxDiv.appendChild(select);
// over select
const overSelect = document.createElement("div");
overSelect.setAttribute("class", "over-select");
selectBoxDiv.append(overSelect);
multiSelectDiv.appendChild(selectBoxDiv);
//------------ options -----------------//
const checkboxDiv = this.checkBoxDiv = document.createElement("div");
checkboxDiv.setAttribute("class", "graph-series-checkboxes");
multiSelectDiv.append(checkboxDiv);
dropdownContainer.appendChild(multiSelectDiv);
this.parentElement.appendChild(dropdownContainer);
};
private selectNDeselect = (series: string, checked: boolean, all: HTMLInputElement | undefined) => {
let visibility = this.g?.getOption('visibility');
const labels = this.g?.getLabels();
if (all) {
//
if ("all" === series) {
all.checked = true;
// select all
if (visibility && labels) {
//
labels.forEach((label: string, index: number) => {
if (label != "x") {
visibility[index - 1] = true;
let options = this.options;
options[index - 1].checked = true;
}
});
// update graph
this.g?.updateOptions({
visibility: visibility
});
}
} else {
// no deselect all
if (visibility && labels) {
let fullChecked = true;
//
labels.forEach((label: string, index: number) => {
if (label == series) {
visibility[index - 1] = checked;
}
});
visibility.map((v: boolean) => {
if (!v) {
fullChecked = false;
}
});
all.checked = fullChecked;
// update graph
this.g?.updateOptions({
visibility: visibility
});
}
}
} else {
if (visibility && labels) {
//
labels.forEach((label: string, index: number) => {
if (label == series) {
visibility[index - 1] = checked;
}
});
// update graph
this.g?.updateOptions({
visibility: visibility
});
}
}
};
/**
* create options
* @param parentElement
*/
private createOptions = (viewConfig: ViewConfig, parentElement?: Element) => {
this.options = [];
// device view or scatter view ?
if (viewConfig.graphConfig.entities.length > 1 && parentElement) {
parentElement.innerHTML = '';
// add select all
const option = document.createElement("label");
const allCheckbox = document.createElement("input");
allCheckbox.type = 'checkbox';
allCheckbox.checked = true;
allCheckbox.addEventListener('click', () => {
this.selectNDeselect("all", allCheckbox.checked, allCheckbox);
});
option.append(allCheckbox);
option.append("All");
parentElement.append(option);
// scatter view
viewConfig.graphConfig.entities.forEach(_child => {
if (!_child.fragment) {
const option = document.createElement("label");
const checkbox = document.createElement("input");
checkbox.type = 'checkbox';
// find out if data column all null or NaN
let hasData = false;
this.labels?.forEach((label, index) => {
if (label === _child.name) {
// 2. check data
this.currentGraphData?.forEach(_data => {
//
if (_data[index + 1] !== null && !isNaN(_data[index + 1])) {
hasData = true;
}
});
}
});
checkbox.checked = hasData;
if (!hasData) {
option.style.pointerEvents = "none";
} else {
checkbox.addEventListener('click', () => {
this.selectNDeselect(_child.name, checkbox.checked, allCheckbox);
});
}
option.append(checkbox);
option.append(`${_child.name}`);
this.options.push(checkbox);
parentElement.append(option);
}
});
} else if (viewConfig.graphConfig.entities.length === 1 && parentElement) {
// device view
parentElement.innerHTML = '';
if (this.chosenCollection) {
//
this.chosenCollection.series.forEach(_series => {
const option = document.createElement("label");
console.log(`${_series.visibility}`);
const checkbox = document.createElement("input");
checkbox.type = 'checkbox';
// find out if data column all null or NaN
let hasData = false;
this.labels?.forEach((label, index) => {
if (label === _series.label) {
// 2. check data
this.currentGraphData?.forEach(_data => {
//
if (_data[index + 1] !== null && !isNaN(_data[index + 1])) {
hasData = true;
}
});
}
});
checkbox.checked = (!(_series.visibility !== undefined && !_series.visibility));
if(checkbox.checked && !hasData){
checkbox.checked = hasData;
}
if (!hasData) {
option.style.pointerEvents = "none";
} else {
checkbox.addEventListener('click', () => {
this.selectNDeselect(_series.label, checkbox.checked, undefined);
});
}
option.append(checkbox);
option.append(`${_series.label}`);
this.options.push(checkbox);
parentElement.append(option);
});
}
}
};
public setData = (data: any, labels: string[], collection: GraphCollection) => {
this.chosenCollection = collection;
this.currentGraphData = data;
this.labels = labels;
// update options ups to labels and data
this.createOptions(this.viewConfig, this.checkBoxDiv);
};
/**
* update dropdown selection
* @param checked
* @param index
*/
public updateOption = (checked: boolean, index: number) => {
console.log(`${checked} ${index} ${this.options[index]}`);
if (this.options[index]) {
this.options[index].checked = checked;
}
};
}