Skip to content

Commit

Permalink
fix($browser): Fixes the issue with pie labels not lining up on small…
Browse files Browse the repository at this point in the history
…er sizes.

#151
  • Loading branch information
t-mullen authored and theiliad committed Jan 18, 2019
1 parent 3a5ba2b commit 154467f
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 44 deletions.
4 changes: 2 additions & 2 deletions packages/core/src/configuration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -193,8 +193,8 @@ export const pie = {
sliceLimit: 6,
label: {
dy: ".32em",
margin: 15,
other: "Other"
margin: 8,
other: "Other",
},
default: {
strokeWidth: 2
Expand Down
66 changes: 24 additions & 42 deletions packages/core/src/pie-chart.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ export class PieChart extends BaseChart {

// Compute the correct inner & outer radius
const { pie: pieConfigs } = Configuration;
const marginedRadius = radius - (pieConfigs.label.margin * (chartSize.width / pieConfigs.maxWidth));
const marginedRadius = this.computeRadius();
this.arc = arc()
.innerRadius(this.options.type === "donut" ? (marginedRadius * (2 / 3)) : 0)
.outerRadius(marginedRadius);
Expand All @@ -127,16 +127,17 @@ export class PieChart extends BaseChart {
.each(function(d) { this._current = d; });

// Draw the slice labels
const self = this;
this.innerWrap
.selectAll("text.chart-label")
.data(this.pie(dataList), (d: any) => d.data.label)
.enter()
.append("text")
.classed("chart-label", true)
.attr("dy", Configuration.pie.label.dy)
.style("text-anchor", this.deriveTextAnchor)
.attr("transform", d => this.deriveTransformString(d, radius))
.text(d => Tools.convertValueToPercentage(d.data.value, dataList));
.style("text-anchor", "middle")
.text(d => Tools.convertValueToPercentage(d.data.value, dataList))
.attr("transform", function (d) { return self.deriveTransformString(this, d, radius); });

// Hide overlay
this.updateOverlay().hide();
Expand Down Expand Up @@ -212,19 +213,18 @@ export class PieChart extends BaseChart {
.append("text")
.classed("chart-label", true)
.attr("dy", Configuration.pie.label.dy)
.style("text-anchor", this.deriveTextAnchor)
.attr("transform", d => this.deriveTransformString(d, radius))
.style("text-anchor", "middle")
.text(d => Tools.convertValueToPercentage(d.data.value, dataList))
.attr("transform", function (d) { return self.deriveTransformString(this, d, radius); })
.style("opacity", 0)
.transition()
.duration(Configuration.transitions.default.duration / 2)
.style("opacity", 1);

text
.attr("dy", Configuration.pie.label.dy)
.style("text-anchor", this.deriveTextAnchor)
.attr("transform", d => this.deriveTransformString(d, radius))
.style("text-anchor", "middle")
.text(d => Tools.convertValueToPercentage(d.data.value, dataList))
.attr("transform", function (d) { return self.deriveTransformString(this, d, radius); })
.transition()
.duration(Configuration.transitions.default.duration / 2)
.style("opacity", 1);
Expand Down Expand Up @@ -342,8 +342,7 @@ export class PieChart extends BaseChart {

const chartSize: any = this.getChartSize(this.container);
const dimensionToUseForScale = Math.min(chartSize.width, chartSize.height);
const scaleRatio = dimensionToUseForScale / pieConfigs.maxWidth;
const radius: number = dimensionToUseForScale / 2;
const radius: number = this.computeRadius();

// Resize the SVG
select(this.holder).select("svg")
Expand All @@ -353,17 +352,17 @@ export class PieChart extends BaseChart {
.style("transform", `translate(${radius}px,${radius}px)`);

// Resize the arc
const marginedRadius = radius - (pieConfigs.label.margin * scaleRatio);
this.arc = arc()
.innerRadius(this.options.type === "donut" ? (marginedRadius * (2 / 3)) : 0)
.outerRadius(marginedRadius);
.innerRadius(this.options.type === "donut" ? (radius * (2 / 3)) : 0)
.outerRadius(radius);

this.innerWrap.selectAll("path")
.attr("d", this.arc);

const self = this;
this.innerWrap
.selectAll("text.chart-label")
.attr("transform", d => this.deriveTransformString(d, radius));
.attr("transform", function (d) { return self.deriveTransformString(this, d, radius); });

// Reposition the legend
this.positionLegend();
Expand All @@ -386,35 +385,18 @@ export class PieChart extends BaseChart {
* @returns final transform string to be applied to the <text> element
* @memberof PieChart
*/
private deriveTransformString(d, radius) {
const theta = d.endAngle - d.startAngle;
const xPosition = radius * Math.sin((theta / 2) + d.startAngle);
const yPosition = -1 * radius * Math.cos((theta / 2) + d.startAngle);
private deriveTransformString(element, d, radius) {
const textLength = element.getComputedTextLength();
const textOffsetX = textLength / 2;
const textOffsetY = parseFloat(getComputedStyle(element).fontSize) / 2;

return `translate(${xPosition}, ${yPosition})`;
}
const marginedRadius = radius + Configuration.pie.label.margin;

/**
* Decide what text-anchor value the slice label item would need based on the quadrant it's in
*
* @private
* @param {any} d - d3 data item for slice
* @returns computed decision on what the text-anchor string should be
* @memberof PieChart
*/
private deriveTextAnchor(d) {
const QUADRANT = Math.PI / 4;
const rads = (d.endAngle - d.startAngle) / 2 + d.startAngle;

if (rads >= QUADRANT && rads <= 3 * QUADRANT) {
return "start";
} else if ((rads > 7 * QUADRANT && rads < QUADRANT) || (rads > 3 * QUADRANT && rads < 5 * QUADRANT)) {
return "middle";
} else if (rads >= 5 * QUADRANT && rads <= 7 * QUADRANT) {
return "end";
} else {
return "middle";
}
const theta = ((d.endAngle - d.startAngle) / 2) + d.startAngle;
const xPosition = (textOffsetX + marginedRadius) * Math.sin(theta);
const yPosition = (textOffsetY + marginedRadius) * -Math.cos(theta);

return `translate(${xPosition}, ${yPosition})`;
}
}

Expand Down

0 comments on commit 154467f

Please sign in to comment.