This is an automated email from the ASF dual-hosted git repository.

riemer pushed a commit to branch improve-chart-types
in repository https://gitbox.apache.org/repos/asf/streampipes.git

commit 1d4bd3a63e6af6c8cd5233d8a81f341d1b17cec4
Author: Dominik Riemer <[email protected]>
AuthorDate: Tue Mar 24 18:28:30 2026 +0100

    Let users configure the number of decimals to show
---
 ...echarts-widget-appearance-config.component.html | 18 ++++++++
 .../echarts-widget-appearance-config.component.ts  | 37 +++++++++++++++-
 .../charts/density/density-renderer.service.ts     | 18 ++++++++
 .../charts/gauge/gauge-renderer.service.ts         | 11 ++++-
 .../charts/heatmap/heatmap-renderer.service.ts     |  3 +-
 .../charts/histogram/histogram-renderer.service.ts | 49 +++++++++++++++++++++-
 .../components/charts/pie/pie-renderer.service.ts  | 23 +++++++---
 .../charts/scatter/scatter-renderer.service.ts     | 18 ++++++++
 .../sp-timeseries-renderer.service.ts              | 10 ++++-
 .../value-heatmap-renderer.service.ts              |  5 ++-
 .../echarts-renderer/base-echarts-renderer.ts      | 28 +++++++++++++
 .../echarts-basic-options-generator.service.ts     | 13 ++++++
 .../models/dataview-dashboard.model.ts             |  5 +++
 13 files changed, 223 insertions(+), 15 deletions(-)

diff --git 
a/ui/src/app/chart-shared/components/chart-config/echarts-widget-appearance-config/echarts-widget-appearance-config.component.html
 
b/ui/src/app/chart-shared/components/chart-config/echarts-widget-appearance-config/echarts-widget-appearance-config.component.html
index 27aad11995..7b2ee8bed7 100644
--- 
a/ui/src/app/chart-shared/components/chart-config/echarts-widget-appearance-config/echarts-widget-appearance-config.component.html
+++ 
b/ui/src/app/chart-shared/components/chart-config/echarts-widget-appearance-config/echarts-widget-appearance-config.component.html
@@ -32,4 +32,22 @@
         (change)="triggerViewUpdate()"
         >{{ 'Show tooltip' | translate }}
     </mat-checkbox>
+
+    <sp-form-field
+        [level]="3"
+        [label]="'Decimals' | translate"
+        [description]="'Number of decimals to show' | translate"
+    >
+        <mat-form-field>
+            <input
+                matInput
+                type="number"
+                [ngModel]="appearanceConfig.numberFormat?.decimals ?? 2"
+                min="0"
+                max="10"
+                step="1"
+                (ngModelChange)="updateDecimals($event)"
+            />
+        </mat-form-field>
+    </sp-form-field>
 </sp-split-section>
diff --git 
a/ui/src/app/chart-shared/components/chart-config/echarts-widget-appearance-config/echarts-widget-appearance-config.component.ts
 
b/ui/src/app/chart-shared/components/chart-config/echarts-widget-appearance-config/echarts-widget-appearance-config.component.ts
index 5c5ab4da66..af7e8b3796 100644
--- 
a/ui/src/app/chart-shared/components/chart-config/echarts-widget-appearance-config/echarts-widget-appearance-config.component.ts
+++ 
b/ui/src/app/chart-shared/components/chart-config/echarts-widget-appearance-config/echarts-widget-appearance-config.component.ts
@@ -19,15 +19,28 @@
 import { Component, Input, OnInit, inject } from '@angular/core';
 import { WidgetEchartsAppearanceConfig } from 
'../../../models/dataview-dashboard.model';
 import { ChartConfigurationService } from 
'../../../services/chart-configuration.service';
-import { SplitSectionComponent } from '@streampipes/shared-ui';
+import {
+    FormFieldComponent,
+    SplitSectionComponent,
+} from '@streampipes/shared-ui';
 import { MatCheckbox } from '@angular/material/checkbox';
 import { FormsModule } from '@angular/forms';
 import { TranslatePipe } from '@ngx-translate/core';
