d3js Создать легенду для гистограммы

У меня есть пара проблем с гистограммой. Текущий выпуск пытается создать легенду. В легенде должно быть указано Global и Local (сине-зеленый). В настоящее время легенда формирует 5 прямоугольников, 2 из которых цветные. Я предполагаю, что он просматривает мой набор данных и генерирует блоки для каждого набора столбцов. Я не хочу это.

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

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

У меня есть рабочий скрипт, с которым вы можете поиграть.

Источники данных

var colors =    {0: ["Local", "#377EB8"],
             1: ["Global", "#4DAF4A"]};

var dataset = [
            {"keyword": "payday loans", "global": 1400000, "local": 673000, "cpc": "14.11"},
            {"keyword": "title loans", "global": 165000, "local": 160000, "cpc": "12.53" },
            {"keyword": "personal loans", "global": 550000, "local": 301000, "cpc": "6.14"},
            {"keyword": "online personal loans", "global": 15400, "local": 12900, "cpc": "5.84"},
            {"keyword": "online title loans", "global": 111600, "local": 11500, "cpc": "11.74"}
        ];

Код ярлыка

var legend = svg.append("g")
    .attr("class", "legend")
    //.attr("x", w - 65)
    //.attr("y", 50)
    .attr("height", 100)
    .attr("width", 100)
    .attr('transform', 'translate(-20,50)');


legend.selectAll('rect')
    .data(dataset)
    .enter()
    .append("rect")
    .attr("x", w - 65)
    .attr("y", function(d, i) {
        return i * 20;
    })
    .attr("width", 10)
    .attr("height", 10)
    .style("fill", function(d) {
        var color = colors[dataset.indexOf(d)][1];
        return color;
    });

legend.selectAll('text')
    .data(dataset)
    .enter()
    .append("text")
    .attr("x", w - 52)
    .attr("y", function(d, i) {
        return i * 20 + 9;
    })
    .text(function(d) {
        var text = colors[dataset.indexOf(d)][0];
        return text;
    });

Я знаю, что мой массив / объект Colors, вероятно, не самый эффективный способ. Так что я готов изменить это, если это поможет с решением. Кроме того, я бы предпочел, чтобы это был горизонтальный список, а не вертикальный.


person EnigmaRM    schedule 23.04.2013    source источник


Ответы (1)


Вам нужно использовать colors, а не dataset в качестве параметра для .data() вашей легенды. Чтобы это работало, colors должен быть массивом, а не объектом:

var colors = [ ["Local", "#377EB8"],
               ["Global", "#4DAF4A"] ];

Код для создания легенды становится таким:

var legendRect = legend.selectAll('rect').data(colors);

legendRect.enter()
    .append("rect")
    .attr("x", w - 65)
    .attr("width", 10)
    .attr("height", 10);

legendRect
    .attr("y", function(d, i) {
        return i * 20;
    })
    .style("fill", function(d) {
        return d[1];
    });

var legendText = legend.selectAll('text').data(colors);

legendText.enter()
    .append("text")
    .attr("x", w - 52);

legendText
    .attr("y", function(d, i) {
        return i * 20 + 9;
    })
    .text(function(d) {
        return d[0];
    });

См. обновленную скрипку.

person ValarDohaeris    schedule 23.04.2013
comment
Отлично. А как бы сделать горизонтальным? - person EnigmaRM; 24.04.2013
comment
Как это? Я думаю, что повернутый текст немного неудобно читать ... - person ValarDohaeris; 24.04.2013
comment
Кроме того, если вы хотите выполнять динамические обновления, вам следует узнать об общем шаблоне обновления! - person ValarDohaeris; 24.04.2013
comment
Ха-ха. Ты прав. Такой повернутый текст трудно читать. И это не то, чего я хотел добиться. Я так думаю, они рядом. * Глобальный * Локальный (где * обозначает поле / цвет). Прямо сейчас они сложены друг на друга. Я бы предпочел, чтобы они были рядом друг с другом. - person EnigmaRM; 24.04.2013
comment
Готово. Но тогда это работает только в том случае, если ваши метки достаточно короткие, поэтому в более общем случае я все же думаю, что вертикальная легенда предпочтительнее. - person ValarDohaeris; 24.04.2013