在D3.js(V4)中创建分类折线图 [英] Creating a categorical line chart in D3.js (V4)

查看:110
本文介绍了在D3.js(V4)中创建分类折线图的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

相对对D3.js来说是新的,我正在想象'乘客'和'来自 busdatasimple.json 文件的'PassengersOut'值。作为参考,其中一个JSON对象看起来像这样;

I'm relatively new to D3.js and I'm visualising the 'PassengersIn' & 'PassengersOut' values from my busdatasimple.json file. For reference, one of the JSON objects looks like this;

  {
    "BusNo": "1",
    "Date": "21 November 2016",
    "Time": "09:10:34 AM",
    "Destination": "Pier 50",
    "Longitude": "-122.383262",
    "Latitude": "37.773644",
    "PassengersIn": "8",
    "PassengersOut": "1"
  }

我现在正试图绘制PassengersIn& amp;乘客在线图上使用两条线对着目的地。我正在与轴挣扎,因为x只有2个刻度,而y没有缩放到我的数据。如下所示;

I'm now trying to graph the PassengersIn & PassengersOut against the Destination using two lines on a line graph. I'm struggling with the axes as the x has only 2 ticks and the y is not scaling to my data. As seen below;

我的代码如下。我删除了无关的Google Maps和jQuery。

My code is as follows. I've removed the irrelevant Google Maps and jQuery.

//Setting The Dimensions Of The Canvas
var margin = {top: 20, right: 20, bottom: 70, left: 40},
    width = 650 - margin.left - margin.right,
    height = 350 - margin.top - margin.bottom;

//Setting X & Y Ranges
var x = d3.scaleOrdinal().range([0, width]);
var y = d3.scaleLinear().range([height, 0]);

//Define The Axes
var xAxis = d3.axisBottom().scale(x);
var yAxis = d3.axisLeft().scale(y).ticks(10);

//Add The SVG Element
var svg = d3.select("body").append("svg")
    .attr("width", width + margin.left + margin.right + 50)
    .attr("height", height + margin.top + margin.bottom + 200)
    .attr("class", "svg")
    .append("g")
    .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

//Load Data From JSON
d3.json("busdatasimple.json", function(error, data) {
  //Functions for Y-Axis Grid Lines
  function yGridLines() {
    return d3.axisLeft().scale(y).ticks(5);
  }

  //Adding the Y-Axis Grid Lines
  svg.append("g")
      .attr("class", "grid-lines")
      .call(yGridLines().tickSize(-width, 0, 0).tickFormat(""));

  //Adding Y-Axis
  svg.append("g")
      .attr("class", "y axis").call(yAxis)
    .append("text")
      .attr("transform", "rotate(-90)")
      .attr("y", 5)
      .attr("dy", ".71em")
      .style("text-anchor", "end")
      .text("Passengers In");
  
   //Adding X-Axis (Added to the end of the code so the label show over bottom bars)
   svg.append("g")
     .attr("class", "x axis")
     .attr("transform", "translate(0," + height + ")")
     .call(xAxis)
   .selectAll("text")
     .style("text-anchor", "middle")
     //.attr("dx", "-.8em")
     .attr("dy", "-.55em")
     .attr("transform", "translate(-5, 15)")
     .attr("font-family", "Arial")
     .attr("font-weight", "bold")
     .attr("font-size", "1.1em");

    x.domain(data.map(function(d){return d.Destination;}));
    y.domain([d3.min(data, function(d){return d.PassengersIn;}), d3.max(data, function(d)     {return d.PassengersIn;})]);

    var line = d3.line()
      .x(function(d){return x(d.Destination);})
      .y(function(d){return y(d.PassengersIn);});

    svg.append("path").datum(data)
      .attr("class", "line")
      .attr("d", function(d){return d.PassengersIn;})
      .attr("stroke", "green")
      .attr("stroke-width", 2);
});

我设法找到一些使用分类序数量表的例子,然而,他们都使用了d3.js的v3并且在无数次阅读v4 API之后我仍然无法弄明白。

I've managed to find a few examples that use a categorical ordinal scale, however, they are all using v3 of d3.js and after reading through the v4 API countless times I still can't figure it out.

推荐答案

你想要一个分类尺度,这是正确的,但你不需要序数尺度这里。

You want a categorical scale, that's right, but you don't want an ordinal scale here.

从v3到v4有很多变化。在v3中,您可以将.rangeBands,.rangeRoundBands,.rangePoints和.rangeRoundPoints设置为您的序数比例,因此可以接受连续范围。不再是:在D3 v4中你有全新的 scaleBand scalePoint

There was a lot of changes from v3 to v4. In v3, you could set .rangeBands, .rangeRoundBands, .rangePoints and .rangeRoundPoints to your ordinal scale, which therefore could accept an continuous range. Not anymore: in D3 v4 you have the brand new scaleBand and scalePoint.

在v4中,在常规序数范围内( scaleOrdinal ):

In v4, in a regular ordinal scale (which is scaleOrdinal):


如果指定了范围,则将序数范围的范围设置为指定的值数组。域中的第一个元素将映射到范围中的第一个元素,第二个域值将映射到第二个范围值,依此类推。如果范围中的更少元素比域中的更少,则比例将重用范围开头的值。 (强调我的)

If range is specified, sets the range of the ordinal scale to the specified array of values. The first element in the domain will be mapped to the first element in range, the second domain value to the second range value, and so on. If there are fewer elements in the range than in the domain, the scale will reuse values from the start of the range. (emphases mine)

因此,在 scaleOrdinal 中,范围需要具有相同的域长度(元素数量)。

So, in an scaleOrdinal, the range need to have the same length (number of elements) of the domain.

话虽这么说,你想要一个点量表( scalePoint )这里。带尺度和点尺......

That being said, you want a point scale (scalePoint) here. Band scales and point scales...


...除了输出范围连续之外,它们与序数尺度相似和数字。 (强调我的)

...are like ordinal scales except the output range is continuous and numeric. (emphasis mine)

检查这个片段,查看控制台并比较两个比例:

Check this snippet, look at the console and compare the two scales:

var destinations = ["foo", "bar", "baz", "foobar", "foobaz"];

var scale1 = d3.scaleOrdinal()
	.range([0, 100])
	.domain(destinations);
	
var scale2 = d3.scalePoint()
	.range([0, 100])
	.domain(destinations);
	
destinations.forEach(d=>{
console.log(d + " in an ordinal scale: " + scale1(d) + " / in a point scale: " + scale2(d))
})

<script src="https://d3js.org/d3.v4.min.js"></script>

关于你的y轴问题:

在调用轴之前设置y比例的域。所以,而不是这个:

Set the domain of the y scale before calling the axis. So, instead of this:

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

y.domain([d3.min(data, function(d){
    return d.PassengersIn;
}), d3.max(data, function(d){
    return d.PassengersIn;
})]);

更改订单:

y.domain([d3.min(data, function(d){
    return d.PassengersIn;
}), d3.max(data, function(d){
    return d.PassengersIn;
})]);//set the domain first!

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

这篇关于在D3.js(V4)中创建分类折线图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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