mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
95 lines
2.8 KiB
TypeScript
95 lines
2.8 KiB
TypeScript
// Plugin for drawing stripe bars on top of any timeseries barchart
|
|
// Based on cover DIV element with repeating-linear-gradient style
|
|
|
|
import { ChartPoint, default as ChartJS } from "chart.js";
|
|
import moment, { Moment } from "moment";
|
|
import get from "lodash/get";
|
|
|
|
const defaultOptions = {
|
|
interval: 61,
|
|
stripeMinutes: 10,
|
|
stripeColor: "#ffffff08",
|
|
}
|
|
|
|
export const ZebraStripes = {
|
|
updated: null as Moment, // timestamp which all stripe movements based on
|
|
options: {},
|
|
|
|
getOptions(chart: ChartJS) {
|
|
return get(chart, "options.plugins.ZebraStripes");
|
|
},
|
|
|
|
getLastUpdate(chart: ChartJS) {
|
|
const data = chart.data.datasets[0].data[0] as ChartPoint;
|
|
return moment.unix(parseInt(data.x as string));
|
|
},
|
|
|
|
getStripesElem(chart: ChartJS) {
|
|
return chart.canvas.parentElement.querySelector(".zebra-cover");
|
|
},
|
|
|
|
removeStripesElem(chart: ChartJS) {
|
|
const elem = this.getStripesElem(chart);
|
|
if (!elem) return;
|
|
chart.canvas.parentElement.removeChild(elem);
|
|
},
|
|
|
|
renderStripes(chart: ChartJS) {
|
|
if (!chart.data.datasets.length) return;
|
|
const { interval, stripeMinutes, stripeColor } = this.options;
|
|
const { top, left, bottom, right } = chart.chartArea;
|
|
const step = (right - left) / interval;
|
|
const stripeWidth = step * stripeMinutes;
|
|
const cover = document.createElement("div");
|
|
const styles = cover.style;
|
|
|
|
if (this.getStripesElem(chart)) return;
|
|
|
|
cover.className = "zebra-cover";
|
|
styles.width = right - left + "px";
|
|
styles.left = left + "px";
|
|
styles.top = top + "px";
|
|
styles.height = bottom - top + "px";
|
|
styles.backgroundImage = `
|
|
repeating-linear-gradient(to right, ${stripeColor} 0px, ${stripeColor} ${stripeWidth}px,
|
|
transparent ${stripeWidth}px, transparent ${stripeWidth * 2 + step}px)
|
|
`;
|
|
chart.canvas.parentElement.appendChild(cover);
|
|
},
|
|
|
|
afterInit(chart: ChartJS) {
|
|
if (!chart.data.datasets.length) return;
|
|
this.options = {
|
|
...defaultOptions,
|
|
...this.getOptions(chart)
|
|
}
|
|
this.updated = this.getLastUpdate(chart);
|
|
},
|
|
|
|
afterUpdate(chart: ChartJS) {
|
|
this.renderStripes(chart);
|
|
},
|
|
|
|
resize(chart: ChartJS) {
|
|
this.removeStripesElem(chart);
|
|
},
|
|
|
|
afterDatasetUpdate(chart: ChartJS): void {
|
|
if (!this.updated) this.updated = this.getLastUpdate(chart);
|
|
|
|
const { interval } = this.options;
|
|
const { left, right } = chart.chartArea;
|
|
const step = (right - left) / interval;
|
|
const diff = moment(this.updated).diff(this.getLastUpdate(chart), "minutes");
|
|
const minutes = Math.abs(diff);
|
|
|
|
this.removeStripesElem(chart);
|
|
this.renderStripes(chart);
|
|
|
|
if (minutes > 0) {
|
|
// Move position regarding to difference in time
|
|
const cover = this.getStripesElem(chart);
|
|
cover.style.backgroundPositionX = -step * minutes + "px";
|
|
}
|
|
}
|
|
} |