Как сделать диаграмму серии с датой по оси X в d c. js - PullRequest
1 голос
/ 16 апреля 2020

Я использую d c. js V3.2.1 и перекрестный фильтр. Я пытаюсь создать диаграмму серии с измерением даты и сталкиваюсь с проблемой создания диаграммы с датой по оси X и счетчиком по оси Y. В моих выходных данных ось X не отображается как дата.

Мне нужны две группы как Администратор и Агент в столбце агента моих данных и с двумя строками в последовательном графике - одна строка в качестве группы администраторов, а другая линия в качестве линии агента на графике.

Мои образцы данных:

create_time,agent 
2017-01-01,Admin 
2017-01-02,Admin 
2017-01-02,Admin    
2017-01-02,Admin 
2017-01-01,Agent 
2017-01-02,Agent 
2017-01-03,Admin    
2017-01-03,Admin 
2017-01-03,Admin 
2017-01-03,Agent 
2017-02-01,Admin    
2017-02-01,Agent 
2017-02-01,Agent 
2017-02-02,Admin 
2017-02-02,Admin    
2017-02-03,Agent 
2017-02-03,Agent 
2017-03-01,Admin 
2017-03-01,Admin    
2017-03-01,Admin 
2017-03-01,Admin 
2017-03-01,Agent 
2017-03-01,Agent    
2017-03-01,Agent 
2017-04-01,Admin 
2017-04-01,Admin 
2017-04-01,Admin    
2017-04-01,Admin 
2017-04-01,Agent 
2017-04-01,Agent

Это мой код:

<div id="test"></div>

<script src="./static/lib/js/jquery.min.js"></script>
  <script src="./static/lib/js/bootstrap.min.js"></script>
  <script src="./static/lib/js/crossfilter.js"></script>
  <script src="./static/lib/js/d3.js"></script>
  <script src="./static/lib/js/dc.js"></script>
  <script src="./static/lib/js/queue.js"></script>

<script type="text/javascript">

    var chart = new dc.seriesChart("#test");

    d3.csv("static/data/agent.csv").then(function(agent) {
        var mycrossfilter = crossfilter(agent);
        var all = mycrossfilter.groupAll();

        agent.forEach(function(x) {
               if(x.gender == 'Admin') {
                  x.newdata = 1;
               } else {
                  x.newdata = 2;
               }
            });

           var minDate = d3.min(agent, function(d){ return d.create_time; });
           var maxDate = d3.max(agent, function(d){ return d.create_time; });

            var hwDimension = mycrossfilter.dimension(function(data) { 
               return [data.agent, data.create_time];
            });
            var hwGroup = hwDimension.group().reduceCount();

        chart
         .width(800)
         .height(600)
         .chart(function(c) { 
            return dc.lineChart(c).interpolate('cardinal').evadeDomainFilter(true);
         })
         .x(d3.scaleTime().domain([minDate,maxDate]))
         .elasticY(true)
         .brushOn(false)
         .xAxisLabel("Height")
         .yAxisLabel("Count")
         .dimension(hwDimension)
         .group(hwGroup)
         .seriesAccessor(function(d) { return d.key[0];})
         .keyAccessor(function(d) { return +d.key[1]; })
         .valueAccessor(function(d) { return +d.value; })
         .legend(dc.legend().x(350).y(500).itemHeight(13).gap(5).horizontal(1)
            .legendWidth(120).itemWidth(60));

      chart.render();
    });

1 Ответ

0 голосов
/ 17 апреля 2020

Похоже, вы все делали правильно, но d3.scaleTime ожидает объекты Date, поэтому вам необходимо преобразовать данные:

    agent.forEach(function(x) {
      // ...
      x.create_time = new Date(x.create_time);
    });

Я также удалил интерполяцию кардинальной линии, потому что она не работает с эти данные (вероятно, плохая идея в первую очередь). И, похоже, после этого все сработало, даты были показаны на оси X и все.

screenshot with formatted dates

Демонстрация Fiddle .

Форматирование отметок

d c. js использует ось d3 для рисования осей.

Использование

chart.xAxis()

для получения оси X и .tickFormat () для установки формата на оси, передавая d3.timeFormat .

В приведенной выше скрипке,

chart.xAxis().tickFormat(d3.timeFormat('%Y-%m-%d'));
...