Статьи

Визуализация данных с помощью Flot

Есть много учебников о том, как создавать CSS-гистограммы. Но иногда гистограммы недостаточно. Что если наши треки данных меняются со временем и линейный график более уместен? Или, может быть, мы не удовлетворены только гистограммой. Войдите в Flot, плагин ajQuery, который позволяет нам легко создавать хорошо выглядящие графики.




В мире, ориентированном на данные, нам часто приходится отображать большие объемы данных в Интернете. Как правило, мы показываем таблицу значений с заголовками, и если мы действительно хотим получить фантазию, мы будем использовать изображение графика. Люди любят картинки. Мне нравятся картинки. Почему? Потому что гораздо проще интерпретировать данные, когда они находятся в визуальной форме. Тем не менее, создание графического изображения и обновление его новыми данными может быть проблемой. В этом уроке мы будем использовать плагин jQuery под названием Flot для создания графиков на лету.

Для начала нам нужны некоторые данные. В этом уроке мы будем использовать некоторые данные по ВВП для нескольких разных стран, которые я нашел в Википедии. К сожалению, данные относятся только к 2003 году, но поскольку это не урок по экономике, этого будет достаточно. Давайте поместим данные в простую таблицу и добавим несколько строк для их описания.

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
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
<!DOCTYPE html PUBLIC «-//W3C//DTD XHTML 1.0 Transitional//EN» «http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd»>
<html xmlns=»http://www.w3.org/1999/xhtml»>
<head>
<meta http-equiv=»Content-Type» content=»text/html; charset=utf-8″ />
<title>Flot Tutorial</title>
 
</head>
 
<body>
 
<div id=»plotarea»>
    <table>
        <caption>GDP, based on exchange rates, over time.
        <tr>
            <td></td>
            <th scope=»col»>2003</th>
            <th scope=»col»>2002</th>
            <th scope=»col»>2001</th>
            <th scope=»col»>2000</th>
            <th scope=»col»>1999</th>
            <th scope=»col»>1998</th>
        </tr>
        <tr>
            <th scope=»row»>USA</th>
            <td>10,882</td>
            <td>10,383</td>
            <td>10,020</td>
            <td>9,762</td>
            <td>9,213</td>
            <td>8,720</td>
        </tr>
        <tr>
            <th scope=»row»>EU</th>
            <td>10,970</td>
            <td>9,040</td>
            <td>8,303</td>
            <td>8,234</td>
            <td>8,901</td>
            <td>8,889</td>
        </tr>
        <tr>
            <th scope=»row»>UK</th>
            <td>1,765</td>
            <td>1,564</td>
            <td>1,430</td>
            <td>1,438</td>
            <td>1,460</td>
            <td>1,423</td>
        </tr>
        <tr>
            <th scope=»row»>China</th>
            <td>1,575</td>
            <td>1,434</td>
            <td>1,345</td>
            <td>1,252</td>
            <td>1,158</td>
            <td>1,148</td>
        </tr>
        <tr>
            <th scope=»row»>India</th>
            <td>599</td>
            <td>510</td>
            <td>479</td>
            <td>457</td>
            <td>447</td>
            <td>414</td>
        </tr>
    </table>
</div>
 
<p>GDP, based on exchange rates, over time.
 
</body>
</html>

Обратите внимание, что таблица содержится в div с идентификатором «plotarea». График, который мы создадим позже, заменит таблицу, содержащуюся в этом div. На данный момент таблица выглядит немного некрасиво, поэтому давайте добавим немного CSS, чтобы сделать ее более презентабельной.

