D3.js - 如何通过Javascript更新数据集?

时间:2016-06-04 13:12:30

标签: javascript jquery d3.js

我有一个包含11个不同变量的数据集(csv文件有12列)。我希望能够为我的散点图选择某个列,但是我遇到了一些困难。请耐心等待,因为JavaScript不是我的强项(显然)。这就是我的尝试:

<div class="variables" id="fixedacidity" onclick="drawPlot('fixedacidity');">
    <h1>fixed acidity</h1>
</div>
<div class="variables" id="volatileacidity" onclick="drawPlot('volatileacidity');">
    <h1>volatile acidity</h1>
</div>
<div class="variables" id="citricacid" onclick="drawPlot('citricacid');">
    <h1>citric acid</h1>
</div>
<div class="variables" id="residualsugar" onclick="drawPlot('residualsugar');">
    <h1>residual sugar</h1>
</div>
etc ... 

我创建了一个调用drawPlot函数的简单菜单,但是我无法正确地尝试传递变量。

相关的d3 / javascript:

function drawPlot(selectedVar){

$(".visarea").html("");

var wineVar = selectedVar;

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

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

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

var color = d3.scale.category10();

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

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


var chart1 = d3.select(".visarea").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 + ")");

d3.csv("red.csv", function(error, data) {
  if (error) throw error;

  data.forEach(function(d) {
    d.wineVar = +d.wineVar;
    d.quality = +d.quality;
  });

  x.domain(d3.extent(data, function(d) { return d.wineVar; })).nice();
  y.domain([0,10]).nice();

  chart1.append("g")
      .attr("class", "x axis")
      .attr("transform", "translate(0," + height + ")")
      .call(xAxis)
    .append("text")
      .attr("class", "label")
      .attr("x", width)
      .attr("y", -6)
      .style("text-anchor", "end")
      .text(wineVar);

  chart1.append("g")
      .attr("class", "y axis")
      .call(yAxis)
    .append("text")
      .attr("class", "label")
      .attr("transform", "rotate(-90)")
      .attr("y", 6)
      .attr("dy", ".71em")
      .style("text-anchor", "end")
      .text("Rated Quality")

  chart1.selectAll(".red.dot")
      .data(data)
    .enter().append("circle")
      .attr("class", "red dot")
      .attr("r", 3)
      .attr("cx", function(d) { return x(d.wineVar); })
      .attr("cy", function(d) { return y(d.quality); })
      .style("fill", "red");

});
}

虽然变量被传递给函数,d.wineVar,如预期的那样,不会返回所需的值,因此图表不会绘制正确的值。任何人都可以推荐一个解决方法吗?这看起来很简单,但我花了好几个小时都试图解决这个问题。

red.csv示例:

fixedacidity,volatileacidity,citricacid,residualsugar,chlorides,freesulfurdioxide,totalsulfurdioxide,density,pH,sulphates,alcohol,quality
7.4,0.7,0,1.9,0.076,11,34,0.9978,3.51,0.56,9.4,5
7.8,0.88,0,2.6,0.098,25,67,0.9968,3.2,0.68,9.8,5
7.8,0.76,0.04,2.3,0.092,15,54,0.997,3.26,0.65,9.8,5

Image of what I'm trying to accomplish. The first dataset, fixedacidity, gets drawn up fine. I'm having difficulties trying to get the menu to correctly show its respective dataset. "Rated Quality" will always be the data for the Y-axis. 我正在努力实现的形象。第一个数据集,fixedacidity,得到了很好的绘制。我在尝试让菜单正确显示其各自的数据集时遇到困难。 “额定质量”始终是Y轴的数据。

2 个答案:

答案 0 :(得分:2)

你有错误的变量引用,这里:

  data.forEach(function(d) {
    d.wineVar = +d.wineVar;        //  <---------Here
    d.quality = +d.quality;
  });

改变:

  data.forEach(function(d) {
    d.wineVar = +d[wineVar];       // <----------Here
    d.quality = +d.quality;
  });

答案 1 :(得分:1)

klaujesi指出了有关数据提取的明显问题。但是您的代码存在更多问题。

我想说你需要调整你的方法来适应d3.js的工作方式。目前,您将在每次调用函数时添加一个新的svg,这是由代码中的这一行引起的:d3.select(".visarea").append("svg")

我通常会在一个函数中包含一些初始化代码,这会创建svg并将所有内容设置为静态。然后有一个更新功能,它将处理输入变化以显示不同的数据,使用不同的比例等。

关于d3.js的好处是你可以通过.enter()非常轻松地控制新引入的数据会发生什么,并通过.exit()删除数据。