我只是从D3开始,我正在尝试创建一个简单的条形图,该条形图在加载时会转换。我尝试在代码的每个选择和属性更改之间添加.transition(),这会使整个视觉效果消失。这或多或少是我的全部代码:

<style>
.chart rect {
  fill: steelblue;
}

.chart text {
  fill: white;
  font: 10px sans-serif;
  text-anchor: end;
}

</style>
<svg class="chart"></svg>
<script src="js/d3.min.js"></script>
<script>

var width = 1000,
barHeight = 20;

var x = d3.scale.linear()
.range([0, width]);

var chart = d3.select(".chart")
.attr("width", width);

d3.csv("data2.csv", type, function(error, data) {
  x.domain([0, d3.max(data, function(d) { return d.value; })]);

  chart.attr("height", barHeight * data.length);

  var bar = chart.selectAll("g")
      .data(data)
    .enter().append("g")
      .attr("transform", function(d, i) { return "translate(0," + i * barHeight + ")"; });

  bar.append("rect")
      .attr("width", function(d) { return x(d.value); })
      .attr("height", barHeight - 1);

  bar.append("text")
      .attr("x", function(d) { return x(d.value) - 3; })
  .attr("y", barHeight / 2)
  .attr("dy", ".35em")
  .text(function(d) { return d.value; });
});

function type(d) {
  d.value = +d.value; // coerce to number
  return d;
}

</script>


不确定我的代码是否存在更基本的问题,但是我阅读的每个资源都使添加.transition()看起来很容易,但我没有发现这种情况。任何答案表示赞赏。

最佳答案

我可能有解决方案。这可能是一种解决方法。我对此也很陌生,这只是对我有用的解决方案。

我发现的解决方案是拥有两组数据。您需要做的是创建一个空白数据集-具有相同长度的值,但所有值都设置为0的数据-首先呈现。因此,创建一个全局变量,如下所示:

//create before passing data
var emptyVar  = 0;


D3将数据作为对象数组返回。因此,您还需要创建一个空数组:

var emptyData = [];


剩下的步骤将在“类型”函数中(或同时)解析完数据后执行。在传递csv的代码中,您必须使用空变量填充空数据集。这样做,您将创建一个for()语句,并将导入的数据作为emptyData的长度传递。这样,您的emptyData将填充与导入数据中的变量一样多的emptyVar。您可以这样操作:

d3.csv("data2.csv", type, function(error, data) {
x.domain([0, d3.max(data, function(d) { return d.value; })]);

for(var i = 0;i<data.length;i++){
  emptyData[i] = {value:empty[i]};
}


不幸的是,这将返回未定义的变量,因此,如果您控制台记录emptyData [0] .value(请注意:数据是对象的数组,而不仅仅是数组。这就是csv的解释方式,因此这就是我们构建代码的方式)空数组),您将获得“未定义”。为了解决这个问题,您必须传递一个if语句,该语句将所有“未定义”都转换为0。该代码如下所示:

for(i = 0;i<emptyData.length;i++){
  if(emptyData[i].value === undefined){
    emptyData[i].value = 0;
  }
}


如果按顺序完成,您将拥有一个EmptyData集(其中所有值均为0),与初始导入的csv数据集一样长。

现在您拥有一组空数据,您可以告诉D3根据空白数据创建条形图。要伪造此问题的“ onload”部分,您可以通过在文档的整个主体上设置on“ mouseover”事件,来设置第二个实际数据以加载正确的图表。从这个意义上讲,从技术上讲没有onload设置,但是就像图表随着页面加载而转变一样会出现。

为此,首先使用现有代码创建图表,然后传递emptyData:

  chart.attr("height", barHeight * data.length);

  var bar = chart.selectAll("g")
      .data(emptyData)
    .enter().append("g")
      .attr("transform", function(d, i) { return "translate(0," + i * barHeight + ")"; });

  bar.append("rect")
      .attr("width", function(d) { return x(d.value); })
      .attr("height", barHeight - 1);

  bar.append("text")
      .attr("x", function(d) { return x(d.value) - 3; })
  .attr("y", barHeight / 2)
  .attr("dy", ".35em")
  .text(function(d) { return d.value; });


这将根据您的空数据创建一个图表。现在,使用传递的实际数据(csv数据)创建mouseover事件。看起来像这样:

d3.select("body")
  .on("mouseover",function (){

chart.selectAll(".bar")
    .data(data)
    .transition()
    .duration(500)
    .ease("linear")
//the attributes you'd like to change are listed below
    .attr("fill","#5489c7")
    .attr("width", function(d) { return x(d.value); })
    .attr("height", barHeight - 1);
//change the text attributes as well within here
        ...
//close off the function when you're finished
});


应该是这样。这并不是您所要求的onload事件,但它应该伪造得足以使它看起来像一个onload事件。希望对您有用。要使其正常工作,可能需要一些技巧。重要的是要记住如何传递空数据。使它在我端发挥作用仅是成功的一半。

10-06 08:21