+import { MatFormField } from '@angular/material/form-field';
+import { MatInput } from '@angular/material/input';
 
 @Component({
     selector: 'sp-echarts-widget-appearance-config',
     templateUrl: './echarts-widget-appearance-config.component.html',
-    imports: [SplitSectionComponent, MatCheckbox, FormsModule, TranslatePipe],
+    imports: [
+        SplitSectionComponent,
+        FormFieldComponent,
+        MatCheckbox,
+        MatFormField,
+        MatInput,
+        FormsModule,
+        TranslatePipe,
+    ],
 })
 export class SpEchartsWidgetAppearanceConfigComponent implements OnInit {
     private widgetConfigurationService = inject(ChartConfigurationService);
@@ -41,6 +54,12 @@ export class SpEchartsWidgetAppearanceConfigComponent 
implements OnInit {
             showToolbox: true,
             showTooltip: true,
         };
+        this.appearanceConfig.numberFormat ??= {
+            decimals: 2,
+        };
+        this.appearanceConfig.numberFormat.decimals = this.normalizeDecimals(
+            this.appearanceConfig.numberFormat.decimals,
+        );
     }
 
     triggerViewUpdate() {
@@ -49,4 +68,18 @@ export class SpEchartsWidgetAppearanceConfigComponent 
implements OnInit {
             refreshData: false,
         });
     }
+
+    updateDecimals(decimals: number | string): void {
+        this.appearanceConfig.numberFormat.decimals =
+            this.normalizeDecimals(decimals);
+        this.triggerViewUpdate();
+    }
+
+    private normalizeDecimals(decimals: number | string): number {
+        const parsedDecimals = Number(decimals);
+        if (!Number.isFinite(parsedDecimals)) {
+            return 2;
+        }
+        return Math.min(10, Math.max(0, Math.round(parsedDecimals)));
+    }
 }
diff --git 
a/ui/src/app/chart-shared/components/charts/density/density-renderer.service.ts 
b/ui/src/app/chart-shared/components/charts/density/density-renderer.service.ts
index e61809c1a5..06cc688e13 100644
--- 
a/ui/src/app/chart-shared/components/charts/density/density-renderer.service.ts
+++ 
b/ui/src/app/chart-shared/components/charts/density/density-renderer.service.ts
@@ -39,12 +39,17 @@ export class SpDensityRendererService extends 
SpBaseEchartsRenderer<CorrelationC
         widgetConfig: CorrelationChartWidgetModel,
         widgetSize: WidgetSize,
     ): void {
+        const decimals = this.getDecimals(widgetConfig);
         const xField = this.getXField(widgetConfig);
         const yField = this.getYField(widgetConfig);
         const dataset = this.datasetUtilsService.findPreparedDataset(
             datasets,
             xField.sourceIndex,
         );
+        const tooltip =
+            !Array.isArray(options.tooltip) && options.tooltip
+                ? options.tooltip
+                : {};
 
         const data = this.prepareDataset(dataset, xField, yField);
         const stats = this.calculateStats(data);
@@ -65,6 +70,10 @@ export class SpDensityRendererService extends 
SpBaseEchartsRenderer<CorrelationC
                 scale: true,
                 min: Math.floor(stats.minX - 1),
                 max: Math.ceil(stats.maxX + 1),
+                axisLabel: {
+                    formatter: (value: number | string) =>
+                        this.formatNumber(value, decimals),
+                },
                 name:
                     widgetConfig.visualizationConfig.labelX ||
                     `${xField.fullDbName}${xField.measurementUnitResourceId ? 
` (${xField.measurementUnitResourceId.split('#').pop()})` : ''}`,
@@ -78,6 +87,10 @@ export class SpDensityRendererService extends 
SpBaseEchartsRenderer<CorrelationC
                 scale: true,
                 min: Math.floor(stats.minY - 1),
                 max: Math.ceil(stats.maxY + 1),
+                axisLabel: {
+                    formatter: (value: number | string) =>
+                        this.formatNumber(value, decimals),
+                },
                 name:
                     widgetConfig.visualizationConfig.labelY ||
                     `${yField.fullDbName}${yField.measurementUnitResourceId ? 
` (${yField.measurementUnitResourceId.split('#').pop()})` : ''}`,
@@ -100,6 +113,11 @@ export class SpDensityRendererService extends 
SpBaseEchartsRenderer<CorrelationC
                     color: ['white', 'yellow', 'red'],
                 },
             },
