7

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.

Mikael Kessler
  • 1,235
  • 1
  • 15
  • 27
  • 1
    Could you use var tri = paper.path("M100,100,130,100,100,130z"); and then rotate/translate it depending on howMuch or something ? – Ian Nov 27 '13 at 10:03
  • Hey @Ian - Sorry, I should've clarified that I don't really have any experience with generating SVGs. I found the code above within another SO question and modified it slightly to be more along the lines of what I'm looking for, but as for drawing and generating paths I have no idea where to start. Any chance you could try updating the example on fiddle with your suggestion? – Mikael Kessler Nov 27 '13 at 18:41

1 Answers1

5

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

twil
  • 6,032
  • 1
  • 30
  • 28
  • 1
    Thanks for the updated fiddle! I've made a few changes to what you set up to further mimic what I need for my final product and was wondering if you know how to color in the triangle or possibly add a straight line within the circle similar to the image above. http://jsfiddle.net/RS882/3/ – Mikael Kessler Dec 09 '13 at 05:44
  • 2
    It's easy http://jsfiddle.net/RS882/4/. Actually you have all the pieces in your code to figure it out – twil Dec 09 '13 at 13:12
  • Nice! I've learned a lot about SVGs from this, thanks again for the help @twil! – Mikael Kessler Dec 09 '13 at 16:23