В предыдущей части этой серии мы увидели, как приступить к созданию многострочного графика с использованием библиотеки JavaScript D3.js. В этом учебном пособии мы выведем его на следующий уровень, заставив многострочную диаграмму динамически реагировать на данные, и добавим еще несколько функций в процессе обучения.
Начиная
Давайте начнем с клонирования первой части урока от GitHub .
1
|
git clone https://github.com/jay3dec/MultiLineChart_D3.git
|
Перейдите к MultiLineChart_D3
и просмотрите index.html
, и у вас должен быть многострочный график, основанный на данных примера.
Установка домена динамически
В предыдущем уроке , когда мы создавали xScale
и yScale
используя Range
и Domain
, мы жестко запрограммировали минимум и максимум для домена. Чтобы сделать наш график более гибким, нам нужно динамически считывать минимальные и максимальные значения для домена из источника данных.
D3.js предоставляет методы d3.min
и d3.max
для получения минимального и максимального значений из массива соответственно. Мы будем использовать эти функции, чтобы получить минимальные и максимальные значения для домена.
Мы можем получить минимальное значение из массива, как показано:
1
2
3
|
d3.min(data, function(d) {
return d.value;
})
|
Аналогично, чтобы получить максимальное значение:
1
2
3
|
d3.max(data, function(d) {
return d.value;
})
|
Просто замените минимальное и максимальное значения в домене xScale
как показано:
1
2
3
4
5
|
xScale = d3.scale.linear().range([MARGINS.left, WIDTH — MARGINS.right]).domain([d3.min(data, function(d) {
return d.year;
}), d3.max(data, function(d) {
return d.year;
})]),
|
Аналогично замените домен yScale
:
1
2
3
4
5
|
yScale = d3.scale.linear().range([HEIGHT — MARGINS.top, MARGINS.bottom]).domain([d3.min(data, function(d) {
return d.sale;
}), d3.max(data, function(d) {
return d.sale;
})]),
|
Сохраните все изменения и просмотрите index.html
. Теперь вы должны иметь график, работающий хорошо, как это было раньше. Разница лишь в том, что он подбирает максимальные и минимальные значения домена динамически.
Динамическое создание линейной диаграммы
Хранение одного объекта JSON для образца облегчит анализ данных и нанесение их на график. Поэтому объедините две части данных примера в одну строку данных JSON, как показано ниже:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
|
var data = [{
«Client»: «ABC»,
«sale»: «202»,
«year»: «2000»
}, {
«Client»: «ABC»,
«sale»: «215»,
«year»: «2002»
}, {
«Client»: «ABC»,
«sale»: «179»,
«year»: «2004»
}, {
«Client»: «ABC»,
«sale»: «199»,
«year»: «2006»
}, {
«Client»: «ABC»,
«sale»: «134»,
«year»: «2008»
}, {
«Client»: «ABC»,
«sale»: «176»,
«year»: «2010»
}, {
«Client»: «XYZ»,
«sale»: «100»,
«year»: «2000»
}, {
«Client»: «XYZ»,
«sale»: «215»,
«year»: «2002»
}, {
«Client»: «XYZ»,
«sale»: «179»,
«year»: «2004»
}, {
«Client»: «XYZ»,
«sale»: «199»,
«year»: «2006»
}, {
«Client»: «XYZ»,
«sale»: «134»,
«year»: «2008»
}, {
«Client»: «XYZ»,
«sale»: «176»,
«year»: «2013»
}];
|
Теперь мы изменим наш код, чтобы динамически масштабировать график в соответствии с примером набора данных и его значениями.
Далее мы разделим и организуем данные на основе Client
чтобы мы могли нарисовать линейный график для каждого Client
в данных. D3 предоставляет метод с именем d3.nest
который помогает упорядочить данные на основе определенного key
поля. Мы будем использовать d3.nest
для сортировки данных на основе Client
как показано ниже:
1
2
3
4
5
|
var dataGroup = d3.nest()
.key(function(d) {
return d.Client;
})
.entries(data);
|
Вот как будет выглядеть dataGroup
:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
|
[{
«key»: «ABC»,
«values»: [{
«Client»: «ABC»,
«sale»: «202»,
«year»: «2000»
}, {
«Client»: «ABC»,
«sale»: «215»,
«year»: «2002»
}, {
«Client»: «ABC»,
«sale»: «179»,
«year»: «2004»
}, {
«Client»: «ABC»,
«sale»: «199»,
«year»: «2006»
}, {
«Client»: «ABC»,
«sale»: «134»,
«year»: «2008»
}, {
«Client»: «ABC»,
«sale»: «176»,
«year»: «2010»
}]
}, {
«key»: «XYZ»,
«values»: [{
«Client»: «XYZ»,
«sale»: «100»,
«year»: «2000»
}, {
«Client»: «XYZ»,
«sale»: «215»,
«year»: «2002»
}, {
«Client»: «XYZ»,
«sale»: «179»,
«year»: «2004»
}, {
«Client»: «XYZ»,
«sale»: «199»,
«year»: «2006»
}, {
«Client»: «XYZ»,
«sale»: «134»,
«year»: «2008»
}, {
«Client»: «XYZ»,
«sale»: «176»,
«year»: «2013»
}]
}]
|
Затем удалите код пути строки svg
для создания строки, который мы жестко запрограммировали ранее.
01
02
03
04
05
06
07
08
09
10
|
vis.append(‘svg:path’)
.attr(‘d’, lineGen(data))
.attr(‘stroke’, ‘green’)
.attr(‘stroke-width’, 2)
.attr(‘fill’, ‘none’);
vis.append(‘svg:path’)
.attr(‘d’, lineGen(data2))
.attr(‘stroke’, ‘blue’)
.attr(‘stroke-width’, 2)
.attr(‘fill’, ‘none’);
|
Вместо этого мы dataGroup
группу dataGroup
и создадим линейный график для каждого Client
как показано ниже:
1
2
3
4
5
6
7
|
dataGroup.forEach(function(d, i) {
vis.append(‘svg:path’)
.attr(‘d’, lineGen(d.values))
.attr(‘stroke’, ‘blue’)
.attr(‘stroke-width’, 2)
.attr(‘fill’, ‘none’);
});
|
Сохраните изменения и попробуйте просмотреть index.html
. Вы должны увидеть многострочный график, как показано на рисунке:
Давайте также добавим несколько случайных цветов в линии графика. Чтобы добавить случайные цвета, мы будем использовать метод d3.hsl . Измените атрибут stroke
линейного графика, как показано ниже, чтобы получить случайные цвета для линий.
1
2
3
4
5
6
7
8
9
|
dataGroup.forEach(function(d, i) {
vis.append(‘svg:path’)
.attr(‘d’, lineGen(d.values))
.attr(‘stroke’, function(d, j) {
return «hsl(» + Math.random() * 360 + «,100%,50%)»;
})
.attr(‘stroke-width’, 2)
.attr(‘fill’, ‘none’);
});
|
Сохраните изменения и просмотрите index.html
. Вы должны видеть случайные цвета для линий на графике.
Добавление легенды
Далее мы добавим legends
для Clients
в пример данных. Как только легенды будут добавлены, мы добавим к легендам событие щелчка, которое переключит отображение соответствующих линейных графиков.
Во-первых, чтобы добавить легенду, нам нужно изменить margin bottom
margin top
до 50
чтобы приспособить легенды.
1
2
3
4
5
6
7
8
9
|
var vis = d3.select(«#visualisation»),
WIDTH = 1000,
HEIGHT = 500,
MARGINS = {
top: 50,
right: 20,
bottom: 50,
left: 50
},
|
dataGroup
группу dataGroup
, мы добавим легенды для соответствующих линейных графиков. Добавить легенды довольно просто. Во-первых, определите пространство легенды на основе количества клиентов или линейных графиков, которые мы будем рисовать:
1
|
lSpace = WIDTH/dataGroup.length;
|
Добавьте текст в элемент svg с координатами x и y, повторяя итерацию dataGroup
после создания строки, как показано:
1
2
3
4
5
|
vis.append(«text»)
.attr(«x», (lSpace / 2) + i * lSpace)
.attr(«y», HEIGHT)
.style(«fill», «black»)
.text(d.key);
|
Мы отрегулировали расстояние между легендами ( lSpace
) на основе количества легенд, которые мы должны показать, чтобы все легенды были одинаково удалены друг от друга. Мы разделили легенду на 2, чтобы ее центр был выровнен по пространству и чтобы она развивалась по мере продвижения вперед, поскольку мы добавляем ( i * lSpace
) к предстоящим легендам.
Сохраните все изменения и попробуйте просмотреть index.html
и вы должны увидеть легенды под осью X.
Давайте добавим немного стиля к легендам, чтобы они выглядели смелыми. Добавьте следующий CSS в index.html
:
1
2
3
4
|
.legend {
font-size: 14px;
font-weight: bold;
}
|
Добавьте legend
класса к созданной легенде.
1
2
3
4
5
6
|
vis.append(«text»)
.attr(«x», (lSpace / 2) + i * lSpace)
.attr(«y», HEIGHT)
.style(«fill», «black»)
.attr(«class», «legend»)
.text(d.key);
|
D3.js События
Теперь давайте добавим события кликов в каждую из отображаемых легенд, чтобы переключить отображение соответствующей линии на многострочном графике.
Во-первых, нам нужно добавить id
для каждого линейного графика, созданного для переключения его отображения.
1
|
.attr(‘id’, ‘line_’+d.key)
|
Вот как выглядит код создания строки:
1
2
3
4
5
6
7
8
|
vis.append(‘svg:path’)
.attr(‘d’, lineGen(d.values, xScale, yScale))
.attr(‘stroke’, function(d, j) {
return «hsl(» + Math.random() * 360 + «,100%,50%)»;
})
.attr(‘stroke-width’, 2)
.attr(‘id’, ‘line_’ + d.key)
.attr(‘fill’, ‘none’);
|
Затем, в части создания легенды, добавьте атрибут click
:
1
2
3
|
.on(‘click’, function() {
alert(d.key);
})
|
Сохраните изменения и просмотрите index.html
. Нажмите на легенды, и вы должны увидеть имена легенд в качестве предупреждений.
Далее давайте добавим код для переключения отображения строки. Нам просто нужно проверить текущее состояние отображения линейного графика и переключить непрозрачность, чтобы показать и скрыть линию соответственно.
1
2
3
4
5
6
7
8
|
.on(‘click’, function() {
var active = d.active ?
var opacity = active ?
d3.select(«#line_» + d.key).style(«opacity», opacity);
d.active = active;
})
|
Сохраните изменения и попробуйте просмотреть index.html
. Попробуйте нажать на легенды, и отображение соответствующего линейного графика должно переключиться.
Вывод
В этом уроке мы увидели, как сделать наш многострочный график динамичным. Мы также увидели, как создавать события D3.js. Для получения подробной информации о различных других методах и API D3.js ознакомьтесь с официальной документацией .
Исходный код из этого урока доступен на GitHub .
Дайте нам знать ваши мысли в комментариях ниже!