Рисование динамического индикатора выполнения на основе D3.js

внешний интерфейс SVG ECharts d3.js
Рисование динамического индикатора выполнения на основе D3.js

предисловие

Когда страница веб-сайта загружается и фиксируется форма, часто используйте индикатор выполнения, чтобы выразить процесс загрузки, чтобы оптимизировать взаимодействие с пользователем, общий индикатор выполнения имеет прямоугольный индикатор выполнения и круглый индикатор выполнения, как показано ниже:

Мы часто используем svg или холст для рисования динамической графики, но процесс рисования относительно громоздкий. Для интуитивно понятных и красивых индикаторов выполнения сообщество также предлагает зрелые решения, такие как highcharts/ECharts и т. д., но метод разработки на основе конфигурации не может обеспечить 100% пользовательское рисование. В этой статье вы узнаете, как использовать D3.js для пошаговой реализации динамического индикатора выполнения с нуля и поделитесь логическими принципами кода.

Базовые требования

  • Узнайте, как svg рисует базовую графику
  • Понимание версии D3.js v4
  • Узнайте, как рисовать базовую графику для svg с помощью D3.js (v4)

Нарисуйте круговой индикатор выполнения

Для круглого индикатора выполнения мы сначала разделяем задачу:

  • рисовать вложенные дуги
  • Отображение данных в реальном времени в центре круга
  • показать анимацию
  • украшать

1. Нарисуйте вложенные дуги

Для кругов svg предоставляет готовыеcircleМетки доступны для использования, но их недостаток в том, что для круглых индикаторов выполнения используетсяcircleЕго можно удовлетворить, но при дальнейшем расширении графика, например, при рисовании полукруга,circleобращение сложное. D3.js предоставляетarcСвязанный API инкапсулирует метод рисования круга:

var arc = d3.arc()
            .innerRadius(180)
            .outerRadius(240)
            //.startAngle(0)
            //.endAngle(Math.PI)

arc(); // "M0,-100A100,100,0,0,1,100,0L0,0Z"

Приведенный выше код реализует логику рисования для двух вложенных кругов,d3.arc()Возвращает конструктор дуги и устанавливает радиусы, начальный и конечный углы внутренней и внешней окружностей с помощью связанных вызовов. воплощать в жизньarc()Конструктор можно использовать для привязки<path>данные пути на . Полный код выглядит следующим образом:

<!--html-->
<svg width="960" height="500"></svg>

<script>
    var arcGenerator = d3.arc().innerRadius(80).outerRadius(100).startAngle(0);
    
    var picture = d3.select('svg').append('g').attr('transform','translate(480,250)');
</script>

Приведенный выше код реализует 2 шага:

  • 1. Создайте конструктор дуги с 0 градусов в качестве начальной точкиarcGenerator
  • 2. НастройкиtransformСмещение графики, чтобы графика находилась в центре холста

В данный момент на холсте нет элементов, далее мы будем рисовать собственно графику.

var backGround = picture.append("path")
        .datum({endAngle: 2 * Math.PI})
        .style("fill", "#FDF5E6")
        .attr("d", arcGenerator);

наш холстpictureДобавить к<path>элемент, согласноendAngle()особенность, использованиеdatum()метод будет{endAngle:Math.PI}конечный уголсвязываются с<path>элемент и назначьте конструктор дугиpathдорожкаd. Таким образом создается дуга с заданным фоновым цветом.Фактический рисунок выглядит следующим образом:

Рисуется первая дуга, затем согласно иерархической взаимосвязи svgz-index, так называемый индикатор выполнения на самом деле является вторым слоем дуг, покрывающим первый слой дуг. Так же можно получить:

var upperGround = picture.append('path')
        .datum({endAngle:Math.PI / 2})
        .style('fill','#FFC125')
        .attr('d',arcGenerator)

После запуска кода вы можете получить:

2. Отображение данных в реальном времени в центре круга

Первая реализованная нами часть основана на двухpathвложенных кругов. Во второй части мы реализуем отображение данных в реальном времени в центре круга. Когда индикатор загрузки загружается, мы добавляем данные в центр круга, чтобы выразить текущий прогресс загрузки, используя<text>Метка может отображаться:

var dataText = g.append('text')
        .text(12)
        .attr('text-anchor','middle')
        .attr('dominant-baseline','middle')
        .attr('font-size','38px')

Временно установите данные на 12 и установите центр по горизонтали и центр по вертикали, эффект будет следующим:

3. Показать анимацию

Через 1 и 2 мы уже знаем:

  • Суть рисования индикатора выполнения заключается в изменении угла верхней дуги
  • когда радианявляется полным кругом, когда радианπполукруг
  • Данные в круге относятся к текущему радиану.процент из

Таким образом, нам нужно только изменить значение в радианах и числовое значение и установить время, необходимое для процесса изменения для достижения так называемой «анимации». В официальном примере, предоставленном ECharts,setIntervalФактически, для достижения обновления данных каждый фиксированный период времени D3.js также предоставляет аналогичный метод для достижения аналогичногоsetIntervalфункция:

d3.interval(function(){
    foreground.transition().duration(750).attrTween('d',function(d){
        var compute = d3.interpolate(d.endAngle,Math.random() * Math.PI * 2);
        return function(t){
            d.endAngle = compute(t);
            return arcGenerator(d);
        }
        
    })
},1000)

Разберите этот код:

  • d3.interval()метод обеспечиваетsetInterval()функция
  • selection.transition.duration()Задает время, необходимое для процесса перехода от текущего свойства DOM к указанному свойству DOM, в миллисекундах.
  • transation.attrTweenЧто такое интерполяция для API функции интерполяции?

