Question

I need help adding a marker to this donut chart script I've modified utilizing raphael.js. I've got most everything ready to go except for a way to dynamically generate a triangular marker.

JSFiddle: http://jsfiddle.net/aP7MK/73/

function donutChart(total, goal, avg){

    var paper = Raphael("canvas", 400, 400);
    paper.customAttributes.arc = function (xloc, yloc, value, total, R) {
        var alpha = 360 / total * value,
            a = (90 - alpha) * Math.PI / 180,
            x = xloc + R * Math.cos(a),
            y = yloc - R * Math.sin(a),
            path;
        if (total == value) {
            path = [
                ["M", xloc, yloc - R],
                ["A", R, R, 0, 1, 1, xloc - 0.01, yloc - R]
            ];
        } else {
            path = [
                ["M", xloc, yloc - R],
                ["A", R, R, 0, +(alpha > 180), 1, x, y]
            ];
        }
        return {
            path: path
        };
    };

    var backCircle = paper.circle(100, 100, 40).attr({
        "stroke": "#7BC2E5",
            "stroke-width": 14
    });

    var theArc = paper.path().attr({
        "stroke": "#f5f5f5",
            "stroke-width": 14,
        arc: [100, 100, 0, 100, 40]
    });


    //event fired on each animation frame
    eve.on("raphael.anim.frame.*", onAnimate);

    //text in the middle
    theText = paper.text(100, 100, "0%").attr({
        "font-size": 18,
            "fill": "#f5f5f5",
            "font-weight": "bold"
    });

    //the animated arc
    theArc.rotate(0, 100, 100).animate({
        arc: [100, 100, ((total/goal) * 100), 100, 40]
    }, 1900);


    //on each animation frame we change the text in the middle

    function onAnimate() {
        var howMuch = theArc.attr("arc");
        theText.attr("text", Math.floor(howMuch[2]) + "%");
    }
}

donutChart(80, 140, 40);

Here's what I'm eventually trying to create:

I'm not worried about the styling, just need help with the marker element, which will denote where the avg argument being passed to the donutChart function lies within the chart.

Was it helpful?

Solution

As @Ian said you can use path to draw triangle:

// triangle
var tri = paper.path("M100 50 L90 40 L110 40 L100 50 Z");

See the docs about using path (its commands).

Then you need to rotate/translate (again as @Ian said) but SVG helps you here providing rotate method which takes not only angle of rotation but also coordinates of point to rotate around (it translates coordinates for you)

tri.rotate((howMuch[2] - prev_percent) * 3.6, 100, 100);

The only thing here to note is that you need difference of previous and current percentage.

The working fiddle

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top