diff --git a/.betterer.results b/.betterer.results index 116b3c7b307..8844760fb39 100644 --- a/.betterer.results +++ b/.betterer.results @@ -6929,11 +6929,12 @@ exports[`better eslint`] = { "public/app/plugins/panel/barchart/bars.ts:5381": [ [0, 0, 0, "Unexpected any. Specify a different type.", "0"], [0, 0, 0, "Unexpected any. Specify a different type.", "1"], - [0, 0, 0, "Do not use any type assertions.", "2"], - [0, 0, 0, "Unexpected any. Specify a different type.", "3"], - [0, 0, 0, "Do not use any type assertions.", "4"], - [0, 0, 0, "Unexpected any. Specify a different type.", "5"], - [0, 0, 0, "Do not use any type assertions.", "6"] + [0, 0, 0, "Unexpected any. Specify a different type.", "2"], + [0, 0, 0, "Do not use any type assertions.", "3"], + [0, 0, 0, "Unexpected any. Specify a different type.", "4"], + [0, 0, 0, "Do not use any type assertions.", "5"], + [0, 0, 0, "Unexpected any. Specify a different type.", "6"], + [0, 0, 0, "Do not use any type assertions.", "7"] ], "public/app/plugins/panel/barchart/module.tsx:5381": [ [0, 0, 0, "Do not use any type assertions.", "0"], @@ -6944,7 +6945,8 @@ exports[`better eslint`] = { ], "public/app/plugins/panel/barchart/utils.ts:5381": [ [0, 0, 0, "Unexpected any. Specify a different type.", "0"], - [0, 0, 0, "Unexpected any. Specify a different type.", "1"] + [0, 0, 0, "Unexpected any. Specify a different type.", "1"], + [0, 0, 0, "Unexpected any. Specify a different type.", "2"] ], "public/app/plugins/panel/candlestick/CandlestickPanel.tsx:5381": [ [0, 0, 0, "Do not use any type assertions.", "0"], diff --git a/devenv/dev-dashboards/panel-barchart/barchart-label-rotation-skipping.json b/devenv/dev-dashboards/panel-barchart/barchart-label-rotation-skipping.json new file mode 100644 index 00000000000..43d7655053e --- /dev/null +++ b/devenv/dev-dashboards/panel-barchart/barchart-label-rotation-skipping.json @@ -0,0 +1,320 @@ +{ + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": { + "type": "grafana", + "uid": "-- Grafana --" + }, + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "target": { + "limit": 100, + "matchAny": false, + "tags": [], + "type": "dashboard" + }, + "type": "dashboard" + } + ] + }, + "editable": true, + "fiscalYearStartMonth": 0, + "graphTooltip": 0, + "id": 530, + "links": [], + "liveNow": false, + "panels": [ + { + "datasource": { + "type": "testdata", + "uid": "PD8C576611E62080A" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "fillOpacity": 80, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineWidth": 1, + "scaleDistribution": { + "type": "linear" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "decmbytes" + }, + "overrides": [] + }, + "gridPos": { + "h": 14, + "w": 11, + "x": 0, + "y": 0 + }, + "id": 2, + "maxDataPoints": 30, + "options": { + "barRadius": 0, + "barWidth": 0.97, + "groupWidth": 0.7, + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "orientation": "vertical", + "showValue": "auto", + "stacking": "none", + "tooltip": { + "mode": "single", + "sort": "none" + }, + "xTickLabelMaxLength": 6, + "xTickLabelRotation": 45, + "xTickLabelSpacing": 100 + }, + "targets": [ + { + "datasource": { + "type": "testdata", + "uid": "PD8C576611E62080A" + }, + "rawFrameContent": "[\n {\n \"schema\": {\n \"refId\": \"A\",\n \"fields\": [\n {\n \"name\": \"label\",\n \"type\": \"string\",\n \"typeInfo\": {\n \"frame\": \"string\",\n \"nullable\": true\n },\n \"config\": {\n \"interval\": 600000\n }\n },\n {\n \"name\": \"A-series\",\n \"type\": \"number\",\n \"typeInfo\": {\n \"frame\": \"float64\",\n \"nullable\": true\n },\n \"labels\": {},\n \"config\": {}\n }\n ]\n },\n \"data\": {\n \"values\": [\n [\n \"acquisition\",\n \"extension\",\n \"conductor\",\n \"authorise\",\n \"architect\",\n \"illusion\",\n \"congress\",\n \"highlight\",\n \"partnership\",\n \"understanding\",\n \"disagreement\",\n \"personality\",\n \"commerce\",\n \"systematic\",\n \"hesitate\",\n \"business\",\n \"manufacture\",\n \"incredible\",\n \"constitutional\",\n \"prevalence\",\n \"professor\",\n \"entitlement\",\n \"cooperation\",\n \"sickness\",\n \"contrast\",\n \"reference\",\n \"audience\",\n \"discount\",\n \"apparatus\",\n \"disturbance\",\n \"automatic\",\n \"refrigerator\",\n \"elaborate\",\n \"sympathetic\",\n \"integration\",\n \"president\"\n ],\n [\n 306.78931659492116,\n 200.00696051101917,\n 164.90889283973593,\n 518.9385023737021,\n 999.9040675564702,\n 613.9689830172349,\n 773.2337077340269,\n 317.47395634701644,\n 748.3318338316539,\n 606.8039493787173,\n 426.27771317792866,\n 376.47735643253924,\n 66.30635081800493,\n 401.70654338415505,\n 108.86259550477234,\n 182.40284186231278,\n 867.7047958572101,\n 959.3957783599242,\n 396.7606089549935,\n 455.9625595614323,\n 685.4792456298062,\n 368.6567303946707,\n 157.06596562976327,\n 59.54120602048763,\n 406.72723615743973,\n 440.18247585615575,\n 516.0267558264891,\n 258.76006051667315,\n 952.966531725171,\n 554.8746357628739,\n 86.7279280805682,\n 781.2422516386563,\n 754.2723802427706,\n 435.0305712850233,\n 384.43181614983,\n 459.04164596738127\n ]\n ]\n }\n }\n]", + "refId": "A", + "scenarioId": "raw_frame" + } + ], + "title": "Panel Title", + "type": "barchart" + }, + { + "datasource": { + "type": "testdata", + "uid": "PD8C576611E62080A" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "axisSoftMin": 0, + "fillOpacity": 80, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineWidth": 0, + "scaleDistribution": { + "type": "linear" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "decimals": 7, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 14, + "w": 13, + "x": 11, + "y": 0 + }, + "id": 5, + "options": { + "barRadius": 0, + "barWidth": 1, + "groupWidth": 0.82, + "legend": { + "calcs": [ + "max" + ], + "displayMode": "list", + "placement": "right", + "showLegend": true + }, + "orientation": "horizontal", + "showValue": "auto", + "stacking": "none", + "text": {}, + "tooltip": { + "mode": "single", + "sort": "none" + }, + "xTickLabelRotation": 45, + "xTickLabelSpacing": 0 + }, + "targets": [ + { + "csvContent": "Name,Stat1,Stat2\nStockholm, 10, 15\nNew York, 19, -5\nLondon, 10, 1\nLong value, 15,10", + "refId": "A", + "scenarioId": "csv_content" + } + ], + "title": "Auto sizing & auto show values", + "type": "barchart" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Dashboard --" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "fillOpacity": 80, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineWidth": 1, + "scaleDistribution": { + "type": "linear" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "decmbytes" + }, + "overrides": [] + }, + "gridPos": { + "h": 18, + "w": 24, + "x": 0, + "y": 14 + }, + "id": 3, + "maxDataPoints": 20, + "options": { + "barRadius": 0, + "barWidth": 0.97, + "groupWidth": 0.7, + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "orientation": "horizontal", + "showValue": "auto", + "stacking": "none", + "tooltip": { + "mode": "single", + "sort": "none" + }, + "xTickLabelMaxLength": 5, + "xTickLabelRotation": 45, + "xTickLabelSpacing": 100 + }, + "targets": [ + { + "datasource": { + "type": "datasource", + "uid": "-- Dashboard --" + }, + "panelId": 2, + "refId": "A" + } + ], + "title": "Panel Title", + "type": "barchart" + } + ], + "schemaVersion": 37, + "style": "dark", + "tags": [ + "gdev", + "panel-tests", + "barchart", + "graph-ng" + ], + "templating": { + "list": [] + }, + "time": { + "from": "now-6h", + "to": "now" + }, + "timepicker": {}, + "timezone": "", + "title": "BarChart - Label Rotation & Skipping", + "uid": "xCmMwXdVz", + "version": 20, + "weekStart": "" + } diff --git a/devenv/jsonnet/dev-dashboards.libsonnet b/devenv/jsonnet/dev-dashboards.libsonnet index fa47dc594bf..f5787a61e6f 100644 --- a/devenv/jsonnet/dev-dashboards.libsonnet +++ b/devenv/jsonnet/dev-dashboards.libsonnet @@ -107,6 +107,13 @@ local dashboard = grafana.dashboard; id: 0, } }, + dashboard.new('barchart-label-rotation-skipping', import '../dev-dashboards/panel-barchart/barchart-label-rotation-skipping.json') + + resource.addMetadata('folder', 'dev-dashboards') + + { + spec+: { + id: 0, + } + }, dashboard.new('barchart-thresholds-mappings', import '../dev-dashboards/panel-barchart/barchart-thresholds-mappings.json') + resource.addMetadata('folder', 'dev-dashboards') + { diff --git a/public/app/plugins/panel/barchart/__snapshots__/utils.test.ts.snap b/public/app/plugins/panel/barchart/__snapshots__/utils.test.ts.snap index 9fe14c366ec..48b5f0f3b87 100644 --- a/public/app/plugins/panel/barchart/__snapshots__/utils.test.ts.snap +++ b/public/app/plugins/panel/barchart/__snapshots__/utils.test.ts.snap @@ -13,7 +13,7 @@ exports[`BarChart utils preparePlotConfigBuilder orientation 1`] = ` "width": 1, }, "labelGap": 0, - "rotate": -0, + "rotate": 0, "scale": "x", "show": true, "side": 3, @@ -40,7 +40,7 @@ exports[`BarChart utils preparePlotConfigBuilder orientation 1`] = ` "width": 1, }, "labelGap": 0, - "rotate": undefined, + "rotate": -0, "scale": "m/s", "show": true, "side": 2, @@ -167,7 +167,7 @@ exports[`BarChart utils preparePlotConfigBuilder orientation 2`] = ` "width": 1, }, "labelGap": 0, - "rotate": -0, + "rotate": 0, "scale": "x", "show": true, "side": 3, @@ -194,7 +194,7 @@ exports[`BarChart utils preparePlotConfigBuilder orientation 2`] = ` "width": 1, }, "labelGap": 0, - "rotate": undefined, + "rotate": -0, "scale": "m/s", "show": true, "side": 2, @@ -348,7 +348,7 @@ exports[`BarChart utils preparePlotConfigBuilder orientation 3`] = ` "width": 1, }, "labelGap": 0, - "rotate": undefined, + "rotate": 0, "scale": "m/s", "show": true, "side": 3, @@ -475,7 +475,7 @@ exports[`BarChart utils preparePlotConfigBuilder stacking 1`] = ` "width": 1, }, "labelGap": 0, - "rotate": -0, + "rotate": 0, "scale": "x", "show": true, "side": 3, @@ -502,7 +502,7 @@ exports[`BarChart utils preparePlotConfigBuilder stacking 1`] = ` "width": 1, }, "labelGap": 0, - "rotate": undefined, + "rotate": -0, "scale": "m/s", "show": true, "side": 2, @@ -629,7 +629,7 @@ exports[`BarChart utils preparePlotConfigBuilder stacking 2`] = ` "width": 1, }, "labelGap": 0, - "rotate": -0, + "rotate": 0, "scale": "x", "show": true, "side": 3, @@ -656,7 +656,7 @@ exports[`BarChart utils preparePlotConfigBuilder stacking 2`] = ` "width": 1, }, "labelGap": 0, - "rotate": undefined, + "rotate": -0, "scale": "m/s", "show": true, "side": 2, @@ -783,7 +783,7 @@ exports[`BarChart utils preparePlotConfigBuilder stacking 3`] = ` "width": 1, }, "labelGap": 0, - "rotate": -0, + "rotate": 0, "scale": "x", "show": true, "side": 3, @@ -810,7 +810,7 @@ exports[`BarChart utils preparePlotConfigBuilder stacking 3`] = ` "width": 1, }, "labelGap": 0, - "rotate": undefined, + "rotate": -0, "scale": "m/s", "show": true, "side": 2, @@ -937,7 +937,7 @@ exports[`BarChart utils preparePlotConfigBuilder value visibility 1`] = ` "width": 1, }, "labelGap": 0, - "rotate": -0, + "rotate": 0, "scale": "x", "show": true, "side": 3, @@ -964,7 +964,7 @@ exports[`BarChart utils preparePlotConfigBuilder value visibility 1`] = ` "width": 1, }, "labelGap": 0, - "rotate": undefined, + "rotate": -0, "scale": "m/s", "show": true, "side": 2, @@ -1091,7 +1091,7 @@ exports[`BarChart utils preparePlotConfigBuilder value visibility 2`] = ` "width": 1, }, "labelGap": 0, - "rotate": -0, + "rotate": 0, "scale": "x", "show": true, "side": 3, @@ -1118,7 +1118,7 @@ exports[`BarChart utils preparePlotConfigBuilder value visibility 2`] = ` "width": 1, }, "labelGap": 0, - "rotate": undefined, + "rotate": -0, "scale": "m/s", "show": true, "side": 2, diff --git a/public/app/plugins/panel/barchart/bars.ts b/public/app/plugins/panel/barchart/bars.ts index 08bc77b456d..41bccb9040b 100644 --- a/public/app/plugins/panel/barchart/bars.ts +++ b/public/app/plugins/panel/barchart/bars.ts @@ -51,6 +51,7 @@ export interface BarsOptions { getColor?: (seriesIdx: number, valueIdx: number, value: any) => string | null; fillOpacity?: number; formatValue: (seriesIdx: number, value: any) => string; + formatShortValue: (seriesIdx: number, value: any) => string; timeZone?: TimeZone; text?: VizTextDisplayOptions; onHover?: (seriesIdx: number, valueIdx: number) => void; @@ -116,7 +117,17 @@ function calculateFontSizeWithMetrics( * @internal */ export function getConfig(opts: BarsOptions, theme: GrafanaTheme2) { - const { xOri, xDir: dir, rawValue, getColor, formatValue, fillOpacity = 1, showValue, xSpacing = 0 } = opts; + const { + xOri, + xDir: dir, + rawValue, + getColor, + formatValue, + formatShortValue, + fillOpacity = 1, + showValue, + xSpacing = 0, + } = opts; const isXHorizontal = xOri === ScaleOrientation.Horizontal; const hasAutoValueSize = !Boolean(opts.text?.valueSize); const isStacked = opts.stacking !== StackingMode.None; @@ -131,35 +142,34 @@ export function getConfig(opts: BarsOptions, theme: GrafanaTheme2) { let qt: Quadtree; let hRect: Rect | null; - const xSplits: Axis.Splits = (u: uPlot) => { - const dim = isXHorizontal ? u.bbox.width : u.bbox.height; - const _dir = dir * (isXHorizontal ? 1 : -1); + // for distr: 2 scales, the splits array should contain indices into data[0] rather than values + const xSplits: Axis.Splits | undefined = (u) => Array.from(u.data[0].map((v, i) => i)); - let dataLen = u.data[0].length; - let lastIdx = dataLen - 1; + const hFilter: Axis.Filter | undefined = + xSpacing === 0 + ? undefined + : (u, splits) => { + // hSpacing? + const dim = u.bbox.width; + const _dir = dir * (isXHorizontal ? 1 : -1); - let skipMod = 0; + let dataLen = splits.length; + let lastIdx = dataLen - 1; - if (xSpacing !== 0) { - let cssDim = dim / devicePixelRatio; - let maxTicks = Math.abs(Math.floor(cssDim / xSpacing)); + let skipMod = 0; - skipMod = dataLen < maxTicks ? 0 : Math.ceil(dataLen / maxTicks); - } + let cssDim = dim / uPlot.pxRatio; + let maxTicks = Math.abs(Math.floor(cssDim / xSpacing)); - let splits: number[] = []; + skipMod = dataLen < maxTicks ? 0 : Math.ceil(dataLen / maxTicks); - // for distr: 2 scales, the splits array should contain indices into data[0] rather than values - u.data[0].forEach((v, i) => { - let shouldSkip = skipMod !== 0 && (xSpacing > 0 ? i : lastIdx - i) % skipMod > 0; + let splits2 = splits.map((v, i) => { + let shouldSkip = skipMod !== 0 && (xSpacing > 0 ? i : lastIdx - i) % skipMod > 0; + return shouldSkip ? null : v; + }); - if (!shouldSkip) { - splits.push(i); - } - }); - - return _dir === 1 ? splits : splits.reverse(); - }; + return _dir === 1 ? splits2 : splits2.reverse(); + }; // the splits passed into here are data[0] values looked up by the indices returned from splits() const xValues: Axis.Values = (u, splits, axisIdx, foundSpace, foundIncr) => { @@ -182,7 +192,7 @@ export function getConfig(opts: BarsOptions, theme: GrafanaTheme2) { return vals; } - return splits.map((v) => formatValue(0, v)); + return splits.map((v) => (isXHorizontal ? formatShortValue(0, v) : formatValue(0, v))); }; // this expands the distr: 2 scale so that the indicies of each data[0] land at the proper justified positions @@ -434,8 +444,8 @@ export function getConfig(opts: BarsOptions, theme: GrafanaTheme2) { if (seriesIdx === 1) { hRect = null; - let cx = u.cursor.left! * devicePixelRatio; - let cy = u.cursor.top! * devicePixelRatio; + let cx = u.cursor.left! * uPlot.pxRatio; + let cy = u.cursor.top! * uPlot.pxRatio; qt.get(cx, cy, 1, 1, (o) => { if (pointWithin(cx, cy, o.x, o.y, o.x + o.w, o.y + o.h)) { @@ -471,10 +481,10 @@ export function getConfig(opts: BarsOptions, theme: GrafanaTheme2) { } return { - left: isHovered ? (hRect!.x + widthReduce) / devicePixelRatio : -10, - top: isHovered ? hRect!.y / devicePixelRatio : -10, - width: isHovered ? (hRect!.w - widthReduce) / devicePixelRatio : 0, - height: isHovered ? (hRect!.h - heightReduce) / devicePixelRatio : 0, + left: isHovered ? (hRect!.x + widthReduce) / uPlot.pxRatio : -10, + top: isHovered ? hRect!.y / uPlot.pxRatio : -10, + width: isHovered ? (hRect!.w - widthReduce) / uPlot.pxRatio : 0, + height: isHovered ? (hRect!.h - heightReduce) / uPlot.pxRatio : 0, }; }, }, @@ -634,6 +644,7 @@ export function getConfig(opts: BarsOptions, theme: GrafanaTheme2) { xRange, xValues, xSplits, + hFilter, barsBuilder, diff --git a/public/app/plugins/panel/barchart/module.tsx b/public/app/plugins/panel/barchart/module.tsx index 1a4cb2a7cc5..77cdc1495a2 100644 --- a/public/app/plugins/panel/barchart/module.tsx +++ b/public/app/plugins/panel/barchart/module.tsx @@ -138,7 +138,7 @@ export const plugin = new PanelPlugin(BarChartPa }) .addSliderInput({ path: 'xTickLabelRotation', - name: 'Rotate bar labels', + name: 'Rotate X tick labels', defaultValue: defaultPanelOptions.xTickLabelRotation, settings: { min: -90, @@ -147,18 +147,16 @@ export const plugin = new PanelPlugin(BarChartPa marks: { '-90': '-90°', '-45': '-45°', 0: '0°', 45: '45°', 90: '90°' }, included: false, }, - showIf: (opts) => { - return opts.orientation === VizOrientation.Auto || opts.orientation === VizOrientation.Vertical; - }, }) .addNumberInput({ path: 'xTickLabelMaxLength', - name: 'Bar label max length', - description: 'Bar labels will be truncated to the length provided', + name: 'X tick label max length', + description: 'X labels will be truncated to the length provided', settings: { placeholder: 'None', min: 0, }, + showIf: (opts) => opts.xTickLabelRotation !== 0, }) .addCustomEditor({ id: 'xTickLabelSpacing', diff --git a/public/app/plugins/panel/barchart/utils.ts b/public/app/plugins/panel/barchart/utils.ts index 0e4d3b8b529..64bd4da4fca 100644 --- a/public/app/plugins/panel/barchart/utils.ts +++ b/public/app/plugins/panel/barchart/utils.ts @@ -81,15 +81,18 @@ export const preparePlotConfigBuilder: UPlotConfigPrepFn = ({ timeZone, }) => { const builder = new UPlotConfigBuilder(); - const defaultValueFormatter = (seriesIdx: number, value: any) => { - return shortenValue(formattedValueToString(frame.fields[seriesIdx].display!(value)), xTickLabelMaxLength); + + const formatValue = (seriesIdx: number, value: any) => { + return formattedValueToString(frame.fields[seriesIdx].display!(value)); + }; + + const formatShortValue = (seriesIdx: number, value: any) => { + return shortenValue(formatValue(seriesIdx, value), xTickLabelMaxLength); }; // bar orientation -> x scale orientation & direction const vizOrientation = getBarCharScaleOrientation(orientation); - const formatValue = defaultValueFormatter; - // Use bar width when only one field if (frame.fields.length === 2) { groupWidth = barWidth; @@ -107,6 +110,7 @@ export const preparePlotConfigBuilder: UPlotConfigPrepFn = ({ getColor, fillOpacity, formatValue, + formatShortValue, timeZone, text, showValue, @@ -126,8 +130,13 @@ export const preparePlotConfigBuilder: UPlotConfigPrepFn = ({ builder.setTooltipInterpolator(config.interpolateTooltip); - if (vizOrientation.xOri === ScaleOrientation.Horizontal && xTickLabelRotation !== 0) { - builder.setPadding(getRotationPadding(frame, xTickLabelRotation, xTickLabelMaxLength)); + if (xTickLabelRotation !== 0) { + // these are the amount of space we already have available between plot edge and first label + // TODO: removing these hardcoded value requires reading back uplot instance props + let lftSpace = 50; + let btmSpace = vizOrientation.xOri === ScaleOrientation.Horizontal ? 14 : 5; + + builder.setPadding(getRotationPadding(frame, xTickLabelRotation, xTickLabelMaxLength, lftSpace, btmSpace)); } builder.setPrepData(config.prepData); @@ -155,12 +164,13 @@ export const preparePlotConfigBuilder: UPlotConfigPrepFn = ({ placement: xFieldAxisPlacement, label: frame.fields[0].config.custom?.axisLabel, splits: config.xSplits, + filter: vizOrientation.xOri === 0 ? config.hFilter : undefined, values: config.xValues, timeZone, grid: { show: false }, ticks: { show: false }, gap: 15, - tickLabelRotation: xTickLabelRotation * -1, + tickLabelRotation: vizOrientation.xOri === 0 ? xTickLabelRotation * -1 : 0, theme, show: xFieldAxisShow, }); @@ -272,6 +282,8 @@ export const preparePlotConfigBuilder: UPlotConfigPrepFn = ({ size: customConfig.axisWidth, placement, formatValue: (v, decimals) => formattedValueToString(field.display!(v, decimals)), + filter: vizOrientation.yOri === 0 ? config.hFilter : undefined, + tickLabelRotation: vizOrientation.xOri === 1 ? xTickLabelRotation * -1 : 0, theme, grid: { show: customConfig.axisGridShow }, }); @@ -293,7 +305,13 @@ function shortenValue(value: string, length: number) { } } -function getRotationPadding(frame: DataFrame, rotateLabel: number, valueMaxLength: number): Padding { +function getRotationPadding( + frame: DataFrame, + rotateLabel: number, + valueMaxLength: number, + lftSpace = 0, + btmSpace = 0 +): Padding { const values = frame.fields[0].values; const fontSize = UPLOT_AXIS_FONT_SIZE; const displayProcessor = frame.fields[0].display ?? ((v) => v); @@ -325,9 +343,15 @@ function getRotationPadding(frame: DataFrame, rotateLabel: number, valueMaxLengt : 0; // Add padding to the bottom to avoid clipping the rotated labels. - const paddingBottom = Math.sin(((rotateLabel >= 0 ? rotateLabel : rotateLabel * -1) * Math.PI) / 180) * maxLength; + const paddingBottom = + Math.sin(((rotateLabel >= 0 ? rotateLabel : rotateLabel * -1) * Math.PI) / 180) * maxLength - btmSpace; - return [Math.round(UPLOT_AXIS_FONT_SIZE * uPlot.pxRatio), paddingRight, paddingBottom, paddingLeft]; + return [ + Math.round(UPLOT_AXIS_FONT_SIZE * uPlot.pxRatio), + paddingRight, + paddingBottom, + Math.max(0, paddingLeft - lftSpace), + ]; } /** @internal */