Skip to content

Commit

Permalink
feat(core, angular, react, vue): allow customizations to pie labels &…
Browse files Browse the repository at this point in the history
… the donut center number (carbon-design-system#427)
  • Loading branch information
theiliad authored and cal-smith committed Dec 9, 2019
1 parent 85afa1f commit 210ddd2
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 21 deletions.
43 changes: 24 additions & 19 deletions packages/core/src/components/graphs/donut.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,51 +7,36 @@ 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";

render(animate = true) {
// 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
DOMUtils.appendOrSelect(svg, "text.donut-title")
.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() {
Expand All @@ -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)));
};
}
}
8 changes: 7 additions & 1 deletion packages/core/src/components/graphs/pie.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
6 changes: 5 additions & 1 deletion packages/core/src/configuration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,9 @@ const pieChart: PieChartOptions = Tools.merge({}, chart, {
offsetY: 12,
horizontalLineLength: 8,
textMargin: 2
},
labels: {
formatter: null
}
}
} as PieChartOptions);
Expand All @@ -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);
Expand Down
4 changes: 4 additions & 0 deletions packages/core/src/interfaces/charts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,9 @@ export interface PieChartOptions extends BaseChartOptions {
offsetY?: number;
horizontalLineLength?: number;
textMargin?: number;
},
labels?: {
formatter?: Function;
}
};
}
Expand All @@ -144,6 +147,7 @@ export interface DonutChartOptions extends PieChartOptions {
numberFontSize?: Function;
titleFontSize?: Function;
titleYPosition?: Function;
numberFormatter?: Function;
};
};
}

0 comments on commit 210ddd2

Please sign in to comment.