Может ли график линии / области D3 работать с неупорядоченными данными?

1

Пожалуйста, обратитесь по следующей ссылке: https://bl.ocks.org/mbostock/34f08d5e11952a80609169b7917d4172

Здесь данные упорядочены (последовательно), как jan 2000, feb 2000 и т.д., Но я хочу, чтобы этот график d3 работал на неупорядоченных данных, таких как jan 2001, feb 2000 и т.д. Возможно ли это?

  • 0
    сначала попробуйте что-нибудь, когда у вас возникнут проблемы, задайте свой вопрос
Теги:
angular
d3.js

1 ответ

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>

Ещё вопросы

Сообщество Overcoder
Наверх
Меню