+            tooltip: {
+                ...tooltip,
+                valueFormatter: (value: unknown) =>
+                    this.formatNumber(value, decimals),
+            },
             series: [
                 {
                     name: dataset.rawDataset,
diff --git 
a/ui/src/app/chart-shared/components/charts/gauge/gauge-renderer.service.ts 
b/ui/src/app/chart-shared/components/charts/gauge/gauge-renderer.service.ts
index f72bfcf52d..263c62c961 100644
--- a/ui/src/app/chart-shared/components/charts/gauge/gauge-renderer.service.ts
+++ b/ui/src/app/chart-shared/components/charts/gauge/gauge-renderer.service.ts
@@ -43,6 +43,7 @@ export class SpGaugeRendererService implements 
SpEchartsRenderer<GaugeWidgetMode
         seriesName: string,
         fieldName: string,
         value: number,
+        decimals: number,
         widgetConfig: GaugeWidgetModel,
         widgetSize: WidgetSize,
         gaugeLayout: GaugeLayout,
@@ -64,7 +65,8 @@ export class SpGaugeRendererService implements 
SpEchartsRenderer<GaugeWidgetMode
             detail: {
                 show: true,
                 valueAnimation: false,
-                formatter: '{value}',
+                formatter: (currentValue: number) =>
+                    currentValue.toFixed(decimals),
                 fontSize: 14 * clamp,
                 offsetCenter: [0, gaugeLayout.detailOffsetY],
             },
@@ -102,13 +104,17 @@ export class SpGaugeRendererService implements 
SpEchartsRenderer<GaugeWidgetMode
             widgetConfig.baseAppearanceConfig as WidgetEchartsAppearanceConfig,
             {},
         );
+        const appearanceConfig =
+            widgetConfig.baseAppearanceConfig as WidgetEchartsAppearanceConfig;
+        const decimals = appearanceConfig.numberFormat?.decimals ?? 2;
         const selectedField = this.getSelectedField(widgetConfig);
         const sourceIndex = selectedField.sourceIndex;
         const dataSeries = queryResult[sourceIndex].allDataSeries[0];
         const columnIndex = dataSeries.headers.indexOf(
             selectedField.fullDbName,
         );
-        const data = parseFloat(dataSeries.rows[0][columnIndex].toFixed(2));
+        const value = Number(dataSeries.rows[0][columnIndex]);
+        const data = Number.isFinite(value) ? value : 0;
         const legend =
             !Array.isArray(option.legend) && option.legend ? option.legend : 
{};
         const toolbox =
@@ -139,6 +145,7 @@ export class SpGaugeRendererService implements 
SpEchartsRenderer<GaugeWidgetMode
                 '',
                 selectedField.fullDbName,
                 data,
+                decimals,
                 widgetConfig,
                 widgetSize,
                 gaugeLayout,
diff --git 
a/ui/src/app/chart-shared/components/charts/heatmap/heatmap-renderer.service.ts 
b/ui/src/app/chart-shared/components/charts/heatmap/heatmap-renderer.service.ts
index 0fb0af79de..b17ed70b86 100644
--- 
a/ui/src/app/chart-shared/components/charts/heatmap/heatmap-renderer.service.ts
+++ 
b/ui/src/app/chart-shared/components/charts/heatmap/heatmap-renderer.service.ts
@@ -36,6 +36,7 @@ export class SpHeatmapRendererService extends 
SpBaseEchartsRenderer<HeatmapWidge
         widgetConfig: HeatmapWidgetModel,
     ): void {
         this.basicOptions(options, widgetConfig);
+        const decimals = this.getDecimals(widgetConfig);
 
         const field = widgetConfig.visualizationConfig.selectedHeatProperty;
         const sourceIndex = field.sourceIndex;
@@ -62,7 +63,7 @@ export class SpHeatmapRendererService extends 
SpBaseEchartsRenderer<HeatmapWidge
             return [
                 index,
                 this.makeTag(rawDataset.rawDataset.dimensions, tags, row),
-                (row[heatIndex] as number).toFixed(2),
+                this.formatNumber(row[heatIndex], decimals),
             ];
         });
 
