更新D3 V3 Zoomable Sunburst数据中断图表

时间:2016-12-15 10:58:18

标签: javascript d3.js web data-visualization sunburst-diagram

我是编程D3的新手,我们在更新旭日形图时遇到问题而不会导致其破坏过渡。更改数据后,图表的某些部分将停止调整缩放功能,并且看起来相互重叠。另外,显然,我得到的错误来自图中每个“弧”的标志的插值(即错误:属性d:期望的弧标志('0'或'1'),“...... 125862517296 0 0.987032831999999 ...”。 )。我们正在使用特定于此问题的补间,因此无法理解可能导致它的原因。 由于我对这种语言缺乏经验,所以我花了几天时间来解决这个问题只是为了让它回来。如果你们中的任何人能够提供帮助,我将非常感激。

这是我创建的一个工作小提琴来说明我们的问题: - https://jsfiddle.net/v9ab0vms/1/

通过等待5秒并单击“商业”然后单击“通信”弧可以看到问题。导致转换错误并打破一些弧。在数据发生变化时缩放图形会导致它以其他方式中断,对此的任何帮助也将非常受欢迎。我只是想一步一步地修复它。

Picture of broken chart arcs

代码也必须发布,所以我只是为sunburst插入两个主要功能:

function genSunburst2() {
  var width = d3.select("#container_sunburst").style("width").split("px")[0],
    height = d3.select("#container_sunburst").style("height").split("px")[0],
    radius = Math.min(width, height) / 2;

  var x = d3.scale.linear()
    .range([0, 2 * Math.PI]);

  var y = d3.scale.sqrt()
    .range([0, radius]);

  var color = d3.scale.category20c();

  var svg = d3.select("#sunburst")
    .attr("id", "sunburst")
    .attr("width", width)
    .attr("height", height)
    .select("g")
    .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");

  var partition = d3.layout.partition()
    .value(function(d) {
      return d.size;
    });

  var arc = d3.svg.arc()
    .startAngle(function(d) {
      return Math.max(0, Math.min(2 * Math.PI, x(d.x)));
    })
    .endAngle(function(d) {
      return Math.max(0, Math.min(2 * Math.PI, x(d.x + d.dx)));
    })
    .innerRadius(function(d) {
      return Math.max(0, y(d.y));
    })
    .outerRadius(function(d) {
      return Math.max(0, y(d.y + d.dy));
    });

  function computeTextRotation(d) {
    var angle = x(d.x + d.dx / 2) - Math.PI / 2;
    return angle / Math.PI * 180;
  }

  function arcTween(d) {
    var xd = d3.interpolate(x.domain(), [d.x, d.x + d.dx]),
      yd = d3.interpolate(y.domain(), [d.y, 1]),
      yr = d3.interpolate(y.range(), [d.y ? 20 : 0, radius]);
    return function(d, i) {
      return i ? function(t) {
        return arc(d);
      } : function(t) {
        x.domain(xd(t));
        y.domain(yd(t)).range(yr(t));
        return arc(d);
      };
    };
  }

  function arcTweenUpdate(a) {
    console.log(path);
    var _self = this;
    var i = d3.interpolate({
      x: this.x0,
      dx: this.dx0
    }, a);
    return function(t) {
      var b = i(t);
      console.log(window);
      _self.x0 = b.x;
      _self.dx0 = b.dx;
      return arc(b);
    };
  }

  updateSunburst3 = function() {
    if (sunburstClick) {
      sunburstClick = false;
      return;
    }

    var root = createJsonDataset();
    // DATA JOIN - Join new data with old elements, if any.
    var gs = svg.selectAll("g").data(partition.nodes(root));

    // ENTER
    var g = gs.enter().append("g").on("click", click);

    // UPDATE
    var path = g.append("path");

    gs.select('path')
      .style("fill", function(d) {
        return color(d.name);
      })
      .on("click", click)
      .each(function(d) {
        this.x0 = d.x;
        this.dx0 = d.dx;
      })
      .transition().duration(500)
      .attr("d", arc);

    var text = g.append("text");

    gs.select('text')
      .attr("x", function(d) {
        return y(d.y);
      })
      .attr("dx", "6") // margin
      .attr("dy", ".35em") // vertical-align
      .attr("transform", function(d) {
        return "rotate(" + computeTextRotation(d) + ")";
      })
      .text(function(d) {
        return d.name;
      })
      .style("fill", "white");


    function click(d) {
      sunburstClick = true;
      console.log(d);
      // fade out all text elements
      /*if (d.size !== undefined) {
        d.size += 100;
      };*/

      text.transition().attr("opacity", 0);
      console.log(path);

      for (var i = 0; i < path[0].length; ++i) {
        if (path[0][i] === undefined || path[0][i] === null) {
          path[0].splice(i, 1);
          --i;
        }
      }

      path.transition()
        .duration(750)
        .attrTween("d", arcTween(d))
        .each("end", function(e, i) {
          // check if the animated element's data e lies within the visible angle span given in d
          if (e.x >= d.x && e.x < (d.x + d.dx)) {
            // get a selection of the associated text element
            var arcText = d3.select(this.parentNode).select("text");
            // fade in the text element and recalculate positions
            arcText.transition().duration(750)
              .attr("opacity", 1)
              .attr("transform", function() {
                return "rotate(" + computeTextRotation(e) + ")"
              })
              .attr("x", function(d) {
                return y(d.y);
              });
          }
        });

      userSelection = undefined;
      purposeSelection = undefined;

      // TODO: alterar para ele ter em conta a hierarquia da selecao corrente
      // para so sair de uma hierarquia
      if (typeof d.name != "undefined" && d.name != "") {
        if (typeof d.size === "undefined") {
          userSelection = d.name;
          purposeSelection = undefined;
        } else {
          userSelection = d.parent.name;
          purposeSelection = d.name;
        }
      } else {
        // if only the user was selected, back out to no selection
        if (purposeSelection === undefined && userSelection != undefined) {
          userSelection = undefined;
          // if both the user and the purpose were selected, back out to just user selection
        } else if (purposeSelection != undefined && userSelection != undefined) {
          purposeSelection = undefined;
        }
      }

      applySelection();
    }

    // EXIT - Remove old elements as needed.
    gs.exit().transition().duration(500).style("fill-opacity", 1e-6).remove();
  }
}

提前谢谢

编辑:澄清:

  • 这是D3 V3。
  • 我们有两个变量,一个是完整的数据集 和另一个“工作”数据集。我们完全应用过滤器 数据集并将结果存储在工作数据集中。

0 个答案:

没有答案