21.4.16. Пример использования элемента <canvas>: внутристрочные диаграммы

We use cookies. Read the Privacy and Cookie Policy

Закончим главу практическим примером рисования внутристрочных диаграмм. Внутристрочная диаграмма (sparkline) - это маленькое изображение (обычно некий график) предназначенное для отображения в потоке текста, например: Server load: 8. Термин «sparkline» был введен их автором Эдвардом Тафти (Edward Tufte), который описывает внутристрочные диаграммы так: «Маленькие графические изображения с высоким разрешением, встроенные в контекст окружающих их слов, чисел, изображений. Внутристрочная диаграмма -это простой в создании, тесно связанный с данными график, размер которого сопоставим с размером слова». (Подробнее о создании внутристрочных диаграмм см. в книге Эдварда Тафти «Beautiful Evidence» [Graphics Press].)

В примере 21.13 приводится относительно простой модуль на языке JavaScript, позволяющий вставлять в веб-страницы внутристрочные диаграммы. Порядок работы модуля описывается в комментариях. Обратите внимание, что в нем используется функция onLoad() из примера 13.5.

Пример 21.13. Реализация внутристрочных диаграмм с помощью элемента <canvas>

/*

* Отыскивает все элементы с CSS-классом "sparkline", анализирует их содержимое

* как последовательность чисел и замещает их графическим представлением.

*

* Определить внутристрочную диаграмму в разметке можно так:

* <span class="sparkline">3 5 7 6 6 9 11 15</span>

*

* Определить визуальное оформление диаграмм средствами CSS можно так:

* .sparkline { background-color: #ddd; color: red; }

*

* - Цвет кривой графика определяется CSS-свойством color вычисленного стиля.

* - Сами диаграммы являются прозрачными, поэтому сквозь них просвечивает фон страницы.

* - Высота диаграммы определяется атрибутом data-height, если он указан,

* или свойством font-size вычисленного стиля в противном случае.

* - Ширина диаграммы определяется атрибутом data-width, если он указан,

* или числом точек данных, умноженным на значение атрибута data-dx, если он

* указан, или числом точек данных, умноженным на высоту, деленную на 6

* - Минимальное и максимальное значение по оси у извлекаются из атрибутов

* data-ymin и data-ymax, если они указаны, иначе отыскиваются минимальное

* и максимальное значение в данных.

*/

onLoad(function() { // Когда документ будет загружен

  //Отыскать все элементы с классом "sparkline"

  var elts = document.getElementsByClassName("sparkline");

  main: for(var e = 0; e < elts.length: e++) { // Для каждого элемента

    var elt = elts[e];

    // Получить содержимое элемента и преобразовать его в массив чисел.

    // Если преобразование не удалось, пропустить этот элемент.

    var content = elt.textContent || elt.innerText; // Содержимое

    var content = content.replace(/~s+|s+$/g, // Удалить пробелы

    var text = content.replace(/#.*$/gm, // Удалить комментарии

    text = text.replace(/[ vf]/g, " ");// Преобр. и др. в пробел

    var data = text.split(/s+|s*,s*/); // По пробелам и запятым

    for(var і = 0; і < data.length; і++) { // Каждый фрагмент

      data[i] = Number(data[і]); // Преобразовать в число

      if (isNaN(data[і])) continue main; // Прервать при неудаче

    }

    // Определить цвет, ширину, высоту и границы по оси у для диаграммы

    // из данных, из атрибутов data- элемента и из вычисленного стиля,

    var style = getComputedStyle(elt, null);

    var color = style.color:

    var height = parselnt(elt.getAttributefdata-height")) ||

      parseInt(style.fontSize) || 20;

    var width = parseInt(elt.getAttribute("data-width")) ||

      data.length * (parseInt(elt.getAttribute("data-dx")) || height/6);

    var ymin = parselnt(elt.getAttribute("data-ymin")) ||

      Math.min.apply(Math, data);

    var ymax = parseInt(elt.getAttribute("data-ymax")) || Math.max.apply(Math, data);

    if (ymin >= ymax) ymax = ymin + 1;

    // Создать элемент <canvas>.

    var canvas = document.createElement("canvas”);

    canvas.width = width; // Установить размеры холста

    canvas.height = height;

    canvas.title = content; // Содержимое использовать как подсказку

    elt.innerHTML = "" ;// Стереть содержимое элемента

    elt.appendChild(canvas); // Вставить холст в элемент

    // Нарисовать график по точкам (і,data[і]), преобразовав в координаты холста,

    var context = canvas.getContext('2d');

    for(var і = 0; і < data.length; i++) { // Для каждой точки на графике

      var х = width*i/data.length;                // Масштабировать і

      var у = (ymax-data[i])*height/(ymax-ymin);  // и data[i]

      context.1іnеТо(х,у); // Первый вызов lineТо() выполнит moveTo()

    }

    context.strokeStyle = color; // Указать цвет кривой на диаграмме

    context.stroke(); // и нарисовать ее

  }

});