diff --git 
a/ui/src/app/chart-shared/components/charts/histogram/histogram-renderer.service.ts
 
b/ui/src/app/chart-shared/components/charts/histogram/histogram-renderer.service.ts
index 1ab7f79ca5..33d91bb79a 100644
--- 
a/ui/src/app/chart-shared/components/charts/histogram/histogram-renderer.service.ts
+++ 
b/ui/src/app/chart-shared/components/charts/histogram/histogram-renderer.service.ts
@@ -29,8 +29,27 @@ export class SpHistogramRendererService extends 
SpBaseSingleFieldEchartsRenderer
     HistogramChartWidgetModel,
     BarSeriesOption
 > {
-    addAdditionalConfigs(option: EChartsOption) {
-        //do nothing
+    addAdditionalConfigs(
+        option: EChartsOption,
+        widgetConfig?: HistogramChartWidgetModel,
+    ) {
+        if (!widgetConfig) {
+            return;
+        }
+
+        const decimals = this.getDecimals(widgetConfig);
+        const tooltip =
+            !Array.isArray(option.tooltip) && option.tooltip
+                ? option.tooltip
+                : {};
+        option.tooltip = {
+            ...tooltip,
+            valueFormatter: (value: unknown) =>
+                this.formatNumber(value, decimals),
+        };
+
+        this.applyAxisLabelFormatting(option.xAxis, decimals);
+        this.applyAxisLabelFormatting(option.yAxis, decimals);
     }
 
     public handleUpdatedFields(
@@ -91,4 +110,30 @@ export class SpHistogramRendererService extends 
SpBaseSingleFieldEchartsRenderer
     getDefaultSeriesName(widgetConfig: HistogramChartWidgetModel): string {
         return widgetConfig.visualizationConfig.selectedProperty.fullDbName;
     }
+
+    private applyAxisLabelFormatting(
+        axis: EChartsOption['xAxis'] | EChartsOption['yAxis'] | undefined,
+        decimals: number,
+    ): void {
+        if (!axis) {
+            return;
+        }
+
+        if (Array.isArray(axis)) {
+            axis.forEach(a => {
+                (a as any).axisLabel = {
+                    ...(a as any).axisLabel,
+                    formatter: (value: number | string) =>
+                        this.formatNumber(value, decimals),
+                };
+            });
+            return;
+        }
+
+        (axis as any).axisLabel = {
+            ...(axis as any).axisLabel,
+            formatter: (value: number | string) =>
+                this.formatNumber(value, decimals),
+        };
+    }
 }
diff --git 
a/ui/src/app/chart-shared/components/charts/pie/pie-renderer.service.ts 
b/ui/src/app/chart-shared/components/charts/pie/pie-renderer.service.ts
index 8c61215663..5b4aaf3430 100644
--- a/ui/src/app/chart-shared/components/charts/pie/pie-renderer.service.ts
+++ b/ui/src/app/chart-shared/components/charts/pie/pie-renderer.service.ts
@@ -86,11 +86,12 @@ export class SpPieRendererService extends 
SpBaseSingleFieldEchartsRenderer<
     addSeriesItem(
         name: string,
         datasetIndex: number,
-        _widgetConfig: PieChartWidgetModel,
+        widgetConfig: PieChartWidgetModel,
     ): PieSeriesOption {
-        const innerRadius = _widgetConfig.visualizationConfig.selectedRadius;
+        const innerRadius = widgetConfig.visualizationConfig.selectedRadius;
         const colorMapping =
-            _widgetConfig.visualizationConfig.colorMappingsPieChart;
+            widgetConfig.visualizationConfig.colorMappingsPieChart;
+        const decimals = this.getDecimals(widgetConfig);
 
         return {
             name,
@@ -103,7 +104,15 @@ export class SpPieRendererService extends 
SpBaseSingleFieldEchartsRenderer<
                         colorMapping.find(
                             c => c.value === params.value[0]?.toString(),
                         )?.label || params.value[0];
-                    return `${params.marker} ${mappedLabel} 
<b>${params.value[1]}</b> (${params.percent}%)`;
+                    const formattedValue = this.formatNumber(
+                        params.value[1],
+                        decimals,
+                    );
+                    const formattedPercent =
+                        typeof params.percent === 'number'
+                            ? this.formatNumber(params.percent, decimals)
+                            : params.percent;
+                    return `${params.marker} ${mappedLabel} 
<b>${formattedValue}</b> (${formattedPercent}%)`;
                 },
             },
             label: {
@@ -112,7 +121,11 @@ export class SpPieRendererService extends 
SpBaseSingleFieldEchartsRenderer<
                         colorMapping.find(
                             c => c.value === params.value[0]?.toString(),
                         )?.label || params.value[0];
-                    return `${mappedLabel} (${params.percent}%)`;
+                    const formattedPercent =
+                        typeof params.percent === 'number'
+                            ? this.formatNumber(params.percent, decimals)
+                            : params.percent;
+                    return `${mappedLabel} (${formattedPercent}%)`;
                 },
             },
             encode: { itemName: 'name', value: 'value' },
diff --git 
a/ui/src/app/chart-shared/components/charts/scatter/scatter-renderer.service.ts 
b/ui/src/app/chart-shared/components/charts/scatter/scatter-renderer.service.ts
index c25272d75d..cf6802114e 100644
--- 
a/ui/src/app/chart-shared/components/charts/scatter/scatter-renderer.service.ts
+++ 
b/ui/src/app/chart-shared/components/charts/scatter/scatter-renderer.service.ts
@@ -31,12 +31,17 @@ export class SpScatterRendererService extends 
SpBaseEchartsRenderer<CorrelationC
         widgetConfig: CorrelationChartWidgetModel,
         _widgetSize: WidgetSize,
     ): void {
+        const decimals = this.getDecimals(widgetConfig);
         const xField = this.getXField(widgetConfig);
         const yField = this.getYField(widgetConfig);
         const dataset = this.datasetUtilsService.findPreparedDataset(
             generatedDataset,
             xField.sourceIndex,
         );
+        const tooltip =
+            !Array.isArray(options.tooltip) && options.tooltip
+                ? options.tooltip
+                : {};
         const series = [];
         for (
             let i = 0;
@@ -66,6 +71,10 @@ export class SpScatterRendererService extends 
SpBaseEchartsRenderer<CorrelationC
                 type: 'value',
                 min: 'dataMin',
                 max: 'dataMax',
+                axisLabel: {
+                    formatter: (value: number | string) =>
+                        this.formatNumber(value, decimals),
+                },
                 name:
                     widgetConfig.visualizationConfig.labelX ||
                     `${xField.fullDbName}${xField.measurementUnitResourceId ? 
` (${xField.measurementUnitResourceId.split('#').pop()})` : ''}`,
@@ -79,6 +88,10 @@ export class SpScatterRendererService extends 
SpBaseEchartsRenderer<CorrelationC
                 type: 'value',
                 min: 'dataMin',
                 max: 'dataMax',
+                axisLabel: {
+                    formatter: (value: number | string) =>
+                        this.formatNumber(value, decimals),
+                },
                 name:
                     widgetConfig.visualizationConfig.labelY ||
                     `${yField.fullDbName}${yField.measurementUnitResourceId ? 
` (${yField.measurementUnitResourceId.split('#').pop()})` : ''}`,
@@ -89,6 +102,11 @@ export class SpScatterRendererService extends 
SpBaseEchartsRenderer<CorrelationC
                 nameGap: 40,
             },
             series,
+            tooltip: {
+                ...tooltip,
+                valueFormatter: (value: unknown) =>
+                    this.formatNumber(value, decimals),
+            },
         });
     }
 
