【问题标题】:Can a D3 line/area chart work on unordered data?D3 折线图/面积图可以处理无序数据吗?
【发布时间】:2018-05-10 15:39:04
【问题描述】:

请参考以下链接: https://bl.ocks.org/mbostock/34f08d5e11952a80609169b7917d4172

这里的数据是有序的(按顺序),如 2000 年 1 月、2000 年 2 月等,但我想让这个 d3 图表处理无序数据,如 2001 年 1 月、2000 年 2 月等。有可能吗?

【问题讨论】:

  • 先尝试一下,遇到问题再提出问题

标签: javascript angular d3.js


【解决方案1】:

简短回答:

线生成器或区域生成器(即块中的那个)将根据输入数据按其顺序生成一条线(或一个区域)。 API 说得很清楚:

d3.line():为给定的数据数组生成一行。根据此线生成器的关联曲线,给定的输入数据可能需要在传递给线生成器之前按 x 值排序。 (强调我的)

让我们在一个基本示例中看到这一点。我有一组值和年份,其中年份未排序:

var data = [{
  year: 2010,
  value: 100
}, {
  year: 2017,
  value: 70
}, {
  year: 2012,
  value: 50
}, {
  year: 2016,
  value: 10
}, {
  year: 2013,
  value: 90
}, {
  year: 2014,
  value: 20
}, {
  year: 2011,
  value: 50
}, {
  year: 2015,
  value: 40
}];

如果我按照现在的方式将数据传递给线生成器,这就是我们得到的折线图:

var svg = d3.select("svg");
var data = [{
  year: 2010,
  value: 100
}, {
  year: 2017,
  value: 70
}, {
  year: 2012,
  value: 50
}, {
  year: 2016,
  value: 10
}, {
  year: 2013,
  value: 90
}, {
  year: 2014,
  value: 20
}, {
  year: 2011,
  value: 50
}, {
  year: 2015,
  value: 40
}];

var parseTime = d3.timeParse("%Y");

data.forEach(function(d) {
  d.year = parseTime(d.year)
});

var xScale = d3.scaleTime()
  .domain(d3.extent(data, function(d) {
    return d.year
  }))
  .range([0, 300]);

var yScale = d3.scaleLinear()
  .domain(d3.extent(data, function(d) {
    return d.value
  }))
  .range([150, 0]);

var lineGenerator = d3.line()
  .x(function(d) {
    return xScale(d.year)
  })
  .y(function(d) {
    return yScale(d.value)
  })
  .curve(d3.curveMonotoneX)

svg.append("path")
  .style("fill", "none")
  .style("stroke", "teal")
  .style("stroke-width", "2px")
  .attr("d", lineGenerator(data));
<script src="https://d3js.org/d3.v4.min.js"></script>
<svg></svg>

现在是相同的代码,但对数据进行排序:

data.sort(function(a, b) {
    return d3.ascending(a.year, b.year)
});

结果如下:

var svg = d3.select("svg");
var data = [{
  year: 2010,
  value: 100
}, {
  year: 2017,
  value: 70
}, {
  year: 2012,
  value: 50
}, {
  year: 2011,
  value: 10
}, {
  year: 2013,
  value: 90
}, {
  year: 2014,
  value: 20
}, {
  year: 2016,
  value: 50
}, {
  year: 2015,
  value: 40
}];

var parseTime = d3.timeParse("%Y");

data.forEach(function(d) {
  d.year = parseTime(d.year)
});

data.sort(function(a, b) {
  return d3.ascending(a.year, b.year)
})

var xScale = d3.scaleTime()
  .domain(d3.extent(data, function(d) {
    return d.year
  }))
  .range([0, 300]);

var yScale = d3.scaleLinear()
  .domain(d3.extent(data, function(d) {
    return d.value
  }))
  .range([150, 0]);

var lineGenerator = d3.line()
  .x(function(d) {
    return xScale(d.year)
  })
  .y(function(d) {
    return yScale(d.value)
  })
  .curve(d3.curveMonotoneX)

svg.append("path")
  .style("fill", "none")
  .style("stroke", "teal")
  .style("stroke-width", "2px")
  .attr("d", lineGenerator(data));
<script src="https://d3js.org/d3.v4.min.js"></script>
<svg></svg>

【讨论】:

    猜你喜欢
    • 2014-08-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-12
    相关资源
    最近更新 更多