javascript - 加载时 D3 中的转换

标签 javascript csv d3.js transition

我刚刚开始使用 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 = [];

一旦数据在“type”函数(或 while)中被解析,剩下的步骤就会发生。在传递 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]};
}

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

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

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

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

为此,首先使用现有代码创建图表,但传递空数据:

  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 数据)创建鼠标悬停事件。看起来像这样:

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 事件。希望这对你有用。可能需要一些技巧才能让它发挥作用;重要的是记住如何传递空数据。让它在我这边工作就成功了一半。

关于javascript - 加载时 D3 中的转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29978957/

相关文章:

d3.js - 在 D3.js v4 中使用轴过渡包裹长标签

javascript - 我需要应用的正确过渡结束(或动画结束)是什么?

python - 如何使用Python循环删除包含特定单词的行?

d3.js - 用于可视化和图表的 D3.js 与 zingChart 库的比较

python - BigQuery : Load from CSV, 跳过列

PHP和SQL带来不同的结果

javascript - 如何从 d3 列表中删除所选项目

javascript - 在JavaScript中,绑定(bind)参数必须在匿名函数参数中吗?

javascript - Ember Web 应用程序 - 显示 JSON 数据时出现问题 - 开放天气 map API

javascript - 不再使用 jQuery 悬停时隐藏