diff --git 
a/ui/src/app/chart-shared/components/charts/time-series-chart/sp-timeseries-renderer.service.ts
 
b/ui/src/app/chart-shared/components/charts/time-series-chart/sp-timeseries-renderer.service.ts
index e0a603bd1c..6cbe67b849 100644
--- 
a/ui/src/app/chart-shared/components/charts/time-series-chart/sp-timeseries-renderer.service.ts
+++ 
b/ui/src/app/chart-shared/components/charts/time-series-chart/sp-timeseries-renderer.service.ts
@@ -46,7 +46,8 @@ export class SpTimeseriesRendererService extends 
SpBaseEchartsRenderer<TimeSerie
         widgetConfig: TimeSeriesChartWidgetModel,
         widgetSize: WidgetSize,
     ): void {
-        this.addAxisOptions(widgetConfig, options, widgetSize);
+        const decimals = this.getDecimals(widgetConfig);
+        this.addAxisOptions(widgetConfig, options, widgetSize, decimals);
         const finalSeries: SeriesOption[] = [];
 
         
widgetConfig.visualizationConfig.selectedTimeSeriesChartProperties.forEach(
@@ -110,6 +111,8 @@ export class SpTimeseriesRendererService extends 
SpBaseEchartsRenderer<TimeSerie
             tooltip: {
                 show: showTooltip,
                 trigger: 'axis',
+                valueFormatter: (value: unknown) =>
+                    this.formatNumber(value, decimals),
                 axisPointer: {
                     type: 'cross',
                 },
@@ -267,6 +270,7 @@ export class SpTimeseriesRendererService extends 
SpBaseEchartsRenderer<TimeSerie
         config: TimeSeriesChartWidgetModel,
         options: EChartsOption,
         widgetSize: WidgetSize,
+        decimals: number,
     ): void {
         const xAxisOption = this.axisGeneratorService.makeAxis(
             'time',
@@ -305,6 +309,10 @@ export class SpTimeseriesRendererService extends 
SpBaseEchartsRenderer<TimeSerie
                 position: axis as CartesianAxisPosition,
                 min: settings.autoScaleActive ? undefined : settings.axisMin,
                 max: settings.autoScaleActive ? undefined : settings.axisMax,
+                axisLabel: {
+                    formatter: (value: number | string) =>
+                        this.formatNumber(value, decimals),
+                },
             });
             axisIndex++;
         });
