@future-grid/fgp-graph
Version:
fgp-graph is a chart lib based on Dygraphs
142 lines (111 loc) • 5.75 kB
text/typescript
import { GraphCollection, ViewConfig } from "../../../metadata/configurations";
import utils from "../../utils";
export default class Intervals {
private dateWindow: [number, number] = [0, 0];
private dateRange: [number, number] = [0, 0];
private readonly collection: GraphCollection[];
private readonly options: Array<{ label: string, value: number }>;
private dropdownOptions: Array<HTMLOptionElement>;
constructor(public parentElement: Element, public viewConfig: ViewConfig, public g?: Dygraph, public intervalSelectionListener?: (collection: GraphCollection, dateWindow: [number, number]) => void) {
this.collection = viewConfig.graphConfig.collections;
this.options = [];
this.dropdownOptions = [];
this.initDom();
}
private initDom = () => {
// dropdown container
let dropdownContainer: HTMLDivElement = document.createElement('div');
dropdownContainer.setAttribute("class", "fgp-intervals-dropdown");
// create select
const select = document.createElement("select");
//sort
this.viewConfig.ranges?.sort((current, next) => {
return next.value - current.value;
});
//
if (this.viewConfig.ranges) {
this.viewConfig.ranges.forEach(_range => {
const option = document.createElement('option');
option.text = _range.name;
option.value = _range.value.toString();
option.selected = !!_range.show;
select.add(option);
this.dropdownOptions.push(option);
this.options.push({ label: _range.name, value: _range.value });
});
//
}
select.addEventListener("change", (e: Event) => {
// get config
const chosenInterval = this.viewConfig.ranges ? this.viewConfig.ranges[select.selectedIndex] : null;
if (chosenInterval && this.dateWindow) {
// get the middle timestamp of current timeWindow.
let middleDatetime = this.dateWindow[0] + (this.dateWindow[1] - this.dateWindow[0]) / 2;
let halfConfigRequire = chosenInterval.value / 2;
let start = (middleDatetime - halfConfigRequire) > this.dateRange[0] ? (middleDatetime - halfConfigRequire) : this.dateRange[0];
let end = (middleDatetime + halfConfigRequire) > this.dateRange[1] ? this.dateRange[1] : (middleDatetime + halfConfigRequire);
// fix 2 sides problem
if ((middleDatetime + halfConfigRequire) > this.dateRange[1]) {
end = this.dateRange[1];
start = end - chosenInterval.value;
if (start < this.dateRange[0]) {
start = this.dateRange[0];
}
} else if ((middleDatetime - halfConfigRequire) < this.dateRange[0]) {
start = this.dateRange[0];
end = start + chosenInterval.value;
if (end > this.dateRange[1]) {
end = this.dateRange[1]
}
}
let potentialDateWindow: [number, number] = [start, end];
// find collection base on new date window
const chosenCollection = utils.findBestCollection(this.collection, potentialDateWindow);
if (this.intervalSelectionListener && chosenCollection) {
this.intervalSelectionListener(chosenCollection, potentialDateWindow);
}
}
});
dropdownContainer.appendChild(select);
// add container to header
this.parentElement.appendChild(dropdownContainer);
};
public setDateWindow = (dateWindow: Array<number>, dateRange: Array<number>) => {
// check if different
if (this.dateWindow[0] !== dateWindow[0] || this.dateWindow[1] !== dateWindow[1]) {
this.dateWindow = [dateWindow[0], dateWindow[1]];
}
if (this.dateRange[0] !== dateRange[0] || this.dateRange[1] !== dateRange[1]) {
this.dateRange = [dateRange[0], dateRange[1]];
}
// find best option for dropdown base on date window
// if (this.options) {
// // find best one
// const gap = this.dateWindow[1] - this.dateWindow[0];
// let bestInterval: { label: string, value: number } | undefined = undefined;
// if (this.options[0] && gap >= this.options[0].value) {
// bestInterval = this.options[0];
// } else {
// bestInterval = this.options.find((op, index) => {
// if (this.options[index - 1]) {
// return gap >= op.value && gap < (this.options[index - 1].value);
// }
// });
// }
// // if options doesn't exist, ignore it.
// if (!bestInterval && this.options && this.options.length > 0) {
// // check if gap less than the smallest one
// if (gap <= this.options[this.options.length - 1].value) {
// bestInterval = this.options[this.options.length - 1];
// }
// }
// if (bestInterval) {
// console.log(`Best: ${bestInterval?.label}, Gap: ${new Date(this.dateWindow[0])} ${new Date(this.dateWindow[1])}`);
// // reset selection
// this.dropdownOptions.forEach(op => {
// op.selected = bestInterval?.label === op.text;
// })
// }
// }
};
}