d3 JS上的简单条形图

时间:2017-05-18 12:59:59

标签: d3.js

我是这个库的新手,我不明白为什么矩形条具有负值。我正在使用带有jsdom的d3-node(d3 v4)来从服务器渲染svg。

这就是我的尝试:

var data = [
{
  "name" : "Nom Prénom",
  "value1" : 40,
  "value2" : 100,
  "value3" : 10,
  "total" : 150 //a changer
}
];

var margin = {top: 20, right: 160, bottom: 35, left: 30};

var width = 960 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;


 var svg = this.d3n
        .createSVG(GRAPH_WIDTH - MARGINS.left - MARGINS.right - LEGEND_PANEL.width, GRAPH_HEIGHT - MARGINS.top - MARGINS.bottom)
        .append('g');


var stack = d3.stack().keys(["value1","value2","value3"]).order(d3.stackOrderNone).offset(d3.stackOffsetNone);

 var dataSet = stack(data);

  //set x, y and colors

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

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

  var colors = ["b33040", "#d25c4d", "#f2b447", "#d9d574"];


   //define and draw axis 
  var xAxis = d3.axisBottom(x);
  var yAxis = d3.axisLeft(x).ticks(5).tickFormat(function(d){ return d;});

  svg.append("g")
  .attr("class", "y axis")
  .call(yAxis);

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



 // Create groups for each series, rects for each segment 
 var groups = svg.selectAll("g.cost")
  .data(dataSet)
  .enter().append("g")
  .attr("class", "cost")
  .style("fill", function(d, i) { return colors[i]; });

var rect = groups.selectAll("rect")
.data(function(d) { return d; })
.enter()
.append("rect")
.attr("x", function(d) { 
  return x(d[0]);
 })
.attr("y", function(d) { return y(d[0] + d[1]); })
.attr("height", function(d) { return y(d[0]); })
.attr("width", x.bandwidth())
.on("mouseover", function() { tooltip.style("display", null); })
.on("mouseout", function() { tooltip.style("display", "none"); })
.on("mousemove", function(d) {
  var xPosition = d3.mouse(this)[0] - 15;
  var yPosition = d3.mouse(this)[1] - 25;
  tooltip.attr("transform", "translate(" + xPosition + "," + yPosition + ")");
  tooltip.select("text").text(d.y);
});

svg看起来像这样

<svg xmlns="http://www.w3.org/2000/svg" width="360" height="250"><g><g class="y axis" fill="none" font-size="10" font-family="sans-serif" text-anchor="end"><path class="domain" stroke="#000" d="M-6,0.5H0.5V770.5H-6"></path></g><g class="x axis" transform="translate(0,445)" fill="none" font-size="10" font-family="sans-serif" text-anchor="middle"><path class="domain" stroke="#000" d="M0.5,6V0.5H770.5V6"></path></g><g class="cost" style="fill: b33040;"><rect y="-17355" height="445" width="770"></rect></g><g class="cost" style="fill: #d25c4d;"><rect y="-79655" height="-17355" width="770"></rect></g><g class="cost" style="fill: #f2b447;"><rect y="-128605" height="-61855" width="770"></rect></g></g></svg>

有点难以看到一些v4教程,似乎v3和v4之间有很多变化。你能解释一下这是错误的吗?

非常感谢

1 个答案:

答案 0 :(得分:0)

首先,看起来高度和宽度存在一些问题:

var width = 960 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;

给我们width = 770height = 445。但

.createSVG(GRAPH_WIDTH - MARGINS.left - MARGINS.right - LEGEND_PANEL.width, GRAPH_HEIGHT - MARGINS.top - MARGINS.bottom)

<svg width="360" height="250">结束。

然后,由于您的height声明中缺少域名部分,您收到了否定yy.scaleLinear

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

应该是这样的:

 var y = d3.scaleLinear()
        .domain([0, 150])
        .range([height, 0])

D3 scaleLinear()返回一个函数,它将数据维度中的每个点(在本例中为[0,150],其中0和150分钟以及数据中的最大可能值)转换为其可视坐标,即然后用于绘图。即它映射[0,150] - &gt; [445,0]。

为了更好地理解,我建议阅读official ds-scale docs。第一段中还提到了三个教程。

即使您找到了v3教程,也许值得一读,但这些想法保持不变,只需保持the changelog page打开即可验证如何在v4中编写相同的代码。最大的教程集合列在here