Как создать целевые линии в диаграмме строк в dc.js

Я использую диаграмму, чтобы показать общую сумму продаж по позициям продавца.

Уже безуспешно пытались составить составную диаграмму, как и многие сообщения из Google, но ни в одном из примеров не используется диаграмма строк.

Как создать целевые линии в диаграмме строк в dc.js

Мне нужно сделать как изображение, создав красные линии, чтобы обозначить целевую стоимость продажи для каждого элемента, но я не знаю как, вы, ребята, можете мне помочь? Спасибо!

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

spenderRowChart = dc.rowChart("#chart-row-spenders");        

spenderRowChart
    .width(450).height(200)
    .dimension(itemDim)
    .group(totalItemGroup)
    .elasticX(true);

Если вы просто пытаетесь добавить несколько строк, вероятно, ловушка pretransition / renderlet - самый простой способ. Вы делаете более простую версию этот пример. ага ... нашел точный дубликат

Gordon 11.01.2019 04:00

Не могу сохранить это как дубликат, потому что ответ не был принят, но, пожалуйста, взгляните на этот вопрос / ответ и посмотрите, сработает ли он для вас! stackoverflow.com/questions/49125887/…

Gordon 11.01.2019 04:01

@Gordon эй, на самом деле я использую этот пример в своем текущем коде, но если вы посмотрите пример, линия не является динамической и покрывает все строки, это не то, что я точно хочу

Sandro Motyl 11.01.2019 11:54
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
2
3
151
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

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

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

Затем он добавляет новый элемент path в каждую строку. Удобно, что строки уже имеют формат SVG g групповые элементы, поэтому все, что помещено туда, уже будет смещено в верхний левый угол прямоугольника строки.

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

    var height = chart.select('g.row rect').attr('height');

Затем мы выбираем g и используем общий шаблон обновления, чтобы добавить path.target к каждому из них, если у него его нет. Мы сделаем его красным, сделаем его видимым, только если у нас есть данные для этой строки, и запустим его с X 0, чтобы он анимировался слева, как это делают прямоугольники строки:

    var target = chart.selectAll('g.row')
        .selectAll('path.target').data(function(d) { return [d]; });
    target = target.enter().append('path')
        .attr('class', 'target')
        .attr('stroke', 'red')
        .attr('visibility', function(d) {
            return (d.value.target !== undefined || _targets[d.key] !== undefined) ? 'visible' : 'hidden';
        })
        .attr('d', function(d) {
            return 'M0,0 v' + height;
        }).merge(target);

Последний .merge(target) объединяет этот выбор с основным.

Теперь мы можем анимировать все целевые строки в нужное положение:

    target.transition().duration(chart.transitionDuration())
        .attr('visibility', function(d) {
            return (d.value.target !== undefined || _targets[d.key] !== undefined) ? 'visible' : 'hidden';
        })
        .attr('d', function(d) {
            return 'M' + (chart.x()(d.value.target || _targets[d.key] || 0)+0.5) + ',0 v' + height;
        });

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

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

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

    .renderlet(function(chart) {
        dc.events.trigger(function() {
            filter1 = yearRingChart.filters();
            filter2 = spenderRowChart.filters();
        });
    })

    .on('pretransition', function(chart) {
        if (aux_path.length > 0){
            for (i = 0; i < aux_path.length; i++){
                aux_path[i].remove();
            }
        };

        aux_data = JSON.parse(JSON.stringify(data2));
        aux_data = aux_data.filter(venda => filter1.indexOf(venda.Nome) > -1);

        meta_subgrupo = [];
        aux_data.forEach(function(o) {
            var existing = meta_subgrupo.filter(function(i) { return i.SubGrupo === o.SubGrupo })[0];
            if (!existing)
                meta_subgrupo.push(o);
            else
                existing.Meta += o.Meta;
        });
        
        if (filter1.length > 0) {
            for (i = 0; (i < Object.keys(subGrupos).length); i++){                 
                var x_vert = meta_subgrupo[i].Meta;
                var extra_data = [
                    {x: chart.x()(x_vert), y: 0},
                    {x: chart.x()(x_vert), y: chart.effectiveHeight()}
                ];
                var line = d3.line()
                    .x(function(d) { return d.x; })
                    .y(function(d) { return d.y; })
                    .curve(d3.curveLinear);
                var chartBody = chart.select('g');
                var path = chartBody.selectAll('path.extra').data([extra_data]);
                path = path.enter()
                        .append('path')
                        .attr('class', 'oeExtra')
                        .attr('stroke', subGruposColors[i].Color)
                        .attr('id', 'ids')
                        .attr("stroke-width", 2)
                        .style("stroke-dasharray", ("10,3"))
                    .merge(path)
                path.attr('d', line);
                aux_path.push(path);
            }  
        }
})

И вот как это выглядит

Другие вопросы по теме