From 0446045a973b9e5a0b4ec742ec36f4a718b39cb0 Mon Sep 17 00:00:00 2001 From: Eliad Moosavi Date: Mon, 9 Dec 2019 15:37:40 -0500 Subject: [PATCH] feat(core, angular, react, vue): allow customizations to pie labels & the donut center number (#427) --- packages/core/src/components/graphs/donut.ts | 43 +++++++++++--------- packages/core/src/components/graphs/pie.ts | 8 +++- packages/core/src/configuration.ts | 6 ++- packages/core/src/interfaces/charts.ts | 4 ++ 4 files changed, 40 insertions(+), 21 deletions(-) diff --git a/packages/core/src/components/graphs/donut.ts b/packages/core/src/components/graphs/donut.ts index 4d078835b3..d4c6bee5b7 100644 --- a/packages/core/src/components/graphs/donut.ts +++ b/packages/core/src/components/graphs/donut.ts @@ -7,16 +7,6 @@ import { Tools } from "../../tools"; import { select } from "d3-selection"; import { interpolateNumber } from "d3-interpolate"; -const donutCenterNumberTween = (d3Ref, newNumber: number) => { - // Remove commas from the current value string, and convert to an int - const currentValue = parseInt(d3Ref.text().replace(/[, ]+/g, ""), 10) || 0; - const i = interpolateNumber(currentValue, newNumber); - - const formatInterpolatedValue = number => Math.floor(number).toLocaleString(); - - return t => d3Ref.text(formatInterpolatedValue(i(t))); -}; - export class Donut extends Pie { type = "donut"; @@ -24,26 +14,21 @@ export class Donut extends Pie { // Call render() from Pie super.render(animate); + const self = this; + const svg = DOMUtils.appendOrSelect(this.getContainerSVG(), "g.center"); const options = this.model.getOptions(); // Compute the outer radius needed const radius = this.computeRadius(); - let donutCenterFigure = Tools.getProperty(options, "center", "number"); - if (!donutCenterFigure) { - donutCenterFigure = this.getDataList().reduce((accumulator, d) => { - return accumulator + d.value; - }, 0); - } - // Add the number shown in the center of the donut DOMUtils.appendOrSelect(svg, "text.donut-figure") .attr("text-anchor", "middle") .style("font-size", () => options.donut.center.numberFontSize(radius)) .transition(this.services.transitions.getTransition("donut-figure-enter-update", animate)) .tween("text", function() { - return donutCenterNumberTween(select(this), donutCenterFigure); + return self.centerNumberTween(select(this)); }); // Add the label below the number in the center of the donut @@ -51,7 +36,7 @@ export class Donut extends Pie { .attr("text-anchor", "middle") .style("font-size", () => options.donut.center.titleFontSize(radius)) .attr("y", options.donut.center.titleYPosition(radius)) - .text(options.donut.center.label); + .text(Tools.getProperty(options, "donut", "center", "label")); } getInnerRadius() { @@ -60,4 +45,24 @@ export class Donut extends Pie { return radius * (3 / 4); } + + centerNumberTween(d3Ref) { + const options = this.model.getOptions(); + + let donutCenterFigure = Tools.getProperty(options, "donut", "center", "number"); + if (!donutCenterFigure) { + donutCenterFigure = this.getDataList().reduce((accumulator, d) => { + return accumulator + d.value; + }, 0); + } + + // Remove commas from the current value string, and convert to an int + const currentValue = parseInt(d3Ref.text().replace(/[, ]+/g, ""), 10) || 0; + const i = interpolateNumber(currentValue, donutCenterFigure); + + return t => { + const { numberFormatter } = options.donut.center; + d3Ref.text(numberFormatter(i(t))); + }; + } } diff --git a/packages/core/src/components/graphs/pie.ts b/packages/core/src/components/graphs/pie.ts index 35fab4eb1d..18638c0a7a 100644 --- a/packages/core/src/components/graphs/pie.ts +++ b/packages/core/src/components/graphs/pie.ts @@ -124,7 +124,13 @@ export class Pie extends Component { const calloutData = []; enteringLabels.merge(labels) .style("text-anchor", "middle") - .text(d => Tools.convertValueToPercentage(d.data.value, dataList) + "%") + .text(d => { + if (options.pie.labels.formatter) { + return options.pie.labels.formatter(d); + } + + return Tools.convertValueToPercentage(d.data.value, dataList) + "%"; + }) // Calculate dimensions in order to transform .datum(function(d) { const textLength = this.getComputedTextLength(); diff --git a/packages/core/src/configuration.ts b/packages/core/src/configuration.ts index 91356c25ae..56129f60fb 100644 --- a/packages/core/src/configuration.ts +++ b/packages/core/src/configuration.ts @@ -202,6 +202,9 @@ const pieChart: PieChartOptions = Tools.merge({}, chart, { offsetY: 12, horizontalLineLength: 8, textMargin: 2 + }, + labels: { + formatter: null } } } as PieChartOptions); @@ -214,7 +217,8 @@ const donutChart: DonutChartOptions = Tools.merge({}, pieChart, { center: { numberFontSize: radius => Math.min((radius / 100) * 24, 24) + "px", titleFontSize: radius => Math.min((radius / 100) * 15, 15) + "px", - titleYPosition: radius => Math.min((radius / 80) * 20, 20) + titleYPosition: radius => Math.min((radius / 80) * 20, 20), + numberFormatter: number => Math.floor(number).toLocaleString() } } } as DonutChartOptions); diff --git a/packages/core/src/interfaces/charts.ts b/packages/core/src/interfaces/charts.ts index 10f0edb800..932399c299 100644 --- a/packages/core/src/interfaces/charts.ts +++ b/packages/core/src/interfaces/charts.ts @@ -129,6 +129,9 @@ export interface PieChartOptions extends BaseChartOptions { offsetY?: number; horizontalLineLength?: number; textMargin?: number; + }, + labels?: { + formatter?: Function; } }; } @@ -144,6 +147,7 @@ export interface DonutChartOptions extends PieChartOptions { numberFontSize?: Function; titleFontSize?: Function; titleYPosition?: Function; + numberFormatter?: Function; }; }; }