Skip to content

Commit

Permalink
feat: pie/donut now shows the value of the serie instead of the perce…
Browse files Browse the repository at this point in the history
…ntage. Old behavior with `datalabels: percent`
  • Loading branch information
RomRider committed Jul 4, 2021
1 parent 9a1b2c1 commit 7591aba
Show file tree
Hide file tree
Showing 8 changed files with 37 additions and 9 deletions.
4 changes: 4 additions & 0 deletions .devcontainer/ui-lovelace.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -450,6 +450,10 @@ views:
title: pie
series:
- entity: sensor.random0_100
unit: kWh
show:
datalabels: percent

- entity: sensor.random_0_1000
- type: custom:apexcharts-card
chart_type: donut
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ The card stricly validates all the options available (but not for the `apex_conf
| `name_in_header` | boolean | `true` | v1.8.0 | Only valid if `in_header: true`. If `false`, it will hide the name of the serie under the its state in the header |
| `header_color_threshold` | boolean | `false` | v1.7.0 | If `true` and `color_threshold` experimental mode is enabled, it will colorize the header's state based on the threshold (ignoring opacity). |
| `in_chart` | boolean | `true` | v1.4.0 | If `false`, hides the serie from the chart |
| `datalabels` | boolean or string | `false` | v1.5.0 | If `true` will show the value of each point for this serie directly in the chart. Don't use it if you have a lot of points displayed, it will be a mess. If you set it to `total` (introduced in v1.7.0), it will display the stacked total value (only works when `stacked: true`) |
| `datalabels` | boolean or string | `false` | v1.5.0 | If `true` will show the value of each point for this serie directly in the chart. Don't use it if you have a lot of points displayed, it will be a mess. If you set it to `total` (introduced in v1.7.0), it will display the stacked total value (only works when `stacked: true`). If you set it to `percent`, it will display the percentage of the serie instead of the value in the case of a `pie` or `donut` chart. |
| `hidden_by_default` | boolean | `false` | v1.6.0 | See [experimental](#hidden_by_default-experimental-feature) |
| `extremas` | boolean or string | `false` | v1.7.0 | If `true`, will show the min and the max of the serie in the chart. If the value is `time`, it will display also the time of the min/max value on top of the value. This feature doesn't work with `stacked: true`. |
| `in_brush` | boolean | `false` | v1.8.0 | See [brush](#brush-experimental-feature) |
Expand Down
25 changes: 22 additions & 3 deletions src/apex-layouts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,13 @@ import { ChartCardConfig } from './types';
import { computeName, computeUom, is12Hour, mergeDeep, prettyPrintTime, truncateFloat } from './utils';
import { layoutMinimal } from './layouts/minimal';
import { getLocales, getDefaultLocale } from './locales';
import GraphEntry from './graphEntry';

export function getLayoutConfig(config: ChartCardConfig, hass: HomeAssistant | undefined = undefined): unknown {
export function getLayoutConfig(
config: ChartCardConfig,
hass: HomeAssistant | undefined = undefined,
graphs: (GraphEntry | undefined)[] | undefined,
): unknown {
const locales = getLocales();
const def = {
chart: {
Expand Down Expand Up @@ -58,7 +63,7 @@ export function getLayoutConfig(config: ChartCardConfig, hass: HomeAssistant | u
dataLabels: {
enabled: getDataLabelsEnabled(config),
enabledOnSeries: getDataLabels_enabledOnSeries(config),
formatter: getDataLabelsFormatter(config),
formatter: getDataLabelsFormatter(config, graphs),
},
plotOptions: {
radialBar: getPlotOptions_radialBar(config),
Expand Down Expand Up @@ -313,7 +318,21 @@ function getDataLabelsEnabled(config: ChartCardConfig): boolean {
);
}

function getDataLabelsFormatter(config: ChartCardConfig) {
function getDataLabelsFormatter(config: ChartCardConfig, graphs: (GraphEntry | undefined)[] | undefined) {
if (config.chart_type === 'pie' || config.chart_type === 'donut') {
return function (value, opts, lgraphs = graphs, conf = config) {
if (conf.series_in_graph[opts.seriesIndex].show.datalabels !== false) {
if (conf.series_in_graph[opts.seriesIndex].show.datalabels === 'percent') {
return truncateFloat(value, conf.series_in_graph[opts.seriesIndex].float_precision);
}
return truncateFloat(
lgraphs?.[conf.series_in_graph[opts.seriesIndex].index]?.lastState,
conf.series_in_graph[opts.seriesIndex].float_precision,
);
}
return '';
};
}
return function (value, opts, conf = config) {
if (conf.series_in_graph[opts.seriesIndex].show.datalabels === 'total') {
return truncateFloat(
Expand Down
2 changes: 1 addition & 1 deletion src/apexcharts-card.ts
Original file line number Diff line number Diff line change
Expand Up @@ -705,7 +705,7 @@ class ChartsCard extends LitElement {
if (!this._apexChart && this.shadowRoot && this._config && this.shadowRoot.querySelector('#graph')) {
this._loaded = true;
const graph = this.shadowRoot.querySelector('#graph');
const layout = getLayoutConfig(this._config, this._hass);
const layout = getLayoutConfig(this._config, this._hass, this._graphs);
if (this._config.series_in_brush.length) {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
(layout as any).chart.id = Math.random().toString(36).substring(7);
Expand Down
4 changes: 4 additions & 0 deletions src/graphEntry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,10 @@ export default class GraphEntry {
this._cache = cache;
}

get lastState(): number | null {
return this.history.length > 0 ? this.history[this.history.length - 1][1] : null;
}

public nowValue(now: number, before: boolean): number | null {
if (this.history.length === 0) return null;
const index = this.history.findIndex((point, index, arr) => {
Expand Down
2 changes: 1 addition & 1 deletion src/types-config-ti.ts
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ export const ChartCardSeriesShowConfigExt = t.iface([], {
"name_in_header": t.opt("boolean"),
"header_color_threshold": t.opt("boolean"),
"in_chart": t.opt("boolean"),
"datalabels": t.opt(t.union("boolean", t.lit('total'))),
"datalabels": t.opt(t.union("boolean", t.lit('total'), t.lit('percent'))),
"hidden_by_default": t.opt("boolean"),
"extremas": t.opt(t.union("boolean", t.lit('time'))),
"in_brush": t.opt("boolean"),
Expand Down
2 changes: 1 addition & 1 deletion src/types-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ export interface ChartCardSeriesShowConfigExt {
name_in_header?: boolean;
header_color_threshold?: boolean;
in_chart?: boolean;
datalabels?: boolean | 'total';
datalabels?: boolean | 'total' | 'percent';
hidden_by_default?: boolean;
extremas?: boolean | 'time';
in_brush?: boolean;
Expand Down
5 changes: 3 additions & 2 deletions src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -234,8 +234,9 @@ export function is12Hour(locale: string): boolean {
return !(new Date(2021, 1, 1, 15, 0, 0, 0).toLocaleTimeString(locale).indexOf('15') > -1);
}

export function truncateFloat(value: number | null, precision: number | undefined): string | number | null {
let lValue: string | number | null = value;
export function truncateFloat(value: number | null | undefined, precision: number | undefined): string | number | null {
let lValue: string | number | null | undefined = value;
if (lValue === undefined) return null;
if (value !== null && typeof value === 'number' && !Number.isInteger(value)) {
lValue = (lValue as number).toFixed(precision === undefined ? DEFAULT_FLOAT_PRECISION : precision);
}
Expand Down

0 comments on commit 7591aba

Please sign in to comment.