diff --git 
a/ui/src/app/chart-shared/components/charts/value-heatmap/value-heatmap-renderer.service.ts
 
b/ui/src/app/chart-shared/components/charts/value-heatmap/value-heatmap-renderer.service.ts
index 502ad7c125..18cadbe9b6 100644
--- 
a/ui/src/app/chart-shared/components/charts/value-heatmap/value-heatmap-renderer.service.ts
+++ 
b/ui/src/app/chart-shared/components/charts/value-heatmap/value-heatmap-renderer.service.ts
@@ -92,9 +92,10 @@ export class SpValueHeatmapRendererService extends 
SpBaseSingleFieldEchartsRende
     addSeriesItem(
         name: string,
         datasetIndex: number,
-        _widgetConfig: ValueHeatmapChartWidgetModel,
+        widgetConfig: ValueHeatmapChartWidgetModel,
         index: number,
     ): HeatmapSeriesOption {
+        const decimals = this.getDecimals(widgetConfig);
         return {
             universalTransition: true,
             animation: true,
@@ -107,7 +108,7 @@ export class SpValueHeatmapRendererService extends 
SpBaseSingleFieldEchartsRende
             tooltip: {
                 valueFormatter: value => {
                     if (typeof value === 'number' && isFinite(value)) {
-                        return (value * 100).toFixed(3) + '%';
+                        return this.formatNumber(value * 100, decimals) + '%';
                     } else {
                         return value as string;
                     }
diff --git a/ui/src/app/chart-shared/echarts-renderer/base-echarts-renderer.ts 
b/ui/src/app/chart-shared/echarts-renderer/base-echarts-renderer.ts
index 416ad2774b..1b4ecd1991 100644
--- a/ui/src/app/chart-shared/echarts-renderer/base-echarts-renderer.ts
+++ b/ui/src/app/chart-shared/echarts-renderer/base-echarts-renderer.ts
@@ -102,4 +102,32 @@ export abstract class SpBaseEchartsRenderer<
     > {
         return {};
     }
+
+    protected getDecimals(widgetConfig: T): number {
+        const appearanceConfig =
+            widgetConfig.baseAppearanceConfig as WidgetEchartsAppearanceConfig;
+        return 
this.normalizeDecimals(appearanceConfig?.numberFormat?.decimals);
+    }
+
+    protected formatNumber(value: unknown, decimals: number): string {
+        const numericValue = typeof value === 'number' ? value : Number(value);
+        if (Number.isFinite(numericValue)) {
+            return numericValue.toFixed(this.normalizeDecimals(decimals));
+        }
+
+        if (value === null || value === undefined) {
+            return '';
+        }
+
+        return String(value);
+    }
+
+    private normalizeDecimals(decimals: unknown): number {
+        const parsedValue = Number(decimals);
+        if (!Number.isFinite(parsedValue)) {
+            return 2;
+        }
+
+        return Math.min(10, Math.max(0, Math.round(parsedValue)));
+    }
 }
diff --git 
a/ui/src/app/chart-shared/echarts-renderer/echarts-basic-options-generator.service.ts
 
b/ui/src/app/chart-shared/echarts-renderer/echarts-basic-options-generator.service.ts
index 6eab87f218..bae2997adb 100644
--- 
a/ui/src/app/chart-shared/echarts-renderer/echarts-basic-options-generator.service.ts
+++ 
b/ui/src/app/chart-shared/echarts-renderer/echarts-basic-options-generator.service.ts
@@ -35,6 +35,12 @@ export class EchartsBasicOptionsGeneratorService {
             showLegend: true,
             showTooltip: true,
         };
+        appearanceConfig.numberFormat ??= {
+            decimals: 2,
+        };
+        appearanceConfig.numberFormat.decimals = this.normalizeDecimals(
+            appearanceConfig.numberFormat.decimals,
+        );
 
         return {
             legend: {
@@ -56,4 +62,11 @@ export class EchartsBasicOptionsGeneratorService {
             },
         };
     }
+
+    private normalizeDecimals(decimals: number): number {
+        if (!Number.isFinite(decimals)) {
+            return 2;
+        }
+        return Math.min(10, Math.max(0, Math.round(decimals)));
+    }
 }
diff --git a/ui/src/app/chart-shared/models/dataview-dashboard.model.ts 
b/ui/src/app/chart-shared/models/dataview-dashboard.model.ts
index 8a6dc64a9a..a895a9ceae 100644
--- a/ui/src/app/chart-shared/models/dataview-dashboard.model.ts
+++ b/ui/src/app/chart-shared/models/dataview-dashboard.model.ts
@@ -100,6 +100,10 @@ export interface WidgetChartAppearanceConfig {
     showTooltip: boolean;
 }
 
+export interface WidgetNumberFormatConfig {
+    decimals: number;
+}
+
 export interface DataZoomConfig {
     show: boolean;
     type: 'slider' | 'inside';
@@ -111,6 +115,7 @@ export interface TimeSeriesAppearanceConfig extends 
WidgetEchartsAppearanceConfi
 
 export interface WidgetEchartsAppearanceConfig {
     chartAppearance: WidgetChartAppearanceConfig;
+    numberFormat?: WidgetNumberFormatConfig;
 }
 
 export interface WidgetBaseAppearanceConfig {

Reply via email to