代码之家  ›  专栏  ›  技术社区  ›  madmanlear

在Raphael饼图中更新饼图切片大小

  •  4
  • madmanlear  · 技术社区  · 14 年前

    我正在做一个饼图,显示一段时间后的结果。因此,它需要在状态之间设置动画,以显示不同的切片是如何变化的。我已经知道了如何集体改变所有的切片(使用 this example 作为一个起点),但是我希望能够一次选择和管理一个特定的部分(或者拉斐尔所说的扇区)。有人知道怎么做吗?我发现如果var pie是我的饼图,那么我可以得到一个特定的切片:

    var pie = r.g.piechart(200, 200, 150, dataArray);
    slice = pie.series[0];
    

    但是当我尝试用say来改变切片时,动画(特别是改变它的大小)失败了(片段不是正确的方式?):

    slice.animate({segment: [200, 200, 0, 100]}, 800);
    

    任何对操作单个切片的洞察都会非常有帮助。

    1 回复  |  直到 12 年前
        1
  •  7
  •   madmanlear    14 年前

    我很尴尬地意识到,segment属性是一个自定义属性,它是在我发现的更新饼图切片路径的示例中创建和使用的,因此它的大小也是如此。看起来是这样的:

      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)"
          };
      };
    

    这就是上下文中的情况:我有三个值[10,20,15],总共是45。假设一个宽度和高度为250的圆,我可以使用这样的段自定义属性(假设我的页面上有一个带有holder ID的DIV)用切片填充该圆:

    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)"
        };
    };
    points = [10, 20, 15];
    total = 45;
    start = 0;
    paths = [];
    for(i=0; i<=2; i++) {
      size = 360 / total * points[i];
      var slice = r.path();
      slice.attr({segment: [250, 250, 200, start, start + size], stroke: "#000", title: "Slice "+i});
      paths.push(slice);
      start += size;
    }
    

    然后,我可以通过设置分段属性的动画,随时设置路径数组中的切片的动画:

    newPoints = [5, 20, 20];
    start = 0;
    for(i=0; i<=2; i++) {
      size = 360 / total * newPoints[i];
      paths[i].animate({segment: [250, 250, 200, start, start + size]}, 800);
      paths[i].angle = start - size / 2;
      start += size;
    }
    

    有些我理解,有些我不理解。但是上面的代码可以工作(我检查过)。