在过渡甜甜圈图中维护对象的恒定性

时间:2015-05-31 18:18:45

标签: javascript d3.js

我是d3的新手但到了那里。

我无法使用不同大小的数据集维护对象的持久性。 我把它设置在这里。 (我很难让jsfiddle工作)

http://bricbracs.com/test/

初始图表有三个弧线。当您单击一个段弧时,它将使用新数据(使用嵌套函数)进行更新,并且应该返回四个具有四个相应弧的数据元素。你可以看到它只返回三个弧线。什么是最好的方式和最简单的方法来使这个工作变得明显,以便它显示四个segemnts?

我见过这个http://bl.ocks.org/mbostock/5681842。但我正在使用具有汇总功能的嵌套函数。

这是一个csv文件(简化版本,可能没有必要)。

status,dept,city,points
temp,finance,New York,33
contract,HR,London,12
contract,HR,New York,11
casual,shop,London,43
temp,sales,New York,14
contract,shop,Paris,51
temp,finance,London,7
contract,office,New York,61
contract,shop,London,31
temp,office,New York,16
contract,office,London,19
temp,finance,London,7
contract,office,New York,61
contract,sales,London,31
temp,finance,New York,16
contract,sales,Paris,19
temp,sales,New York,11

这是d3脚本。提前致谢

  var data1
  var data2
   var datax
  var width = 960,
  height = 500,
  radius = Math.min(width, height) / 2;
var color = d3.scale.ordinal()
  .range(["#98abc5", "#8a89a6", "#7b6888", "#6b486b", "#a05d56", "#d0743c", "#ff8c00"]);

var arc = d3.svg.arc()
  .outerRadius(radius - 10)
  .innerRadius(radius - 70);

var pie = d3.layout.pie()
  .sort(null)
  .value(function(d) {
    return d.values;
  });

var svg = d3.select("body").append("svg")
  .attr("width", width)
  .attr("height", height)
  .append("g")
  .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
   svg.style("cursor","pointer")

d3.csv("data4.csv", function(error, data) {
 datax=data
  var data1 = d3.nest()
    .key(function(d) {
      return d.city ;
    })
    .rollup(function(d) {
      return d3.sum(d, function(g) {
        return g.points;
      });
    }).entries(data);

   var path = svg.selectAll("path")
   .data(pie(data1))
    .enter()
  .append("path")
  .attr("class", "arc");

  path.on("click", function() {       
  data2=datax
    change(data2)
 })
 path.transition()
.duration(500)
.attr("fill", function(d, i) {
      return color(d.data.key );
   })
  .attr("d", arc)
  .each(function(d) {
    this._current = d;
  })

function arcTween(a) {
var i = d3.interpolate(this._current, a);
this._current = i(0);
return function(t) {
    return arc(i(t));
 };
}
 function change(data) {
 data = data.filter(function(d) { return d.city == "New York"; });
 var data = d3.nest()
    .key(function(d) {
      return d.dept;
    })
    .rollup(function(d) {
      return d3.sum(d, function(g) {
        return g.points;
      });
    }).entries(data);
path.data(pie(data));
path.transition().duration(750).attrTween("d", arcTween); // redraw the arcs
}

});

1 个答案:

答案 0 :(得分:0)

