2016-10-18 6 views
-2

Это собирается быть жестким ...D3.js с датами только

Я пытаюсь работать с d3.js, чтобы сделать какой-то график у людей, которые работают над задачами.

Диаграмма должна выглядеть вроде как это, в конце концов: enter image description here

Это будет пример данных.

var data = [ 
    { 
     'user':'John', 
     'tasks': [ 
      { 
       name: 'Task 1', 
       start: '2016-10-01', 
       end: '2016-10-04' 
      }, 
      { 
       name: 'Task 5', 
       start: '2016-10-13', 
       end: '2016-10-14' 
      } 

     ] 
    }, 
    { 
     'user':'Mikael', 
     'tasks': [ 
      { 
       name: 'Task 2', 
       start: '2016-10-04', 
       end: '2016-10-07' 
      } 

     ] 
    }, 
    { 
     'user':'Oliver', 
     'tasks': [ 
      { 
       name: 'Task 4', 
       start: '2016-10-10', 
       end: '2016-10-12' 
      } 

     ] 
    }, 
    { 
     'user':'Artur', 
     'tasks': [ 
      { 
       name: 'Task 3', 
       start: '2016-10-09', 
       end: '2016-10-15' 
      } 

     ] 
    } 
]; 

Может кто-нибудь дать мне несколько советов о том, как добиться чего-то подобного, пожалуйста? Является ли D3.js подходящей библиотекой для этой диаграммы? Правильно ли форматируются данные или я должен выполнить некоторую логику, прежде чем перейти к D3? Как сравнить даты начала и окончания? Любая помощь очень приветствуется!

+1

Gant t диаграмма, может быть? – moooeeeep

+0

@moooeeeep thnx для ввода, я посмотрю на это! – frederikvdbe

ответ

1

Довольно прямо в D3, и ваши данные выглядят хорошо.

Посмотрите на d3.dateScale(), вам нужно что-то вроде (работает ваш домен):

var dateScale = d3.scaleTime().domain([new Date("2016-10-01"), new Date("2016-10-31")]).range([0,600]); 

, который можно использовать для создания засечек и позиционировать свою задачу <rect>, по одному для каждого задача.

Во-первых, создать SVG:

var svg = d3.select("body").append("svg").attr("width",600).attr("height",400); 

Создать <g> для каждого человека, а затем перевести его на место.

var g = svg.selectAll("g").data(data).enter().append("g").attr("transform", function(_,i) { return "translate(0," + (i * 20) + ")"; }); 

Создайте прямоугольник, затем вычислите его положение с помощью шкалы (см. Атрибут «x»). Здесь мы передаем часть данных из основных данных.

g.selectAll("rect").data(function(d) { return d.tasks; }).enter().append("rect").attr("width", function() { return 100; }).attr("height",10).attr("x", function(d) { return dateScale(new Date(d.start));}).attr("fill","red"); 

Это должно заставить вас начать. Выезд Example running code

+0

Это помогает! Я все еще играю с D3, чтобы получить что-то вроде скриншота выше. Я наткнулся на диаграммы gantt, но примеры онлайн заставляют меня делать больше, чем делать, поэтому я собираюсь начать с нуля, и это очень помогает, особенно в данном примере! – frederikvdbe

1

Я согласен с @Matthew, и это расширит его ответ с полным примером FIDDLE и небольшим прохождением.

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

var dataset = [ 
    { 
     user:'John', 
     task: 'Task 1', 
     start: '2016-10-01', 
     end: '2016-10-04' 
    },..... 

Мы начинаем определяющую временную шкалу в для оси х и шкалы полосы для пользователей по оси y.
Здесь мы используем шкалу Ординала, которая отображает дискретную область в непрерывный диапазон (полосы). Мы используем диапазон диапазона, поскольку наш домен пользователей является дискретным.

var xSc = d3.scaleTime().range([0, w]), 
    ySc = d3.scaleBand().range([h, 0]) 
    xAxis = d3.axisTop(xSc), 
    yAxis = d3.axisLeft(ySc), 
    yScDomArr = []; //This is the array for y scale domain 

Затем мы подготовить данные для весов: здесь мы собираем пользователь в yScDomArr и преобразуют «датирует строку» в Дата объекты для каждого начать и КОНЦА записи ...

dataset.forEach(function(d, i) { 
    yScDomArr.push(d.user); 
    d.start = new Date(d.start); 
    d.end = new Date(d.end); 
}); 

Теперь мы можем определить домены х и у шкалы:

xSc.domain([ 
    d3.min(dataset, function(d, i) { return d.start;}), 
    d3.max(dataset, function(d, i) { return d.end;}) 
]); 
ySc.domain(yScDomArr); //yScDomArr define our y domain values as users 

... и, наконец, мы можем сделать <rect> и <text> для каждой записи данных (здесь я группа каждого прямоугольника и текст пара в элементе g, это делает ваш код чистым и полезным, если вам нужны прослушиватели событий для показа всплывающей подсказки):

+0

Для вас это помогает, некоторые практические примеры для моего дела, только то, что мне нужно! – frederikvdbe

+0

Кстати, зачем выкачать массив? – frederikvdbe

+0

Просто для упрощения примера, но ваш исходный набор данных тоже хорош, ему просто нужно немного больше работы, потому что каждая запись может иметь несколько задач (я сгладил ее только для этого, поэтому у меня есть одна запись для одной задачи) , – Daviz

Смежные вопросы