如何更改此Raphael绘制的饼图,以使颜色不变

问题描述:

我正在尝试更改此饼图,以便在单击细分时,不同细分的颜色不会改变.我看到填充与线段的形状有直接关系,但我完全糟透了.请帮忙!您可以在此处查看运行中的饼图:

I'm trying to change this pie chart, so that when I click on a segment, the color of the different segments don't change. I see that the fill has a direct relationship with the shape of the segment, but I totally suck. Please help! You can see the pie chart in action here:

http://raphaeljs.com/growing-pie.html

function drawgrowingpie () {
    var r = Raphael("holder");

    r.customAttributes.segment = function (x, y, r, a1, a2) {
        var flag = (a2 - a1) > 180,
            clr = (a2 - a1) / 360;
        a1 = (a1 % 360) * Math.PI / 180;
        a2 = (a2 % 360) * Math.PI / 180;
        return {
            path: [["M", x, y], ["l", r * Math.cos(a1), r * Math.sin(a1)], ["A", r, r, 0, +flag, 1, x + r * Math.cos(a2), y + r * Math.sin(a2)], ["z"]],
            fill: "hsb(" + clr + ", .75, .8)"
        };
    };

    function animate(ms) {
        var start = 0,
            val;
        for (i = 0; i < ii; i++) {
            val = 360 / total * data[i];
            paths[i].animate({segment: [200, 200, 150, start, start += val]}, ms || 1500, "bounce");
            paths[i].angle = start - val / 2;
        }
    }

    var data = [24, 92, 24, 52, 78, 99, 82, 27],
        paths = r.set(),
        total,
        start,
        bg = r.circle(200, 200, 0).attr({stroke: "#fff", "stroke-width": 4});
    data = data.sort(function (a, b) { return b - a;});

    total = 0;
    for (var i = 0, ii = data.length; i < ii; i++) {
        total += data[i];
    }
    start = 0;
    for (i = 0; i < ii; i++) {
        var val = 360 / total * data[i];
        (function (i, val) {
            paths.push(r.path().attr({segment: [200, 200, 1, start, start + val], stroke: "#fff"}).click(function () {
                total += data[i];
                data[i] *= 2;
                animate();
            }));
        })(i, val);
        start += val;
    }
    bg.animate({r: 151}, 1000, "bounce");
    animate(1000);
};

更改

return {
    // snip...
    fill: "hsb(" + clr + ", .75, .8)"
};

其他,或从返回的对象中完全删除fill属性.

to something else, or remove the fill property entirely from the returned object.

这是在正确方向上的微调:现在,将颜色传递给segment函数,而不是每次使切片动画时都改变颜色.这意味着两个不同的调用者(初始化程序和单击处理程序)可以不同地控制颜色.如果未传递任何clr(彩色),则segment函数已更改为不返回任何 fill信息.这意味着click处理程序不会更改颜色,因为只有初始化代码才能传递颜色信息.

Here's a nudge in the right direction: instead of changing the color every time a slice is animated, the color is now passed to the segment function. This means that the two different callers (the initializer and the click handler) can control the color differently. The segment function is changed to not return any fill information if no clr (color) was passed to it. This means the color is unchanged by the click handler, since only the initialization code passes color information.

希望这对您有意义.

function drawgrowingpie() {
    var r = Raphael("holder");
                                                        // ↓↓↓ pass the color
    r.customAttributes.segment = function(x, y, r, a1, a2, clr) {
        var flag = (a2 - a1) > 180;
        a1 = (a1 % 360) * Math.PI / 180;
        a2 = (a2 % 360) * Math.PI / 180;
        var props = {
            path: [["M", x, y], ["l", r * Math.cos(a1), r * Math.sin(a1)], ["A", r, r, 0, +flag, 1, x + r * Math.cos(a2), y + r * Math.sin(a2)], ["z"]]
        };

        // only return fill properties if the color was passed
        if (clr) {
            props.fill = "hsb(" + clr + ", .75, .8)";
            console.log(clr);
        }
        return props;
    };

    function animate(ms) {
        var start = 0,
            val;
        for (i = 0; i < ii; i++) {
            val = 360 / total * data[i];
            paths[i].animate({
                // notice that no color data is passed here...
                segment: [200, 200, 150, start, start += val]
            }, ms || 1500, "bounce");
            paths[i].angle = start - val / 2;
        }
    }

    var data = [24, 92, 24, 52, 78, 99, 82, 27],
        paths = r.set(),
        total, start, bg = r.circle(200, 200, 0).attr({
            stroke: "#fff",
            "stroke-width": 4
        });
    data = data.sort(function(a, b) {
        return b - a;
    });

    total = 0;
    for (var i = 0, ii = data.length; i < ii; i++) {
        total += data[i];
    }
    start = 0;
    for (i = 0; i < ii; i++) {
        var val = 360 / total * data[i];
        (function(i, val) {
            paths.push(r.path().attr({
                // ...but we do pass color data here      ↓↓↓↓  
                segment: [200, 200, 1, start, start + val, val],
                stroke: "#fff"
            }).click(function() {
                total += data[i];
                data[i] *= 2;
                animate();
            }));
        })(i, val);
        start += val;
    }
    bg.animate({
        r: 151
    }, 1000, "bounce");
    animate(1000);
}

http://jsfiddle.net/mattball/xsfQj/