d3.js在多个csv文件之间转换的条形图 [英] d3.js bar charts transitioning between multiple csv files

查看:194
本文介绍了d3.js在多个csv文件之间转换的条形图的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在研究一些关于冬季奥运会的Twitter数据的词汇频率。我想制作一个直方图使用d3,将可视化这些计数,并允许用户在游戏的每一天的数据集之间切换。我有一个初始的可视化效果,我对这里感到相当满意,修改自示例。然而,当点击右下角的更新按钮时,这只是在现有直方图的顶部覆盖一个新的直方图。这两个数据集都是CSV的,总共有七个,我想要能够切换。

I'm working on visualizing term frequencies for some Twitter data I've collected about the Winter Olympics. I'd like to make a histogram using d3 that will visualize these counts and allow users to toggle between datasets for each day of the games. I have an initial visualization I'm fairly happy with here, modified from this example. However, when clicking the "Update" button in the lower right corner, this simply overlays a new histogram on top of the existing one. Both datasets are CSV's, and there are seven of them total that I'd like to be able to toggle through.

我搜索了Stack Overflow的其他相关提示,发现这一点,但它似乎并没有涵盖我需要的:在d3.js中转换带有组合框变量切换的条形图。使用这个例子的主要问题是它使用相同的json数据在不同的直方图之间创建转换,而我需要在直方图之间创建转换,每个从不同的CSV数据文件中提取数据。这里是我的代码到目前为止。主要的困惑点被适当地评论。非常感谢任何指导。

I've searched Stack Overflow for other relevant tips and found this, but it doesn't seem to cover quite what I need: Transitioning bar chart with combobox variable toggle in d3.js. The main issue with using this example is that it creates transitions between different histograms using the same json data, whereas I need to create transitions between histograms that each pull data from different CSV data files. Here's my code so far. Major points of confusion are commented appropriately. Any guidance would be greatly appreciated.

<!DOCTYPE html>
<meta charset="utf-8">
<style>

body {
  font: 10px sans-serif;
}

.axis path,
.axis line {
  fill: none;
  stroke: #000;
  shape-rendering: crispEdges;
}

.bar {
  fill: #3c9dd0;
}

.bar:hover {
  fill: #ffc073;
 }

.x.axis path {
  display: none;
}

.d3-tip {
  line-height: 1;
  font-weight: bold;
  padding: 12px;
  background: rgba(0, 0, 0, 0.8);
  color: #fff;
  border-radius: 2px;
}

/* Creates a small triangle extender for the tooltip */
.d3-tip:after {
  box-sizing: border-box;
  display: inline;
  font-size: 10px;
  width: 100%;
  line-height: 1;
  color: rgba(0, 0, 0, 0.8);
  content: "\25BC";
  position: absolute;
  text-align: center;
}

/* Style northward tooltips differently */
.d3-tip.n:after {
  margin: -1px 0 0 0;
  top: 100%;
  left: 0;
}
</style>
<body>
<button onclick="update()">Update</button>

<script src="http://d3js.org/d3.v3.min.js"></script>
<script src="http://labratrevenge.com/d3-tip/javascripts/d3.tip.v0.6.3.js"></script>
<script>

var margin = {top: 40, right: 20, bottom: 30, left: 40},
    width = 960 - margin.left - margin.right,
    height = 500 - margin.top - margin.bottom;

// var formatPercent = d3.format(".0%");

var x = d3.scale.ordinal()
    .rangeRoundBands([0, width], .1);

var y = d3.scale.linear()
    .range([height, 0]);

var xAxis = d3.svg.axis()
    .scale(x)
    .orient("bottom");

var yAxis = d3.svg.axis()
    .scale(y)
    .orient("left");

var tip = d3.tip()
  .attr('class', 'd3-tip')
  .offset([-10, 0])
  .html(function(d) {
    return "<strong>Term: </strong><span style='color:orangered'>" + d.letter + "</span>"      + " <strong>Frequency:</strong> <span style='color:orangered'>" + d.frequency + "</span>";
})

var svg = d3.select("body").append("svg")
    .attr("width", width + margin.left + margin.right)
    .attr("height", height + margin.top + margin.bottom)
  .append("g")
    .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

svg.call(tip);

d3.csv("data1.csv", type, function(error, data) {
  x.domain(data.map(function(d) { return d.letter; }));
  y.domain([0, d3.max(data, function(d) { return d.frequency; })]);

  svg.append("g")
      .attr("class", "x axis")
      .attr("transform", "translate(0," + height + ")")
      .call(xAxis);

  svg.append("g")
      .attr("class", "y axis")
      .call(yAxis)
    .append("text")
      .attr("transform", "rotate(-90)")
      .attr("y", 6)
      .attr("dy", ".71em")
      .style("text-anchor", "end")
      .text("Frequency");

  svg.selectAll(".bar")
      .data(data)
    .enter().append("rect")
      .attr("class", "bar")
      .attr("x", function(d) { return x(d.letter); })
      .attr("width", x.rangeBand())
      .attr("y", function(d) { return y(d.frequency); })
      .attr("height", function(d) { return height - y(d.frequency); })
      .on('mouseover', tip.show)
      .on('mouseout', tip.hide)

});

// Test on updating data. Confusion starts here.
function update(){
  d3.csv("data2.csv", type, function(error, data) {
  x.domain(data.map(function(d) { return d.letter; }));
  y.domain([0, d3.max(data, function(d) { return d.frequency; })]);

  svg.append("g")
      .attr("class", "x axis")
      .attr("transform", "translate(0," + height + ")")
      .call(xAxis);

  svg.append("g")
      .attr("class", "y axis")
      .call(yAxis)
     .append("text")
      .attr("transform", "rotate(-90)")
      .attr("y", 6)
      .attr("dy", ".71em")
      .style("text-anchor", "end")
      .text("Frequency");

  svg.selectAll(".bar")
      .data(data)
    .enter().append("rect")
      .attr("class", "bar")
      .attr("x", function(d) { return x(d.letter); })
      .attr("width", x.rangeBand())
      .attr("y", function(d) { return y(d.frequency); })
      .attr("height", function(d) { return height - y(d.frequency); })
      .on('mouseover', tip.show)
      .on('mouseout', tip.hide)

})

// Confusion continues here. I know I need a transition, but I have
// no idea how to implement it.
d3.transition().selectAll(".bar")
      .attr('d', function(d) {return y(d.frequency);})

}

function type(d) {
  d.frequency = +d.frequency;
  return d;
}

</script>


推荐答案

代码作为最初 - 你需要考虑到这里的现有元素。代码应该看起来像这样:

In your update function, you're executing the same code as initially -- you need to take into account the existing elements here. The code should look something like this:

// update axes
svg.select(".x").call(xAxis);
svg.select(".y").call(yAxis);

// update bars
var sel = svg.selectAll(".bar").data(data);
// add new bars
sel.enter().append("rect")
  .attr("class", "bar");
// update existing (and new) bars
sel.attr("x", function(d) { return x(d.letter); })
  .attr("width", x.rangeBand())
  .attr("y", function(d) { return y(d.frequency); })
  .attr("height", function(d) { return height - y(d.frequency); })
  .on('mouseover', tip.show)
  .on('mouseout', tip.hide);
// remove bars no longer present
sel.exit().remove();

要通过转换进行更改,请添加 .transition code>之前更新属性,例如

To make the change with a transition, add .transition() before the update of the attributes, e.g.

sel.transition()
  .attr("x", function(d) { return x(d.letter); })
  // etc

这篇关于d3.js在多个csv文件之间转换的条形图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