UNPKG

@grafana/ui

Version:
211 lines (208 loc) 6.32 kB
import { merge } from 'lodash'; import uPlot from 'uplot'; import { DefaultTimeZone, getTimeZoneInfo } from '@grafana/data'; import { AxisPlacement } from '@grafana/schema'; import { pluginLog, DEFAULT_PLOT_CONFIG, getStackingBands } from '../utils.mjs'; import { UPlotAxisBuilder } from './UPlotAxisBuilder.mjs'; import { UPlotScaleBuilder } from './UPlotScaleBuilder.mjs'; import { UPlotSeriesBuilder } from './UPlotSeriesBuilder.mjs'; import { getThresholdsDrawHook } from './UPlotThresholds.mjs'; "use strict"; const cursorDefaults = { // prevent client-side zoom from triggering at the end of a selection drag: { setScale: false }, points: { /*@ts-ignore*/ size: (u, seriesIdx) => u.series[seriesIdx].points.size * 2, /*@ts-ignore*/ width: (u, seriesIdx, size) => size / 4 }, focus: { prox: 30 } }; class UPlotConfigBuilder { constructor(timeZone = DefaultTimeZone) { this.uid = Math.random().toString(36).slice(2); this.series = []; this.axes = {}; this.scales = []; this.bands = []; this.stackingGroups = []; this.hasLeftAxis = false; this.hooks = {}; this.tz = void 0; this.mode = 1; this.frames = void 0; // to prevent more than one threshold per scale this.thresholds = {}; this.padding = void 0; this.prepData = void 0; // Exposed to let the container know the primary scale keys this.scaleKeys = ["", ""]; this.tzDate = (ts) => { let date = new Date(ts); return this.tz ? uPlot.tzDate(date, this.tz) : date; }; var _a; this.tz = (_a = getTimeZoneInfo(timeZone, Date.now())) == null ? void 0 : _a.ianaName; } addHook(type, hook) { pluginLog("UPlotConfigBuilder", false, "addHook", type); if (!this.hooks[type]) { this.hooks[type] = []; } this.hooks[type].push(hook); } addThresholds(options) { if (!this.thresholds[options.scaleKey]) { this.thresholds[options.scaleKey] = options; this.addHook("drawClear", getThresholdsDrawHook(options)); } } addAxis(props) { var _a, _b, _c; props.placement = (_a = props.placement) != null ? _a : AxisPlacement.Auto; props.grid = (_b = props.grid) != null ? _b : {}; let scaleKey = props.scaleKey; if (scaleKey === "x") { scaleKey += (_c = props.timeZone) != null ? _c : ""; } if (this.axes[scaleKey]) { this.axes[scaleKey].merge(props); return; } if (props.placement === AxisPlacement.Auto) { props.placement = this.hasLeftAxis ? AxisPlacement.Right : AxisPlacement.Left; } if (props.placement === AxisPlacement.Left) { this.hasLeftAxis = true; } if (props.placement === AxisPlacement.Hidden) { props.grid.show = false; props.size = 0; } this.axes[scaleKey] = new UPlotAxisBuilder(props); } getAxisPlacement(scaleKey) { var _a; const axis = this.axes[scaleKey]; return (_a = axis == null ? void 0 : axis.props.placement) != null ? _a : AxisPlacement.Left; } setCursor(cursor) { this.cursor = merge({}, this.cursor, cursor); } setMode(mode) { this.mode = mode; } setSelect(select) { this.select = select; } addSeries(props) { this.series.push(new UPlotSeriesBuilder(props)); } getSeries() { return this.series; } /** Add or update the scale with the scale key */ addScale(props) { const current = this.scales.find((v) => v.props.scaleKey === props.scaleKey); if (current) { current.merge(props); return; } this.scales.push(new UPlotScaleBuilder(props)); } addBand(band) { this.bands.push(band); } setStackingGroups(groups) { this.stackingGroups = groups; } getStackingGroups() { return this.stackingGroups; } setPrepData(prepData) { this.prepData = (frames) => { this.frames = frames; return prepData(frames, this.getStackingGroups()); }; } setPadding(padding) { this.padding = padding; } getConfig() { if (this.cachedConfig) { return this.cachedConfig; } const config = { ...DEFAULT_PLOT_CONFIG, mode: this.mode, series: [ this.mode === 2 ? null : { value: () => "" } ] }; config.axes = this.ensureNonOverlappingAxes(Object.values(this.axes)).map((a) => a.getConfig()); config.series = [...config.series, ...this.series.map((s) => s.getConfig())]; config.scales = this.scales.reduce((acc, s) => { return { ...acc, ...s.getConfig() }; }, {}); config.hooks = this.hooks; config.select = this.select; const pointColorFn = (alphaHex = "") => (u, seriesIdx) => { let s = u.series[seriesIdx].points._stroke; if (typeof s !== "string") { let field = this.frames[0].fields[seriesIdx]; s = field.display(field.values[u.cursor.idxs[seriesIdx]]).color; } return s + alphaHex; }; config.cursor = merge( {}, cursorDefaults, { points: { stroke: pointColorFn("80"), fill: pointColorFn() } }, this.cursor ); config.tzDate = this.tzDate; if (Array.isArray(this.padding)) { config.padding = this.padding; } this.stackingGroups.forEach((group) => { getStackingBands(group).forEach((band) => { this.addBand(band); }); }); if (this.bands.length) { config.bands = this.bands; } this.cachedConfig = config; return config; } ensureNonOverlappingAxes(axes) { const xAxis = axes.find((a) => a.props.scaleKey === "x"); const axesWithoutGridSet = axes.filter((a) => { var _a; return ((_a = a.props.grid) == null ? void 0 : _a.show) === void 0; }); const firstValueAxisIdx = axesWithoutGridSet.findIndex( (a) => a.props.placement === AxisPlacement.Left || a.props.placement === AxisPlacement.Right || a.props.placement === AxisPlacement.Bottom && a !== xAxis ); for (let i = 0; i < axesWithoutGridSet.length; i++) { if (axesWithoutGridSet[i] === xAxis || i === firstValueAxisIdx) { axesWithoutGridSet[i].props.grid.show = true; } else { axesWithoutGridSet[i].props.grid.show = false; } } return axes; } } export { UPlotConfigBuilder }; //# sourceMappingURL=UPlotConfigBuilder.mjs.map