一种策略是转换更新选择(.data()返回的对象),然后在同步延迟后添加输入选择(.enter()返回的对象)...

        var datax
        var data1

        var enterAntiClockwise = {
            startAngle: Math.PI * 2,
            endAngle: Math.PI * 2
        };

        var width = 960,
            height = 500,
            radius = Math.min(width, height) / 2;

        var color = d3.scale.ordinal()
            .range(["#98abc5", "#8a89a6", "#7b6888", "#6b486b", "#a05d56", "#d0743c", "#ff8c00"]);

        var arc = d3.svg.arc()
            .outerRadius(radius - 10)
            .innerRadius(radius - 70);

        var pie = d3.layout.pie()
            .sort(null)
            .value(function (d) {
                return d.values;
            });

        var svg = d3.select("body").append("svg")
            .attr("width", width)
            .attr("height", height)
            .append("g")
            .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
        svg.style("cursor", "pointer")



        d3.csv("data4.csv", function (error, data) {
            datax = data
            //data1=data
            // data = data.filter(function(d) { return d.city == "New York"; });

            var data1 = d3.nest()
                .key(function (d) {
                    return d.city;
                })
                .rollup(function (d) {
                    return d3.sum(d, function (g) {
                        return g.points;
                    });
                }).entries(data);

            var path = render(data1)

            path.on("click", function () {
                data2 = datax
                render(change(data2));
            })

            function arcTween(a) {
                var i = d3.interpolate(this._current, a);
                this._current = i(0);
                return function (t) {
                    return arc(i(t));
                };
            }

            function change(data) {
                data = data.filter(function (d) { return d.city == "New York"; });
                var newData = d3.nest()
                                .key(function (d) {
                                    return d.dept;
                                })
                                .rollup(function (d) {
                                    return d3.sum(d, function (g) {
                                        return g.points;
                                    });
                                }).entries(data);
                return newData
            }

            function render(data) {
                var path = svg.datum(data).selectAll("path").data(pie)
                path.transition().duration(750).attrTween("d", arcTween); // redraw the arcs
                path.enter()
                        .append("path")
                        .attr("class", "arc")
                        .transition().duration(0).delay(750)
                        .attr("fill", function (d, i) {
                            return color(d.data.key);
                        })
                        .attr("d", arc)
                        .each(function (d) {
                            this._current = d;
                        })
                return path;
            }

        });

(这种技术基于this example,我添加了延迟并通过将其钉在一块木头上来适应你的例子......)

最终策略可能是在布局中创建零饼图,以便它们在输入时从零转换...

var enterAntiClockwise = {
			startAngle: Math.PI * 2,
			endAngle: Math.PI * 2
		};

		var width = window.innerWidth,
			height = window.innerHeight - 20,
			radius = Math.min(width, height) / 2 * 0.8;

		var color = d3.scale.ordinal()
			.range(["#98abc5", "#8a89a6", "#7b6888", "#6b486b", "#a05d56", "#d0743c", "#ff8c00"]);

		var arc = d3.svg.arc()
			.outerRadius(radius)
			.innerRadius(radius - 20);

		var pie = d3.layout.pie()
			.sort(null)
			.value(function (d) {
				return d.values;
			});
		pie.zero = pie([{ values: 1 }, { values: 0 }])[1];  //zero pie slice

		var svg = d3.select("body").append("svg")
			.attr("width", width)
			.attr("height", height)
			.append("g")
			.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
		svg.style("cursor", "pointer")

		d3.csv("data4u.csv", function (error, data) {
			data = data || d3.csv.parse(d3.select("#csv").text())
			var data1 = d3.nest()
				    .key(function (d) {
				      return d.city;
				    })
				    .rollup(function (d) {
				      return d3.sum(d, function (g) {
				        return g.points;
				      });
				    }).entries(data),

			    path = render(data1);

			path.on("click", function () {
			  render(change(data));
			});

			function arcTween(a) {
			  var i = d3.interpolate(this._current, a);
			  this._current = i(0);
			  return function (t) {
			    return arc(i(t));
			  };
			};

			function change(data) {
				data = data.filter(function (d) { return d.city == "New York"; });
				var newData = d3.nest()
								.key(function (d) {
									return d.dept;
								})
								.rollup(function (d) {
									return d3.sum(d, function (g) {
										return g.points;
									});
								}).entries(data);
				return newData
			}
			
			function render(data) {
				var path = svg.datum(data).selectAll("path").data(pie)
				var enter = path.enter();
				enter.append("path")
					.attr("class", "arc")
					.attr("fill", function (d, i) {
						return color(d.data.key);
					})
					.attr("d", function (d, i) {
						this._current = pie.zero;
						return arc(pie.zero);
						});

				path.transition().duration(1500).attrTween("d", arcTween); // redraw the arcs

				return path;
			}

		});
#csv {
		display: none;
	}
svg { padding: 0; margin: 0;}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<div id="csv">status,dept,city,points
		temp,finance,New York,33
		contract,HR,London,12
		contract,HR,New York,11
		casual,shop,London,43
		temp,sales,New York,14
		contract,shop,Paris,51
		temp,finance,London,7
		contract,office,New York,61
		contract,shop,London,31
		temp,office,New York,16
		contract,office,London,19
		temp,finance,London,7
		contract,office,New York,61
		contract,sales,London,31
		temp,finance,New York,16
		contract,sales,Paris,19
		temp,sales,New York,11  </div>