Files
dees-catalog/ts_web/elements/00group-chart/dees-chart-gauge/component.ts

162 lines
4.0 KiB
TypeScript

import {
customElement,
property,
type TemplateResult,
} from '@design.estate/dees-element';
import { DeesChartEchartsBase } from '../dees-chart-echarts-base.js';
import { demoFunc } from './demo.js';
import { gaugeStyles } from './styles.js';
import { renderChartGauge } from './template.js';
import { getEchartsSeriesColors, getThemeColors } from '../dees-chart-echarts-theme.js';
export interface IGaugeThreshold {
value: number;
color: string;
}
declare global {
interface HTMLElementTagNameMap {
'dees-chart-gauge': DeesChartGauge;
}
}
@customElement('dees-chart-gauge')
export class DeesChartGauge extends DeesChartEchartsBase {
public static demo = demoFunc;
public static demoGroups = ['Chart'];
@property({ type: Number })
accessor value: number = 0;
@property({ type: Number })
accessor min: number = 0;
@property({ type: Number })
accessor max: number = 100;
@property({ type: String })
accessor unit: string = '%';
@property({ type: Array })
accessor thresholds: IGaugeThreshold[] = [];
@property({ type: Boolean })
accessor showTicks: boolean = true;
public static styles = gaugeStyles;
public render(): TemplateResult {
return renderChartGauge(this);
}
public async updated(changedProperties: Map<string, any>) {
super.updated(changedProperties);
if (
this.chartInstance &&
(changedProperties.has('value') ||
changedProperties.has('min') ||
changedProperties.has('max') ||
changedProperties.has('unit') ||
changedProperties.has('thresholds') ||
changedProperties.has('showTicks'))
) {
this.updateChart();
}
}
protected buildOption(): Record<string, any> {
const colors = getThemeColors(this.goBright);
const seriesColors = getEchartsSeriesColors(this.goBright);
const primaryColor = seriesColors[0];
// Build axis line color stops from thresholds
let axisLineColors: Array<[number, string]>;
if (this.thresholds.length > 0) {
const sorted = [...this.thresholds].sort((a, b) => a.value - b.value);
axisLineColors = sorted.map((t) => [
(t.value - this.min) / (this.max - this.min),
t.color,
]);
// Ensure we end at 1
if (axisLineColors[axisLineColors.length - 1][0] < 1) {
axisLineColors.push([1, sorted[sorted.length - 1].color]);
}
} else {
axisLineColors = [[1, primaryColor]];
}
return {
series: [
{
type: 'gauge',
min: this.min,
max: this.max,
startAngle: 220,
endAngle: -40,
progress: {
show: true,
width: 14,
roundCap: true,
},
pointer: {
show: true,
length: '60%',
width: 5,
itemStyle: {
color: 'auto',
},
},
axisLine: {
lineStyle: {
width: 14,
color: axisLineColors,
opacity: 0.3,
},
},
axisTick: {
show: this.showTicks,
distance: -20,
length: 6,
lineStyle: {
color: colors.borderStrong,
width: 1,
},
},
splitLine: {
show: this.showTicks,
distance: -24,
length: 10,
lineStyle: {
color: colors.textMuted,
width: 2,
},
},
axisLabel: {
show: this.showTicks,
distance: 30,
color: colors.textMuted,
fontSize: 11,
},
detail: {
valueAnimation: true,
fontSize: 28,
fontWeight: 600,
offsetCenter: [0, '65%'],
color: colors.textPrimary,
formatter: `{value}${this.unit}`,
},
title: {
show: false,
},
data: [
{
value: this.value,
},
],
},
],
};
}
}