1
2
3
4
5
6
7
8
<style type=»text/css»>
    body { font-family: Arial, Helvetica, sans-serif;
    table { border-collapse: collapse;
    td, th { border: 1px solid #222;
     
    /* Fix the legend */
    .legend td, .legend th { border: 0;
</style>

У вас должно быть что-то похожее на это.

Таблица данных

Теперь, когда у нас есть все данные в таблице, мы можем начать добавлять JavaScript, который создаст для нас график. Технически нам не нужно иметь стол, но хорошо иметь его по двум причинам:

  1. Доступность Есть много слепых веб-пользователей, и важно, чтобы все на вашем веб-сайте было удобным для чтения с экрана. Программы чтения с экрана не могут интерпретировать графики, созданные Flot.
  2. Разлагаемость Небольшое количество веб-пользователей отключают JavaScript. Хотя это очень небольшое меньшинство, добавить таблицу не так много, чтобы они также могли просматривать данные.

Связать необходимые библиотеки JavaScript. Их два, плюс еще один для поддержки IE. Нам нужно сначала связать jQuery, а затем библиотеку Flot, поскольку это зависит от jQuery. Поскольку Flot использует элемент canvas для рисования графиков, нам необходимо включить скрипт ExplorerCanvas, который эмулирует элемент canvas в IE. Пользователям Firefox, Opera и Safari это не нужно, поэтому мы будем использовать условные комментарии, чтобы убедиться, что их загружают только пользователи IE.

1
2
3
<script src=»jquery.js» language=»javascript» type=»text/javascript»></script>
<script src=»jquery.flot.pack.js» language=»javascript» type=»text/javascript»></script>
<!—[if IE]><script language=»javascript» type=»text/javascript» src=»excanvas.pack.js»></script><![endif]—>

Создать график с помощью Flot довольно просто, поскольку многие параметры имеют разумные значения по умолчанию. Это означает, что вы можете создать красивый граф с минимальными затратами труда, но также можете настроить его по своему вкусу. Чтобы создать базовый график, нам нужно указать элемент контейнера и данные, которые будут отображаться. Элемент контейнера также должен иметь указанную ширину и высоту, поэтому мы будем использовать jQuery, чтобы установить для div «plotarea» ширину 500 пикселей и высоту 250 пикселей.

1
2
3
4
5
6
7
8
<script language=»javascript» type=»text/javascript»>
$(function() {
    var plotarea = $(«#plotarea»);
    plotarea.css(«height», «250px»);
    plotarea.css(«width», «500px»);
    $.plot( plotarea , data );
});
</script>

Первый параметр — это объект jQuery элемента контейнера. Второй элемент — это трехмерный массив, где первые дочерние массивы являются наборами данных, а массивы «внуков» — это упорядоченные пары, задающие значения X и Y для декартовой плоскости. Давайте сначала представим данные по ВВП для США.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
<script language=»javascript» type=»text/javascript»>
$(function () {
    var data = [ [[2003, 10882],
        [2002, 10383],
        [2001, 10020],
        [2000, 9762],
        [1999, 9213],
        [1998, 8720]] ];
     
    var plotarea = $(«#plotarea»);
    plotarea.css(«height», «250px»);
    plotarea.css(«width», «500px»);
    $.plot( plotarea , data );
});
</script>
Один график

Таблица данных, которую мы имели прежде, должна быть заменена на красивый график. Как видите, массив, содержащий набор данных, содержится в другом родительском массиве. Чтобы отобразить другой набор данных, мы просто добавляем его в качестве другого элемента в родительский массив. Давайте добавим данные для других стран, которые мы имели в нашей таблице.

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
var data = [
    [[2003, 10882],
    [2002, 10383],
    [2001, 10020],
    [2000, 9762],
    [1999, 9213],
    [1998, 8720]],
     
    [[2003, 10970],
    [2002, 9040],
    [2001, 8303],
    [2000, 8234],
    [1999, 8901],
    [1998, 8889]],
     
    [[2003, 1795],
    [2002, 1564],
    [2001, 1430],
    [2000, 1438],
    [1999, 1460],
    [1998, 1423]],
     
    [[2003, 1575],
    [2002, 1434],
    [2001, 1345],
    [2000, 1252],
    [1999, 1158],
    [1998, 1148]],
     
    [[2003, 599],
    [2002, 510],
    [2001, 479],
    [2000, 457],
    [1999, 447],
    [1998, 414]]
];
Мульти График

Теперь у нас есть довольно красивый график, но мы не знаем, какая линия и какая страна! Нам нужна легенда. К счастью, Flot поддерживает это и заключается в том, чтобы поместить наши наборы данных в объект 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
50
51
var data = [
    {
        label: «USA»,
        data: [[2003, 10882],
            [2002, 10383],
            [2001, 10020],
            [2000, 9762],
            [1999, 9213],
            [1998, 8720]]
    },
     
    {
        label: «EU»,
        data: [[2003, 10970],
            [2002, 9040],
            [2001, 8303],
            [2000, 8234],
            [1999, 8901],
            [1998, 8889]]
    },
     
    {
        label: «UK»,
        data: [[2003, 1795],
            [2002, 1564],
            [2001, 1430],
            [2000, 1438],
            [1999, 1460],
            [1998, 1423]]
    },
     
    {
        label: «China»,
        data: [[2003, 1575],
            [2002, 1434],
            [2001, 1345],
            [2000, 1252],
            [1999, 1158],
            [1998, 1148]]
    },
     
    {
        label: «India»,
        data: [[2003, 599],
            [2002, 510],
            [2001, 479],
            [2000, 457],
            [1999, 447],
            [1998, 414]]
    }
];
Граф с легендой

Я уже упоминал об этом, хотя у Flot есть много разумных значений по умолчанию Хотя они, вероятно, подойдут большинству людей, легенда частично скрывает некоторые данные. Flot имеет третий параметр для передачи опций в объекте JSON.

1
$.plot( plotarea , data, options );

Чтобы сделать данные в дальнем конце графика немного более видимыми, мы настроим непрозрачность фона и поля легенды.

1
2
3
4
5
6
7
var options = {
    legend: {
        show: true,
        margin: 10,
        backgroundOpacity: 0.5
    }
};
Параметры

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

01
02
03
04
05
06
07
08
09
10
11
var options = {
    legend: {
        show: true,
        margin: 10,
        backgroundOpacity: 0.5
    },
    points: {
        show: true,
        radius: 3
    }
};
Точки

Отлично, у нас есть точки данных, но куда делись линии ?! Давайте явно включим их обратно.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
var options = {
    legend: {
        show: true,
        margin: 10,
        backgroundOpacity: 0.5
    },
    points: {
        show: true,
        radius: 3
    },
    lines: {
        show: true
    }
};
Очки с линиями

Наш финальный код выглядит примерно так:

001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
063
064
065
066
067
068
069
070
071
072
073
074
075
076
077
078
079
080
081
082
083
084
085
086
087
088
089
090
091
092
093
094
095
096
097
098
099
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
<!DOCTYPE html PUBLIC «-//W3C//DTD XHTML 1.0 Transitional//EN» «http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd»>
<html xmlns=»http://www.w3.org/1999/xhtml»>
<head>
<meta http-equiv=»Content-Type» content=»text/html; charset=utf-8″ />
<title>Flot Tutorial</title>
 
<style type=»text/css»>
    body { font-family: Arial, Helvetica, sans-serif;
    table { border-collapse: collapse;
    td, th { border: 1px solid #222;
     
    /* Fix the legend */
    .legend td, .legend th { border: 0;
</style>
 
<script src=»jquery.js» language=»javascript» type=»text/javascript»></script>
<script src=»jquery.flot.pack.js» language=»javascript» type=»text/javascript»></script>
<!—[if IE]><script language=»javascript» type=»text/javascript» src=»excanvas.pack.js»></script><![endif]—>
 
<script language=»javascript» type=»text/javascript»>
$(function () {
    var data = [
        {
            label: «USA»,
            data: [[2003, 10882],
                [2002, 10383],
                [2001, 10020],
                [2000, 9762],
                [1999, 9213],
                [1998, 8720]]
        },
         
        {
            label: «EU»,
            data: [[2003, 10970],
                [2002, 9040],
                [2001, 8303],
                [2000, 8234],
                [1999, 8901],
                [1998, 8889]]
        },
         
        {
            label: «UK»,
            data: [[2003, 1795],
                [2002, 1564],
                [2001, 1430],
                [2000, 1438],
                [1999, 1460],
                [1998, 1423]]
        },
         
        {
            label: «China»,
            data: [[2003, 1575],
                [2002, 1434],
                [2001, 1345],
                [2000, 1252],
                [1999, 1158],
                [1998, 1148]]
        },
         
        {
            label: «India»,
            data: [[2003, 599],
                [2002, 510],
                [2001, 479],
                [2000, 457],
                [1999, 447],
                [1998, 414]]
        }
    ];
     
    var options = {
        legend: {
            show: true,
            margin: 10,
            backgroundOpacity: 0.5
        },
        points: {
            show: true,
            radius: 3
        },
        lines: {
            show: true
        }
    };
     
    var plotarea = $(«#plotarea»);
    plotarea.css(«height», «250px»);
    plotarea.css(«width», «500px»);
    $.plot( plotarea , data, options );
});
</script>
</head>
 
<body>
 
<div id=»plotarea»>
    <table>
        <caption>GDP, based on exchange rates, over time.
        <tr>
            <td></td>
            <th scope=»col»>2003</th>
            <th scope=»col»>2002</th>
            <th scope=»col»>2001</th>
            <th scope=»col»>2000</th>
            <th scope=»col»>1999</th>
            <th scope=»col»>1998</th>
        </tr>
        <tr>
            <th scope=»row»>USA</th>
            <td>10,882</td>
            <td>10,383</td>
            <td>10,020</td>
            <td>9,762</td>
            <td>9,213</td>
            <td>8,720</td>
        </tr>
        <tr>
            <th scope=»row»>EU</th>
            <td>10,970</td>
            <td>9,040</td>
            <td>8,303</td>
            <td>8,234</td>
            <td>8,901</td>
            <td>8,889</td>
        </tr>
        <tr>
            <th scope=»row»>UK</th>
            <td>1,765</td>
            <td>1,564</td>
            <td>1,430</td>
            <td>1,438</td>
            <td>1,460</td>
            <td>1,423</td>
        </tr>
        <tr>
            <th scope=»row»>China</th>
            <td>1,575</td>
            <td>1,434</td>
            <td>1,345</td>
            <td>1,252</td>
            <td>1,158</td>
            <td>1,148</td>
        </tr>
        <tr>
            <th scope=»row»>India</th>
            <td>599</td>
            <td>510</td>
            <td>479</td>
            <td>457</td>
            <td>447</td>
            <td>414</td>
        </tr>
    </table>
</div>
 
<p>GDP, based on exchange rates, over time.
 
</body>
</html>

Есть много возможностей с Flot. Flot API детализирует все различные параметры, доступные для настройки графиков, включая указание различных типов графиков, цветов, осей и даже включение интерактивных функций, таких как выбор и масштабирование. Другая возможность — сделать все это полностью динамическим и динамически генерировать код JavaScript с данными из базы данных, используя PHP.