Короче говоря, интерполяция функции в заданных дискретных данных позволяет этой непрерывной функции проходить через все точки данных. Например, для элемента div я хочу добиться линейного градиента цвета его фона от красного (красного) слева до зеленого (зеленого) справа Как рассчитать значение цвета каждой области? Только что:

var compute = d3.interpolate(d3.rgb(255,0,0),d3.rgb(0,255,0));

computeТо есть функция интерполяции, диапазон параметров [0, 1], пока вы вводите числа в этом диапазоне, тоcomputeФункция вернет соответствующее значение цвета. Какая польза от такой интерполяции? См. рисунок ниже:

Предполагая, что ширина длины div на приведенном выше рисунке равна 100, затем преобразуйте [0, 100] в данные диапазона [0, 10] в соответствии с пропорциональным соотношением и введитеcomputeФункция, вы можете получить цвет, соответствующий определенной области. Конечно, мы не должны использовать дискретные данные в качестве ввода и вывода для линейной обработки области, поэтому D3.js предоставляет более удобный API линейного градиента.d3.linearПодождите, я не буду расширять описание здесь.

Ближе к дому, кодd3.interpolate(d.endAngle,Math.random() * Math.PI * 2);Реализованы следующие диапазоны интерполяции:

["当前角度值","随机角度值"] //表达区间而非数组

Затем верните параметр какtфункция, то какова функция этой функции?
tПараметры иdАналогично, интерполяция реализована внутри D3.js, и ее диапазон составляет [0, 1].tпараметры устанавливаются в соответствии сduration()Продолжительность автоматически вычисляет количество интерполяции в [0, 1] и возвращает результат интерполяции, а также реализуется линейный эффект анимации перехода.

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

d3.interval(function(){
        foreground.transition().duration(750).attrTween('d',function(d){
            var compute = d3.interpolate(d.endAngle,Math.random() * Math.PI * 2);
            return function(t){
                d.endAngle = compute(t);
                var data = d.endAngle / Math.PI / 2 * 100;
                //设置数值
                d3.select('text').text(data.toFixed(0) + '%');
                //将新参数传入,生成新的圆弧构造器
                return arcGenerator(d);
            }
        })
    },2000)

Окончательный эффект выглядит следующим образом:

4. Украсить

В частях 1, 2 и 3 мы реализовали самые основные стили и функции индикатора выполнения, но стиль все еще выглядит очень однообразно.Далее мы выполним обработку линейного градиента на индикаторе выполнения. Мы используем API линейной интерполяции, предоставляемый D3.js:

var colorLinear = d3.scaleLinear().domain([0,100]).range(["#EEE685","#EE3B3B"]);

colorLinearЭто также функция интерполяции.Когда мы вводим значение в интервале [0, 100], он возвращает значение цвета, соответствующее интервалу ["#EEE685", "#EE3B3B"]. Например, когда индикатор выполнения показывает, что прогресс составляет «80%»:

var color = colorLinear(80);
//color即为"80%"对应的色值

После определения значения цвета нам нужно изменить исходный цвет только при изменении индикатора выполнения:

d3.interval(function(){
        foreground.transition().duration(750).attrTween('d',function(d){
            var compute = d3.interpolate(d.endAngle,Math.random() * Math.PI * 2);
            return function(t){
                d.endAngle = compute(t);
                var data = d.endAngle / Math.PI / 2 * 100;
                //设置数值
                d3.select('text').text(data.toFixed(0) + '%');
                //将新参数传入,生成新的圆弧构造器
                return arcGenerator(d);
            }
        })
        .styleTween('fill',function(d){
            return function(t){
                var data = d.endAngle / Math.PI / 2 * 100;
                //返回数值对应的色值
                return colorLinear(data);
            }
        })
    },2000)

styleTweenа такжеattrTweenТочно так же есть функция интерполяции, реализующая изменение стилей. Вы можете установить значение и цвет индикатора выполнения одновременно в виде цепных вызовов. Окончательный эффект выглядит следующим образом:

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

Нарисуйте прямоугольный индикатор выполнения

Прямоугольная панель прогресса намного проще, чем круговой прогресс. Он также основан на принципе интерполяции, а длина прямоугольника может быть гладко изменена. Перейдите непосредственно к коду:

<head>
    <style>
        #slider {
            height: 20px;
            width: 20px;
            background: #2394F5;
            margin: 15px;
        }
    </style>
</head>

<body>
    <div id='slider'></div>
    <script>
        d3.interval(function(){
            d3.select("#slider").transition()
                .duration(1000)
                .attrTween("width", function() {
                    var i = d3.interpolate(20, 400);
                    var ci = d3.interpolate('#2394F5', '#BDF436');
                    var that = this;
                    return function(t) {
                        that.style.width = i(t) + 'px';
                        that.style.background = ci(t);
                    };
                });
        },1500)
    </script>
</body>

Достигаемый эффект следующий:

Суммировать

Ключевым моментом рисования индикатора выполнения на основе D3.js является интерполяция, чтобы графика могла плавно переходить правильно. Если вам нужно использовать svg или чистый css для получения прямоугольных и круглых индикаторов выполнения, это, безусловно, возможно, но обработка путей и анимации, а также требования к написанию css намного сложнее. Мы заметили, что логический код для рисования двух вышеперечисленных индикаторов выполнения с использованием D3.js почти полностью реализован с использованием js.В то же время объем кода можно контролировать примерно до 20 строк, его можно инкапсулировать и использовать повторно. была очень усовершенствована и очень полезна при разработке пользовательских диаграмм.

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