Как создать целевые строки в диаграмме строк в dc.js - PullRequest
0 голосов
/ 09 января 2019

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

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

enter image description here

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

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

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

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

Ответы [ 2 ]

0 голосов
/ 13 января 2019

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

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

    .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);
            }  
        }
})

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

enter image description here

0 голосов
/ 13 января 2019

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

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

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

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

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

Затем мы выбираем g s и используем общий шаблон обновления, чтобы добавить 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;
        });

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

...