mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
BarChart: when horiz, allow rotation and skipping of y tick labels (#59354)
This commit is contained in:
parent
ce0bdb2cd9
commit
122f0d947e
@ -6929,11 +6929,12 @@ exports[`better eslint`] = {
|
|||||||
"public/app/plugins/panel/barchart/bars.ts:5381": [
|
"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.", "0"],
|
||||||
[0, 0, 0, "Unexpected any. Specify a different type.", "1"],
|
[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.", "2"],
|
||||||
[0, 0, 0, "Unexpected any. Specify a different type.", "3"],
|
[0, 0, 0, "Do not use any type assertions.", "3"],
|
||||||
[0, 0, 0, "Do not use any type assertions.", "4"],
|
[0, 0, 0, "Unexpected any. Specify a different type.", "4"],
|
||||||
[0, 0, 0, "Unexpected any. Specify a different type.", "5"],
|
[0, 0, 0, "Do not use any type assertions.", "5"],
|
||||||
[0, 0, 0, "Do not use any type assertions.", "6"]
|
[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": [
|
"public/app/plugins/panel/barchart/module.tsx:5381": [
|
||||||
[0, 0, 0, "Do not use any type assertions.", "0"],
|
[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": [
|
"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.", "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": [
|
"public/app/plugins/panel/candlestick/CandlestickPanel.tsx:5381": [
|
||||||
[0, 0, 0, "Do not use any type assertions.", "0"],
|
[0, 0, 0, "Do not use any type assertions.", "0"],
|
||||||
|
@ -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": ""
|
||||||
|
}
|
@ -107,6 +107,13 @@ local dashboard = grafana.dashboard;
|
|||||||
id: 0,
|
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') +
|
dashboard.new('barchart-thresholds-mappings', import '../dev-dashboards/panel-barchart/barchart-thresholds-mappings.json') +
|
||||||
resource.addMetadata('folder', 'dev-dashboards') +
|
resource.addMetadata('folder', 'dev-dashboards') +
|
||||||
{
|
{
|
||||||
|
@ -13,7 +13,7 @@ exports[`BarChart utils preparePlotConfigBuilder orientation 1`] = `
|
|||||||
"width": 1,
|
"width": 1,
|
||||||
},
|
},
|
||||||
"labelGap": 0,
|
"labelGap": 0,
|
||||||
"rotate": -0,
|
"rotate": 0,
|
||||||
"scale": "x",
|
"scale": "x",
|
||||||
"show": true,
|
"show": true,
|
||||||
"side": 3,
|
"side": 3,
|
||||||
@ -40,7 +40,7 @@ exports[`BarChart utils preparePlotConfigBuilder orientation 1`] = `
|
|||||||
"width": 1,
|
"width": 1,
|
||||||
},
|
},
|
||||||
"labelGap": 0,
|
"labelGap": 0,
|
||||||
"rotate": undefined,
|
"rotate": -0,
|
||||||
"scale": "m/s",
|
"scale": "m/s",
|
||||||
"show": true,
|
"show": true,
|
||||||
"side": 2,
|
"side": 2,
|
||||||
@ -167,7 +167,7 @@ exports[`BarChart utils preparePlotConfigBuilder orientation 2`] = `
|
|||||||
"width": 1,
|
"width": 1,
|
||||||
},
|
},
|
||||||
"labelGap": 0,
|
"labelGap": 0,
|
||||||
"rotate": -0,
|
"rotate": 0,
|
||||||
"scale": "x",
|
"scale": "x",
|
||||||
"show": true,
|
"show": true,
|
||||||
"side": 3,
|
"side": 3,
|
||||||
@ -194,7 +194,7 @@ exports[`BarChart utils preparePlotConfigBuilder orientation 2`] = `
|
|||||||
"width": 1,
|
"width": 1,
|
||||||
},
|
},
|
||||||
"labelGap": 0,
|
"labelGap": 0,
|
||||||
"rotate": undefined,
|
"rotate": -0,
|
||||||
"scale": "m/s",
|
"scale": "m/s",
|
||||||
"show": true,
|
"show": true,
|
||||||
"side": 2,
|
"side": 2,
|
||||||
@ -348,7 +348,7 @@ exports[`BarChart utils preparePlotConfigBuilder orientation 3`] = `
|
|||||||
"width": 1,
|
"width": 1,
|
||||||
},
|
},
|
||||||
"labelGap": 0,
|
"labelGap": 0,
|
||||||
"rotate": undefined,
|
"rotate": 0,
|
||||||
"scale": "m/s",
|
"scale": "m/s",
|
||||||
"show": true,
|
"show": true,
|
||||||
"side": 3,
|
"side": 3,
|
||||||
@ -475,7 +475,7 @@ exports[`BarChart utils preparePlotConfigBuilder stacking 1`] = `
|
|||||||
"width": 1,
|
"width": 1,
|
||||||
},
|
},
|
||||||
"labelGap": 0,
|
"labelGap": 0,
|
||||||
"rotate": -0,
|
"rotate": 0,
|
||||||
"scale": "x",
|
"scale": "x",
|
||||||
"show": true,
|
"show": true,
|
||||||
"side": 3,
|
"side": 3,
|
||||||
@ -502,7 +502,7 @@ exports[`BarChart utils preparePlotConfigBuilder stacking 1`] = `
|
|||||||
"width": 1,
|
"width": 1,
|
||||||
},
|
},
|
||||||
"labelGap": 0,
|
"labelGap": 0,
|
||||||
"rotate": undefined,
|
"rotate": -0,
|
||||||
"scale": "m/s",
|
"scale": "m/s",
|
||||||
"show": true,
|
"show": true,
|
||||||
"side": 2,
|
"side": 2,
|
||||||
@ -629,7 +629,7 @@ exports[`BarChart utils preparePlotConfigBuilder stacking 2`] = `
|
|||||||
"width": 1,
|
"width": 1,
|
||||||
},
|
},
|
||||||
"labelGap": 0,
|
"labelGap": 0,
|
||||||
"rotate": -0,
|
"rotate": 0,
|
||||||
"scale": "x",
|
"scale": "x",
|
||||||
"show": true,
|
"show": true,
|
||||||
"side": 3,
|
"side": 3,
|
||||||
@ -656,7 +656,7 @@ exports[`BarChart utils preparePlotConfigBuilder stacking 2`] = `
|
|||||||
"width": 1,
|
"width": 1,
|
||||||
},
|
},
|
||||||
"labelGap": 0,
|
"labelGap": 0,
|
||||||
"rotate": undefined,
|
"rotate": -0,
|
||||||
"scale": "m/s",
|
"scale": "m/s",
|
||||||
"show": true,
|
"show": true,
|
||||||
"side": 2,
|
"side": 2,
|
||||||
@ -783,7 +783,7 @@ exports[`BarChart utils preparePlotConfigBuilder stacking 3`] = `
|
|||||||
"width": 1,
|
"width": 1,
|
||||||
},
|
},
|
||||||
"labelGap": 0,
|
"labelGap": 0,
|
||||||
"rotate": -0,
|
"rotate": 0,
|
||||||
"scale": "x",
|
"scale": "x",
|
||||||
"show": true,
|
"show": true,
|
||||||
"side": 3,
|
"side": 3,
|
||||||
@ -810,7 +810,7 @@ exports[`BarChart utils preparePlotConfigBuilder stacking 3`] = `
|
|||||||
"width": 1,
|
"width": 1,
|
||||||
},
|
},
|
||||||
"labelGap": 0,
|
"labelGap": 0,
|
||||||
"rotate": undefined,
|
"rotate": -0,
|
||||||
"scale": "m/s",
|
"scale": "m/s",
|
||||||
"show": true,
|
"show": true,
|
||||||
"side": 2,
|
"side": 2,
|
||||||
@ -937,7 +937,7 @@ exports[`BarChart utils preparePlotConfigBuilder value visibility 1`] = `
|
|||||||
"width": 1,
|
"width": 1,
|
||||||
},
|
},
|
||||||
"labelGap": 0,
|
"labelGap": 0,
|
||||||
"rotate": -0,
|
"rotate": 0,
|
||||||
"scale": "x",
|
"scale": "x",
|
||||||
"show": true,
|
"show": true,
|
||||||
"side": 3,
|
"side": 3,
|
||||||
@ -964,7 +964,7 @@ exports[`BarChart utils preparePlotConfigBuilder value visibility 1`] = `
|
|||||||
"width": 1,
|
"width": 1,
|
||||||
},
|
},
|
||||||
"labelGap": 0,
|
"labelGap": 0,
|
||||||
"rotate": undefined,
|
"rotate": -0,
|
||||||
"scale": "m/s",
|
"scale": "m/s",
|
||||||
"show": true,
|
"show": true,
|
||||||
"side": 2,
|
"side": 2,
|
||||||
@ -1091,7 +1091,7 @@ exports[`BarChart utils preparePlotConfigBuilder value visibility 2`] = `
|
|||||||
"width": 1,
|
"width": 1,
|
||||||
},
|
},
|
||||||
"labelGap": 0,
|
"labelGap": 0,
|
||||||
"rotate": -0,
|
"rotate": 0,
|
||||||
"scale": "x",
|
"scale": "x",
|
||||||
"show": true,
|
"show": true,
|
||||||
"side": 3,
|
"side": 3,
|
||||||
@ -1118,7 +1118,7 @@ exports[`BarChart utils preparePlotConfigBuilder value visibility 2`] = `
|
|||||||
"width": 1,
|
"width": 1,
|
||||||
},
|
},
|
||||||
"labelGap": 0,
|
"labelGap": 0,
|
||||||
"rotate": undefined,
|
"rotate": -0,
|
||||||
"scale": "m/s",
|
"scale": "m/s",
|
||||||
"show": true,
|
"show": true,
|
||||||
"side": 2,
|
"side": 2,
|
||||||
|
@ -51,6 +51,7 @@ export interface BarsOptions {
|
|||||||
getColor?: (seriesIdx: number, valueIdx: number, value: any) => string | null;
|
getColor?: (seriesIdx: number, valueIdx: number, value: any) => string | null;
|
||||||
fillOpacity?: number;
|
fillOpacity?: number;
|
||||||
formatValue: (seriesIdx: number, value: any) => string;
|
formatValue: (seriesIdx: number, value: any) => string;
|
||||||
|
formatShortValue: (seriesIdx: number, value: any) => string;
|
||||||
timeZone?: TimeZone;
|
timeZone?: TimeZone;
|
||||||
text?: VizTextDisplayOptions;
|
text?: VizTextDisplayOptions;
|
||||||
onHover?: (seriesIdx: number, valueIdx: number) => void;
|
onHover?: (seriesIdx: number, valueIdx: number) => void;
|
||||||
@ -116,7 +117,17 @@ function calculateFontSizeWithMetrics(
|
|||||||
* @internal
|
* @internal
|
||||||
*/
|
*/
|
||||||
export function getConfig(opts: BarsOptions, theme: GrafanaTheme2) {
|
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 isXHorizontal = xOri === ScaleOrientation.Horizontal;
|
||||||
const hasAutoValueSize = !Boolean(opts.text?.valueSize);
|
const hasAutoValueSize = !Boolean(opts.text?.valueSize);
|
||||||
const isStacked = opts.stacking !== StackingMode.None;
|
const isStacked = opts.stacking !== StackingMode.None;
|
||||||
@ -131,35 +142,34 @@ export function getConfig(opts: BarsOptions, theme: GrafanaTheme2) {
|
|||||||
let qt: Quadtree;
|
let qt: Quadtree;
|
||||||
let hRect: Rect | null;
|
let hRect: Rect | null;
|
||||||
|
|
||||||
const xSplits: Axis.Splits = (u: uPlot) => {
|
// for distr: 2 scales, the splits array should contain indices into data[0] rather than values
|
||||||
const dim = isXHorizontal ? u.bbox.width : u.bbox.height;
|
const xSplits: Axis.Splits | undefined = (u) => Array.from(u.data[0].map((v, i) => i));
|
||||||
const _dir = dir * (isXHorizontal ? 1 : -1);
|
|
||||||
|
|
||||||
let dataLen = u.data[0].length;
|
const hFilter: Axis.Filter | undefined =
|
||||||
let lastIdx = dataLen - 1;
|
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 skipMod = 0;
|
||||||
let cssDim = dim / devicePixelRatio;
|
|
||||||
let maxTicks = Math.abs(Math.floor(cssDim / xSpacing));
|
|
||||||
|
|
||||||
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
|
let splits2 = splits.map((v, i) => {
|
||||||
u.data[0].forEach((v, i) => {
|
let shouldSkip = skipMod !== 0 && (xSpacing > 0 ? i : lastIdx - i) % skipMod > 0;
|
||||||
let shouldSkip = skipMod !== 0 && (xSpacing > 0 ? i : lastIdx - i) % skipMod > 0;
|
return shouldSkip ? null : v;
|
||||||
|
});
|
||||||
|
|
||||||
if (!shouldSkip) {
|
return _dir === 1 ? splits2 : splits2.reverse();
|
||||||
splits.push(i);
|
};
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return _dir === 1 ? splits : splits.reverse();
|
|
||||||
};
|
|
||||||
|
|
||||||
// the splits passed into here are data[0] values looked up by the indices returned from splits()
|
// 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) => {
|
const xValues: Axis.Values = (u, splits, axisIdx, foundSpace, foundIncr) => {
|
||||||
@ -182,7 +192,7 @@ export function getConfig(opts: BarsOptions, theme: GrafanaTheme2) {
|
|||||||
return vals;
|
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
|
// 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) {
|
if (seriesIdx === 1) {
|
||||||
hRect = null;
|
hRect = null;
|
||||||
|
|
||||||
let cx = u.cursor.left! * devicePixelRatio;
|
let cx = u.cursor.left! * uPlot.pxRatio;
|
||||||
let cy = u.cursor.top! * devicePixelRatio;
|
let cy = u.cursor.top! * uPlot.pxRatio;
|
||||||
|
|
||||||
qt.get(cx, cy, 1, 1, (o) => {
|
qt.get(cx, cy, 1, 1, (o) => {
|
||||||
if (pointWithin(cx, cy, o.x, o.y, o.x + o.w, o.y + o.h)) {
|
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 {
|
return {
|
||||||
left: isHovered ? (hRect!.x + widthReduce) / devicePixelRatio : -10,
|
left: isHovered ? (hRect!.x + widthReduce) / uPlot.pxRatio : -10,
|
||||||
top: isHovered ? hRect!.y / devicePixelRatio : -10,
|
top: isHovered ? hRect!.y / uPlot.pxRatio : -10,
|
||||||
width: isHovered ? (hRect!.w - widthReduce) / devicePixelRatio : 0,
|
width: isHovered ? (hRect!.w - widthReduce) / uPlot.pxRatio : 0,
|
||||||
height: isHovered ? (hRect!.h - heightReduce) / devicePixelRatio : 0,
|
height: isHovered ? (hRect!.h - heightReduce) / uPlot.pxRatio : 0,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -634,6 +644,7 @@ export function getConfig(opts: BarsOptions, theme: GrafanaTheme2) {
|
|||||||
xRange,
|
xRange,
|
||||||
xValues,
|
xValues,
|
||||||
xSplits,
|
xSplits,
|
||||||
|
hFilter,
|
||||||
|
|
||||||
barsBuilder,
|
barsBuilder,
|
||||||
|
|
||||||
|
@ -138,7 +138,7 @@ export const plugin = new PanelPlugin<PanelOptions, PanelFieldConfig>(BarChartPa
|
|||||||
})
|
})
|
||||||
.addSliderInput({
|
.addSliderInput({
|
||||||
path: 'xTickLabelRotation',
|
path: 'xTickLabelRotation',
|
||||||
name: 'Rotate bar labels',
|
name: 'Rotate X tick labels',
|
||||||
defaultValue: defaultPanelOptions.xTickLabelRotation,
|
defaultValue: defaultPanelOptions.xTickLabelRotation,
|
||||||
settings: {
|
settings: {
|
||||||
min: -90,
|
min: -90,
|
||||||
@ -147,18 +147,16 @@ export const plugin = new PanelPlugin<PanelOptions, PanelFieldConfig>(BarChartPa
|
|||||||
marks: { '-90': '-90°', '-45': '-45°', 0: '0°', 45: '45°', 90: '90°' },
|
marks: { '-90': '-90°', '-45': '-45°', 0: '0°', 45: '45°', 90: '90°' },
|
||||||
included: false,
|
included: false,
|
||||||
},
|
},
|
||||||
showIf: (opts) => {
|
|
||||||
return opts.orientation === VizOrientation.Auto || opts.orientation === VizOrientation.Vertical;
|
|
||||||
},
|
|
||||||
})
|
})
|
||||||
.addNumberInput({
|
.addNumberInput({
|
||||||
path: 'xTickLabelMaxLength',
|
path: 'xTickLabelMaxLength',
|
||||||
name: 'Bar label max length',
|
name: 'X tick label max length',
|
||||||
description: 'Bar labels will be truncated to the length provided',
|
description: 'X labels will be truncated to the length provided',
|
||||||
settings: {
|
settings: {
|
||||||
placeholder: 'None',
|
placeholder: 'None',
|
||||||
min: 0,
|
min: 0,
|
||||||
},
|
},
|
||||||
|
showIf: (opts) => opts.xTickLabelRotation !== 0,
|
||||||
})
|
})
|
||||||
.addCustomEditor({
|
.addCustomEditor({
|
||||||
id: 'xTickLabelSpacing',
|
id: 'xTickLabelSpacing',
|
||||||
|
@ -81,15 +81,18 @@ export const preparePlotConfigBuilder: UPlotConfigPrepFn<BarChartOptionsEX> = ({
|
|||||||
timeZone,
|
timeZone,
|
||||||
}) => {
|
}) => {
|
||||||
const builder = new UPlotConfigBuilder();
|
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
|
// bar orientation -> x scale orientation & direction
|
||||||
const vizOrientation = getBarCharScaleOrientation(orientation);
|
const vizOrientation = getBarCharScaleOrientation(orientation);
|
||||||
|
|
||||||
const formatValue = defaultValueFormatter;
|
|
||||||
|
|
||||||
// Use bar width when only one field
|
// Use bar width when only one field
|
||||||
if (frame.fields.length === 2) {
|
if (frame.fields.length === 2) {
|
||||||
groupWidth = barWidth;
|
groupWidth = barWidth;
|
||||||
@ -107,6 +110,7 @@ export const preparePlotConfigBuilder: UPlotConfigPrepFn<BarChartOptionsEX> = ({
|
|||||||
getColor,
|
getColor,
|
||||||
fillOpacity,
|
fillOpacity,
|
||||||
formatValue,
|
formatValue,
|
||||||
|
formatShortValue,
|
||||||
timeZone,
|
timeZone,
|
||||||
text,
|
text,
|
||||||
showValue,
|
showValue,
|
||||||
@ -126,8 +130,13 @@ export const preparePlotConfigBuilder: UPlotConfigPrepFn<BarChartOptionsEX> = ({
|
|||||||
|
|
||||||
builder.setTooltipInterpolator(config.interpolateTooltip);
|
builder.setTooltipInterpolator(config.interpolateTooltip);
|
||||||
|
|
||||||
if (vizOrientation.xOri === ScaleOrientation.Horizontal && xTickLabelRotation !== 0) {
|
if (xTickLabelRotation !== 0) {
|
||||||
builder.setPadding(getRotationPadding(frame, xTickLabelRotation, xTickLabelMaxLength));
|
// 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);
|
builder.setPrepData(config.prepData);
|
||||||
@ -155,12 +164,13 @@ export const preparePlotConfigBuilder: UPlotConfigPrepFn<BarChartOptionsEX> = ({
|
|||||||
placement: xFieldAxisPlacement,
|
placement: xFieldAxisPlacement,
|
||||||
label: frame.fields[0].config.custom?.axisLabel,
|
label: frame.fields[0].config.custom?.axisLabel,
|
||||||
splits: config.xSplits,
|
splits: config.xSplits,
|
||||||
|
filter: vizOrientation.xOri === 0 ? config.hFilter : undefined,
|
||||||
values: config.xValues,
|
values: config.xValues,
|
||||||
timeZone,
|
timeZone,
|
||||||
grid: { show: false },
|
grid: { show: false },
|
||||||
ticks: { show: false },
|
ticks: { show: false },
|
||||||
gap: 15,
|
gap: 15,
|
||||||
tickLabelRotation: xTickLabelRotation * -1,
|
tickLabelRotation: vizOrientation.xOri === 0 ? xTickLabelRotation * -1 : 0,
|
||||||
theme,
|
theme,
|
||||||
show: xFieldAxisShow,
|
show: xFieldAxisShow,
|
||||||
});
|
});
|
||||||
@ -272,6 +282,8 @@ export const preparePlotConfigBuilder: UPlotConfigPrepFn<BarChartOptionsEX> = ({
|
|||||||
size: customConfig.axisWidth,
|
size: customConfig.axisWidth,
|
||||||
placement,
|
placement,
|
||||||
formatValue: (v, decimals) => formattedValueToString(field.display!(v, decimals)),
|
formatValue: (v, decimals) => formattedValueToString(field.display!(v, decimals)),
|
||||||
|
filter: vizOrientation.yOri === 0 ? config.hFilter : undefined,
|
||||||
|
tickLabelRotation: vizOrientation.xOri === 1 ? xTickLabelRotation * -1 : 0,
|
||||||
theme,
|
theme,
|
||||||
grid: { show: customConfig.axisGridShow },
|
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 values = frame.fields[0].values;
|
||||||
const fontSize = UPLOT_AXIS_FONT_SIZE;
|
const fontSize = UPLOT_AXIS_FONT_SIZE;
|
||||||
const displayProcessor = frame.fields[0].display ?? ((v) => v);
|
const displayProcessor = frame.fields[0].display ?? ((v) => v);
|
||||||
@ -325,9 +343,15 @@ function getRotationPadding(frame: DataFrame, rotateLabel: number, valueMaxLengt
|
|||||||
: 0;
|
: 0;
|
||||||
|
|
||||||
// Add padding to the bottom to avoid clipping the rotated labels.
|
// 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 */
|
/** @internal */
|
||||||
|
Loading…
Reference in New Issue
Block a user