Круговые диаграммы

Snap.svg предоставляет удобные инструменты для создания векторной графики на веб-странице, включая построение круговых диаграмм. Круговая диаграмма состоит из сегментов (секторов), которые визуально отображают пропорции данных.

Создание SVG-контейнера

Для начала необходимо создать контейнер SVG с помощью Snap:

var s = Snap(500, 500); // создаём холст размером 500x500 пикселей

Контейнер s станет основой для всех элементов диаграммы.

Рисование кругового сегмента

Круговой сегмент строится с помощью команды path. Основная идея — использовать дугу (arc) для формирования части окружности. Для этого удобно определить функцию, которая строит путь сегмента:

function describeArc(x, y, radius, startAngle, endAngle){
    var start = polarToCartesian(x, y, radius, endAngle);
    var end = polarToCartesian(x, y, radius, startAngle);

    var largeArcFlag = endAngle - startAngle <= 180 ? "0" : "1";

    return [
        "M", start.x, start.y,
        "A", radius, radius, 0, largeArcFlag, 0, end.x, end.y,
        "L", x, y,
        "Z"
    ].join(" ");
}

function polarToCartesian(centerX, centerY, radius, angleInDegrees) {
    var angleInRadians = (angleInDegrees-90) * Math.PI / 180.0;

    return {
        x: centerX + (radius * Math.cos(angleInRadians)),
        y: centerY + (radius * Math.sin(angleInRadians))
    };
}
  • polarToCartesian переводит угол в координаты точки на окружности.
  • describeArc возвращает строку пути, формирующую сектор.

Создание отдельных сегментов

После определения функции построения пути можно добавить сегменты диаграммы:

var data = [30, 70, 45, 55]; // значения для диаграммы
var colors = ["#FF5733", "#33FF57", "#3357FF", "#F3FF33"];
var total = data.reduce((a,b) => a + b, 0);
var startAngle = 0;

data.forEach(function(value, i){
    var angle = (value / total) * 360;
    var path = describeArc(250, 250, 100, startAngle, startAngle + angle);
    s.path(path).attr({fill: colors[i]});
    startAngle += angle;
});
  • data.reduce вычисляет общую сумму значений для корректного расчёта углов.
  • startAngle аккумулирует начальный угол для каждого нового сегмента.
  • Атрибут fill задаёт цвет сегмента.

Анимация круговой диаграммы

Snap.svg позволяет анимировать сегменты. Для плавного отображения можно использовать изменение атрибута path:

var pathElement = s.path(describeArc(250, 250, 100, 0, 0)).attr({fill: "#FF5733"});

pathElement.animate({d: describeArc(250, 250, 100, 0, 120)}, 1000, mina.easeinout);
  • animate плавно меняет атрибут d пути.
  • mina.easeinout добавляет эффект замедления в начале и конце анимации.

Добавление текста в сегменты

Для отображения значений можно использовать элемент text:

var angle = 60; // средний угол сегмента
var pos = polarToCartesian(250, 250, 70, angle); // позиция текста внутри сегмента
s.text(pos.x, pos.y, "30").attr({
    "font-size": 16,
    "text-anchor": "middle",
    "alignment-baseline": "middle"
});
  • text-anchor: middle центрирует текст по горизонтали.
  • alignment-baseline: middle центрирует по вертикали относительно заданной точки.

Создание интерактивной диаграммы

Snap.svg позволяет добавлять события для сегментов:

pathElement.hover(
    function(){ this.attr({fill: "#FF0000"}); },
    function(){ this.attr({fill: "#FF5733"}); }
);
  • Метод hover принимает функции для наведения мыши и её ухода.
  • Можно изменить цвет сегмента или добавить эффект увеличения.

Итоговая структура круговой диаграммы

  • Создать SVG-контейнер.
  • Определить функции polarToCartesian и describeArc.
  • Построить сегменты с учётом долей данных.
  • При необходимости добавить текстовые подписи.
  • Для улучшения восприятия — анимация и интерактивность.

Использование Snap.svg для круговых диаграмм обеспечивает точное построение сегментов, гибкость при изменении данных и возможность визуально насыщенных эффектов без сторонних библиотек.