Skip to content

Automatic placement of pie chart labels #591

@Thom1729

Description

@Thom1729

It would be nice to have an option to automatically place the label within a segment of a pie chart in an aesthetically reasonable location. I suggest computing the largest circle that can be inscribed within a segment and placing the label at the center of that circle.

inscribedsections

image

Implementation:

function pieLabelRadius(fraction) {
    if (fraction === 1) {
        return 0;
    } else if (fraction >= .5) {
        return 0.5;
    } else {
        const t = Math.tan(fraction * Math.PI / 2);
        return (2*t) / ((1+t)*(1+t));
    }
}

const MyPie = ({ data, height, width }) => {
    const total = data.map(datum => datum.value).reduce((a,b) => a+b);
    const actualWidth = width - marginsAndSuch;

    return <div>
        <V.VictoryPie
            data={ data }
            height={ height }
            width={ width }

            x="name"
            y="value"

            labels={ datum => '$'+datum.value.toFixed(2) }

            labelRadius={ (args) => actualWidth*(1-pieLabelRadius(args.value/total)) }
            style={{
                labels: {
                    textAnchor: "middle",
                    verticalAnchor: "middle",
                }
            }}
        />
    </div>;
};

An alternative approach is using the centroid of the section. I tried this approach as well, and it didn't seem to look quite as nice.

function pieLabelRadius(fraction) {
    const theta = Math.min(fraction, 0.5) * Math.PI;
    return (5/8) * (Math.sin(theta)/theta);
}

P.S. If a pie chart has an inner radius, then all you have to do is take the minimum of pieLabelRadius and the difference between the outer and inner radii.

P.P.S. As with #586, it may be that the best solution is a general framework for handling complex pluggable layout strategies.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type: Enhancement ✏️An enhancement or feature proposal that will be addressed after the next release

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions