UNPKG

@grafana/ui

Version:
327 lines (324 loc) • 9.77 kB
import { reduceField, fieldReducers, ReducerID, getDisplayProcessor } from '@grafana/data'; import { StackingMode, GraphDrawStyle, GraphTransform } from '@grafana/schema'; import { attachDebugger } from '../../utils/debug.mjs'; import { createLogger } from '../../utils/logger.mjs'; import { buildScaleKey } from './internal.mjs'; "use strict"; const paddingSide = (u, side, sidesWithAxes) => { let hasCrossAxis = side % 2 ? sidesWithAxes[0] || sidesWithAxes[2] : sidesWithAxes[1] || sidesWithAxes[3]; return sidesWithAxes[side] || !hasCrossAxis ? 0 : 8; }; const DEFAULT_PLOT_CONFIG = { ms: 1, focus: { alpha: 1 }, cursor: { focus: { prox: 30 } }, legend: { show: false }, padding: [paddingSide, paddingSide, paddingSide, paddingSide], series: [], hooks: {} }; var StackDirection = /* @__PURE__ */ ((StackDirection2) => { StackDirection2[StackDirection2["Pos"] = 1] = "Pos"; StackDirection2[StackDirection2["Neg"] = -1] = "Neg"; return StackDirection2; })(StackDirection || {}); function getStackingBands(group) { let bands = []; let { series, dir } = group; let lastIdx = series.length - 1; let rSeries = series.slice().reverse(); rSeries.forEach((si, i) => { if (i !== lastIdx) { let nextIdx = rSeries[i + 1]; bands.push({ series: [si, nextIdx], // fill direction is inverted from stack direction dir: -1 * dir }); } }); return bands; } function getStackingGroups(frame) { let groups = /* @__PURE__ */ new Map(); frame.fields.forEach(({ config, values, type }, i) => { var _a; if (i === 0) { return; } let { custom } = config; if (custom == null) { return; } if ((_a = custom.hideFrom) == null ? void 0 : _a.viz) { return; } let { stacking } = custom; if (stacking == null) { return; } let { mode: stackingMode, group: stackingGroup } = stacking; if (stackingMode === StackingMode.None) { return; } let transform = custom.transform; let stackDir = getStackDirection(transform, values); let drawStyle = custom.drawStyle; let drawStyle2 = drawStyle === GraphDrawStyle.Bars ? custom.barAlignment : drawStyle === GraphDrawStyle.Line ? custom.lineInterpolation : null; let stackKey = `${stackDir}|${stackingMode}|${stackingGroup}|${buildScaleKey( config, type )}|${drawStyle}|${drawStyle2}`; let group = groups.get(stackKey); if (group == null) { group = { series: [], dir: stackDir }; groups.set(stackKey, group); } group.series.push(i); }); return [...groups.values()]; } function preparePlotData2(frame, stackingGroups, onStackMeta) { let data = Array(frame.fields.length); let stacksQty = stackingGroups.length; let dataLen = frame.length; let zeroArr = stacksQty > 0 ? Array(dataLen).fill(0) : []; let falseArr = stacksQty > 0 ? Array(dataLen).fill(false) : []; let accums = Array.from({ length: stacksQty }, () => zeroArr.slice()); let anyValsAtX = Array.from({ length: stacksQty }, () => falseArr.slice()); stackingGroups.forEach((group, groupIdx) => { let groupValsAtX = anyValsAtX[groupIdx]; group.series.forEach((seriesIdx) => { var _a, _b; let field = frame.fields[seriesIdx]; if ((_b = (_a = field.config.custom) == null ? void 0 : _a.hideFrom) == null ? void 0 : _b.viz) { return; } let vals = field.values; for (let i = 0; i < dataLen; i++) { if (vals[i] != null) { groupValsAtX[i] = true; } } }); }); frame.fields.forEach((field, i) => { var _a, _b; let vals = field.values; if (i === 0) { data[i] = vals; return; } let { custom } = field.config; if (!custom || ((_a = custom.hideFrom) == null ? void 0 : _a.viz)) { data[i] = vals; return; } if (custom.transform === GraphTransform.Constant) { let firstValIdx = vals.findIndex((v) => v != null); let firstVal = vals[firstValIdx]; vals = Array(vals.length).fill(void 0); vals[firstValIdx] = firstVal; } else { vals = vals.slice(); if (custom.transform === GraphTransform.NegativeY) { for (let i2 = 0; i2 < vals.length; i2++) { if (vals[i2] != null) { vals[i2] *= -1; } } } } let stackingMode = (_b = custom.stacking) == null ? void 0 : _b.mode; if (!stackingMode || stackingMode === StackingMode.None) { data[i] = vals; } else { let stackIdx = stackingGroups.findIndex((group) => group.series.indexOf(i) > -1); let accum = accums[stackIdx]; let groupValsAtX = anyValsAtX[stackIdx]; let stacked = data[i] = Array(dataLen); for (let i2 = 0; i2 < dataLen; i2++) { let v = vals[i2]; if (v != null) { stacked[i2] = accum[i2] += v; } else { stacked[i2] = groupValsAtX[i2] ? accum[i2] : v; } } } }); if (onStackMeta) { let accumsBySeriesIdx = data.map((vals, i) => { let stackIdx = stackingGroups.findIndex((group) => group.series.indexOf(i) > -1); return stackIdx !== -1 ? accums[stackIdx] : vals; }); onStackMeta({ totals: accumsBySeriesIdx }); } frame.fields.forEach((field, i) => { var _a, _b, _c, _d; if (i === 0 || ((_b = (_a = field.config.custom) == null ? void 0 : _a.hideFrom) == null ? void 0 : _b.viz)) { return; } let stackingMode = (_d = (_c = field.config.custom) == null ? void 0 : _c.stacking) == null ? void 0 : _d.mode; if (stackingMode === StackingMode.Percent) { let stackIdx = stackingGroups.findIndex((group2) => group2.series.indexOf(i) > -1); let accum = accums[stackIdx]; let group = stackingGroups[stackIdx]; let stacked = data[i]; for (let i2 = 0; i2 < dataLen; i2++) { let v = stacked[i2]; if (v != null) { stacked[i2] = accum[i2] === 0 ? 0 : group.dir * (v / accum[i2]); } } } }); return data; } function findMidPointYPosition(u, idx) { let y; let sMaxIdx = 1; let sMinIdx = 1; let max = u.data[1][idx]; let min = u.data[1][idx]; for (let i = 1; i < u.data.length; i++) { const sData = u.data[i]; const sVal = sData[idx]; if (sVal != null) { if (max == null) { max = sVal; } else { if (sVal > max) { max = u.data[i][idx]; sMaxIdx = i; } } if (min == null) { min = sVal; } else { if (sVal < min) { min = u.data[i][idx]; sMinIdx = i; } } } } if (min == null && max == null) { y = void 0; } else if (min != null && max != null) { y = (u.valToPos(min, u.series[sMinIdx].scale) + u.valToPos(max, u.series[sMaxIdx].scale)) / 2; } else { y = u.valToPos(min || max, u.series[sMaxIdx || sMinIdx].scale); } if (y !== void 0 && y < 0) { y = u.bbox.height / devicePixelRatio; } return y; } function getStackDirection(transform, data) { const hasNegSamp = hasNegSample(data); if (transform === GraphTransform.NegativeY) { return hasNegSamp ? 1 /* Pos */ : -1 /* Neg */; } return hasNegSamp ? -1 /* Neg */ : 1 /* Pos */; } function hasNegSample(data, samples = 100) { const len = data.length; if (len === 0) { return false; } let firstIdx = 0; let lastIdx = len - 1; while (firstIdx <= lastIdx && data[firstIdx] == null) { firstIdx++; } while (lastIdx >= firstIdx && data[lastIdx] == null) { lastIdx--; } let negCount = 0; let posCount = 0; if (lastIdx >= firstIdx) { const stride = Math.max(1, Math.floor((lastIdx - firstIdx + 1) / samples)); for (let i = firstIdx; i <= lastIdx; i += stride) { const v = data[i]; if (v != null && typeof v === "number") { if (v < 0 || Object.is(v, -0)) { negCount++; } else if (v > 0) { posCount++; } } } if (negCount > posCount) { return true; } } return false; } const getDisplayValuesForCalcs = (calcs, field, theme) => { var _a; if (!(calcs == null ? void 0 : calcs.length)) { return []; } const defaultFormatter = (v) => v == null ? "-" : v.toFixed(1); const fmt = (_a = field.display) != null ? _a : defaultFormatter; let countFormatter = null; const fieldCalcs = reduceField({ field, reducers: calcs }); return calcs.map((reducerId) => { const fieldReducer = fieldReducers.get(reducerId); let formatter = fmt; if (fieldReducer.id === ReducerID.diffperc) { formatter = getDisplayProcessor({ field: { ...field, config: { ...field.config, unit: "percent" } }, theme }); } if (fieldReducer.id === ReducerID.count || fieldReducer.id === ReducerID.changeCount || fieldReducer.id === ReducerID.distinctCount) { if (!countFormatter) { countFormatter = getDisplayProcessor({ field: { ...field, config: { ...field.config, unit: "none" } }, theme }); } formatter = countFormatter; } return { ...formatter(fieldCalcs[reducerId]), title: fieldReducer.name, description: fieldReducer.description }; }); }; const pluginLogger = createLogger("uPlot"); const pluginLog = pluginLogger.logger; attachDebugger("graphng", void 0, pluginLogger); export { DEFAULT_PLOT_CONFIG, findMidPointYPosition, getDisplayValuesForCalcs, getStackingBands, getStackingGroups, pluginLog, pluginLogger, preparePlotData2 }; //# sourceMappingURL=utils.mjs.map