diff --git a/devenv/dev-dashboards/panel-table/table_sparkline_cell.json b/devenv/dev-dashboards/panel-table/table_sparkline_cell.json new file mode 100644 index 00000000000..4a8367f348e --- /dev/null +++ b/devenv/dev-dashboards/panel-table/table_sparkline_cell.json @@ -0,0 +1,116 @@ +{ + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": { + "type": "grafana", + "uid": "-- Grafana --" + }, + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "type": "dashboard" + } + ] + }, + "editable": true, + "fiscalYearStartMonth": 0, + "graphTooltip": 0, + "links": [], + "liveNow": false, + "panels": [ + { + "datasource": { + "type": "testdata", + "uid": "PD8C576611E62080A" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "custom": { + "align": "auto", + "cellOptions": { + "type": "auto" + }, + "inspect": false + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 0 + }, + "id": 1, + "options": { + "cellHeight": "sm", + "footer": { + "countRows": false, + "fields": "", + "reducer": [ + "sum" + ], + "show": false + }, + "showHeader": true + }, + "pluginVersion": "10.1.0-pre", + "targets": [ + { + "csvContent": "time,x\n2023-06-12T05:49:00Z,10\n2023-06-12T07:01:00Z,20\n2023-06-12T08:13:00Z,NaN\n2023-06-12T09:25:00Z,NaN\n2023-06-12T10:37:00Z,NaN\n2023-06-12T11:49:00Z,30\n2023-06-12T13:01:00Z,20\n2023-06-12T14:13:00Z,10\n2023-06-12T15:25:00Z,Inf\n2023-06-12T16:37:00Z,null\n2023-06-12T17:49:00Z,", + "datasource": { + "type": "testdata", + "uid": "PD8C576611E62080A" + }, + "refId": "A", + "scenarioId": "csv_content" + } + ], + "title": "SparkLineCell with NaNs,Nulls,Infinity", + "transformations": [ + { + "id": "timeSeriesTable", + "options": {} + } + ], + "type": "table" + } + ], + "refresh": "", + "schemaVersion": 38, + "style": "dark", + "tags": [], + "templating": { + "list": [] + }, + "time": { + "from": "2023-06-12T00:00:00.000Z", + "to": "2023-06-12T18:00:00.000Z" + }, + "timepicker": {}, + "timezone": "utc", + "title": "Table with SparklineCell", + "uid": "d6373b49-1957-4f00-9218-ee2120d3ecd9", + "version": 4, + "weekStart": "" +} \ No newline at end of file diff --git a/devenv/jsonnet/dev-dashboards.libsonnet b/devenv/jsonnet/dev-dashboards.libsonnet index 63430bc2122..71207c5bad5 100644 --- a/devenv/jsonnet/dev-dashboards.libsonnet +++ b/devenv/jsonnet/dev-dashboards.libsonnet @@ -576,6 +576,13 @@ local dashboard = grafana.dashboard; id: 0, } }, + dashboard.new('table_sparkline_cell', import '../dev-dashboards/panel-table/table_sparkline_cell.json') + + resource.addMetadata('folder', 'dev-dashboards') + + { + spec+: { + id: 0, + } + }, dashboard.new('table_tests', import '../dev-dashboards/panel-table/table_tests.json') + resource.addMetadata('folder', 'dev-dashboards') + { diff --git a/packages/grafana-ui/src/components/Sparkline/utils.ts b/packages/grafana-ui/src/components/Sparkline/utils.ts index ebe72c90b51..c643d375a37 100644 --- a/packages/grafana-ui/src/components/Sparkline/utils.ts +++ b/packages/grafana-ui/src/components/Sparkline/utils.ts @@ -43,5 +43,9 @@ export function preparePlotFrame(sparkline: FieldSparkline, config?: FieldConfig frame = sortDataFrame(frame, 0); } - return applyNullInsertThreshold({ frame }); + return applyNullInsertThreshold({ + frame, + refFieldPseudoMin: sparkline.timeRange?.from.valueOf(), + refFieldPseudoMax: sparkline.timeRange?.to.valueOf(), + }); } diff --git a/packages/grafana-ui/src/components/Table/SparklineCell.tsx b/packages/grafana-ui/src/components/Table/SparklineCell.tsx index d91ba727744..527702c34af 100644 --- a/packages/grafana-ui/src/components/Table/SparklineCell.tsx +++ b/packages/grafana-ui/src/components/Table/SparklineCell.tsx @@ -40,6 +40,20 @@ export const SparklineCell = (props: TableCellProps) => { ); } + // Get the step from the first two values to null-fill the x-axis based on timerange + if (sparkline.x && !sparkline.x.config.interval && sparkline.x.values.length > 1) { + sparkline.x.config.interval = sparkline.x.values[1] - sparkline.x.values[0]; + } + + // Remove non-finite values, e.g: NaN, +/-Infinity + sparkline.y.values = sparkline.y.values.map((v) => { + if (!Number.isFinite(v)) { + return null; + } else { + return v; + } + }); + const range = getMinMaxAndDelta(sparkline.y); sparkline.y.config.min = range.min; sparkline.y.config.max = range.max; @@ -101,5 +115,5 @@ function getTableSparklineCellOptions(field: Field): TableSparklineCellOptions { if (options.type === TableCellDisplayMode.Sparkline) { return options; } - throw new Error(`Excpected options type ${TableCellDisplayMode.Sparkline} but got ${options.type}`); + throw new Error(`Expected options type ${TableCellDisplayMode.Sparkline} but got ${options.type}`); }