Форматирование минут и секунд на оси D3 - PullRequest
0 голосов
/ 05 июня 2018

Я работаю над проектом D3, где у меня есть время (минуты и секунды) в формате JSON, которое выглядит следующим образом:

"Time": "36:50"

Как я могу отобразить время в этом формате на оси YГрафик D3?Должен ли я использовать d3.scaleTime или d3.scaleLinear для оси?Как сделать галочки, которые бы отображали время в формате minute:second, как в формате JSON?

РЕДАКТИРОВАТЬ:
Это то, что у меня естьпока что для шкал / оси:

  //Format data for X Axis
      var yearFormat = "%Y";
      var parsedYear = years.map(function(d) {
        return d3.timeParse(yearFormat)(d)
      });


      var x = d3.scaleTime()
                .range([0, width])
                .domain(d3.extent(parsedYear));


      // Format data for Y Axis
      var specifier = "%M:%S";
      var parsedTime = times.map(function(d) {
        return d3.timeParse(specifier)(d)
      })

      var y = d3.scaleTime()
                .range([height, 0])
                .domain(d3.extent(parsedTime));

      // X Axis
      g.append("g")
        .attr("transform", "translate(0," + height + ")")
        .call(d3.axisBottom(x))
        .attr("stroke-width", 2)
        .style("font-size", ".6em")


      // Y Axis
      g.append("g")
        .call(d3.axisLeft(y))
        .attr("stroke-width", 2)
        .style("font-size", ".6em")
        .tickValues(parsedTime)
        .tickFormat(function(d){
           return d3.timeFormat(specifier)(d)
         });

1 Ответ

0 голосов
/ 05 июня 2018

Любой возможный ответ на ваш вопрос опасно основан на мнении , потому что он зависит именно от того, что вы хотите: хотите ли вы считать время временем ?Или вы хотите рассматривать время как отдельные, отдельные события?

Здесь на самом деле есть три варианта:

  1. Использование порядковой шкалы (диапазон, точка ...): в этом случае каждая запись данных будет просто категориальной переменной.Расстояние между отметками на оси будет одинаковым.
  2. Использование линейной шкалы : это позволяет использовать разные расстояния для отметок на оси.Тем не менее, значения не будут временем, вам придется создать математику, чтобы установить значения (самый простой из них - вычисление количества секунд).
  3. Использование шкала времени : это имеет преимущество, заключающееся в том, что вы будете рассматривать время как время .Однако основным недостатком является именно предыдущее утверждение: время - сложный зверь, у вас будут високосные годы, летнее время, различия в часовых поясах и т. Д. *

Поскольку линейная шкала довольно проста в создании (а порядковая шкала еще более проста), вот ответ, показывающий, как это сделать с шкалой времени.

Предположим, у вас есть этот массив данных:

var data = ["12:32", "21:05", "24:56", "36:30", "45:14", "71:11"];

Первым шагом является разбор дат:

var specifier = "%M:%S";
var parsedData = data.map(function(d) {
  return d3.timeParse(specifier)(d)
});

И затем создание масштаба:

var scale = d3.scaleTime()
  .domain(d3.extent(parsedData));

Чтобы это работало, нам нужно установитьtickValues с использованием нашего разобранного массива данных и форматирования тиков для минут и секунд:

var axis = d3.axisBottom(scale)
    .tickValues(parsedData)
    .tickFormat(function(d){
        return d3.timeFormat(specifier)(d)
    });

Вот результат:

var data = ["12:32", "21:05", "24:56", "36:30", "45:14", "71:11"];
var specifier = "%M:%S";
var svg = d3.select("svg");
var parsedData = data.map(function(d) {
  return d3.timeParse(specifier)(d)
});
var scale = d3.scaleTime()
  .domain(d3.extent(parsedData))
  .range([30, 470]);
var axis = d3.axisBottom(scale)
  .tickValues(parsedData)
  .tickFormat(function(d) {
    return d3.timeFormat(specifier)(d)
  });
var gX = svg.append("g")
  .attr("transform", "translate(0,50)")
  .call(axis)
<script src="https://d3js.org/d3.v5.min.js"></script>
<svg width="500" height="100"></svg>

Как видите, галочки здесь правильно расставлены.Но у нас есть проблема: эти отметки являются действительными датами (если вы проверите код, вы увидите, что это 1900 год).Из-за этого последний тик, который должен составлять 71 минуту и ​​11 секунд, отображается как 11:11, потому что это одиннадцатая минута следующего следующего часа.

Простые решенияссылается на исходный массив строк:

.tickFormat(function(d,i) {
    return data[i]
});

И вот результат:

var data = ["12:32", "21:05", "24:56", "36:30", "45:14", "71:11"];
var specifier = "%M:%S";
var svg = d3.select("svg");
var parsedData = data.map(function(d) {
  return d3.timeParse(specifier)(d)
});
var scale = d3.scaleTime()
  .domain(d3.extent(parsedData))
  .range([30, 470]);
var axis = d3.axisBottom(scale)
  .tickValues(parsedData)
  .tickFormat(function(d, i) {
    return data[i]
  });
var gX = svg.append("g")
  .attr("transform", "translate(0,50)")
  .call(axis)
<script src="https://d3js.org/d3.v5.min.js"></script>
<svg width="500" height="100"></svg>
...