Форсирование отметок X-оси графика области на основе точек данных - PullRequest
2 голосов
/ 12 марта 2019

Я использую диаграмму области D3 для построения диаграммы для данных с такой структурой:

data = [
  {
    date: "2019-02-01", 
    value: 100
  }, {
    date: "2019-03-01", 
    value: 1
  }
]

Когда я использую Пример диаграммы области D3 , они устанавливают ось X следующим образом:

const x = d3.scaleTime()
    .domain(d3.extent(data, d => Date.parse(d.date)))
    .range([margin.left, width - margin.right])
const xAxis = g => g
    .attr("transform", `translate(0,${height - margin.bottom})`)
    .call(d3.axisBottom(x).ticks(width / 80).tickSizeOuter(0));

Тем не менее, это равномерно добавляет отметки по всей оси X.Я попытался сделать что-то вроде:

const xAxis = g => g
    .attr("transform", 'translate(0,' + (height + data.length) + ')')
    .call(d3.axisBottom(x).ticks(data.length).tickSizeOuter(0));

, но затем на оси X ничего не появилось. Как заставить ось X отображать отметки только на заданных значениях date из моих данных (т.е.для приведенных выше примеров я хочу видеть только 2019-02-01 и 2019-03-01 на оси X).

Еще лучше было бы просто отобразить месяц и год этих дат (то есть 2019-02-01 будет отображаться как Feb. 2019 на графике).

1 Ответ

1 голос
/ 12 марта 2019

Вы можете указать, какие значения должны быть тиками, предоставив массив для axis.tickValues(), содержащий желаемые значения тиков. Если ваши тики должны быть значениями в вашем массиве данных, то вам нужно всего лишь перебрать ваш массив и выбрать значения. В вашем случае это может выглядеть так:

var axis = d3.axisBottom()
  .scale(x)
  .tickValues(
     data.map(function(d) { return timeParse(d.date); })
  )

Если ваша шкала является шкалой времени, то значения должны быть объектами даты, поэтому мы не можем передать отформатированные даты. Но если мы хотим указать, как будет отображаться галочка, мы также можем передать формат в axis.tickFormat, это позволит вам установить способ отображения дат. Вместе мы получаем:

var svg = d3.select("svg");

var data = data = [
  {
    date: "2019-02-01", 
    value: 100
  },
  {
    date: "2019-03-1", 
    value: 50
  },
  {
    date: "2019-05-01", 
    value: 1
  }

];

var timeParse = d3.timeParse("%Y-%m-%d");
var timeFormat = d3.timeFormat("%B %Y");

var x = d3.scaleTime()
  .domain(d3.extent(data,function(d) { return timeParse(d.date); }))
  .range([20,300]);
  
var y = d3.scaleLinear()
  .domain([0,100])
  .range([10,100]);
  
var line = d3.line()
  .x(function(d) { return x(timeParse(d.date)); })
  .y(function(d) { return y(d.value); })
  
svg.append("path")
  .datum(data)
  .attr("d", line);
  
// Axis:
var axisBottom = d3.axisBottom()
  .scale(x)
  .tickValues(data.map(function(d) {
    return timeParse(d.date); // specify which values should be ticks.
  }))
  .tickFormat(timeFormat);
  
svg.append("g")
  .attr("transform","translate(0,100)")
  .call(axisBottom);
  
  
  
svg.selectAll("text")
  .attr("text-anchor","start")
  .attr("transform","rotate(90)translate(10,-13)");
path {
  fill: none;
  stroke: black;
  stroke-width: 1px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<svg width="400" height="400"></svg>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...