2015-02-22 2 views
4

Я пытался изучить D3 (Bubble Charts специально). Я создал очень простую схему здесь:Создание легенды для пузырьковой диаграммы с использованием D3

//This is making the demensions for the circles and canvas 
    //The format and color is for hovering over the circles for the dialog box 
    var diameter = 1500, 
     format = d3.format(",d"), 
     color = d3.scale.category20c(); 

    //This makes the canvas that the bubble chart will be made on 
    var canvas = d3.select("body").append("svg") 
            .attr("width", diameter) 
            .attr("height", diameter) 
            .append("g") 
            .attr("transform", "translate(50,50)"); 

    //This is the size of the actual bubbles in the chart 
    var pack = d3.layout.pack() 
      .size([900, 900]) 
      .padding(85); 

    //This is adding the data into the bubbles and creating their size 
    d3.json("CountryData.js", function (data) { 
     var nodes = pack.nodes(data); 

     var node = canvas.selectAll(".node") 
        .data(nodes) 
        .enter() 
        .append("g") 
         .attr("class", "node") 
         .attr("transform", function (d) { return "translate(" + d.x + "," + d.y + ")"; }); 

     //This is the actual bubbles 
     node.append("circle") 
      .attr("r", function (d) {return d.r;}) 
      .style("fill", function (d, i) { return color(i); }); 


     //This is the text inside the bubbles 
     node.append("text") 
      .text(function (d) { return d.children ? "" : d.name; }) 
      .style("text-anchor", "middle") 

     //This is the dialog box 
     node.append("title") 
      .text(function (d) { return d.name + ": " + format(d.value) + "" + "medals"; }); 


    }); 

Я пытаюсь добавить легенду, которая будет показывать «Азия», «Северная Америка», «Ближний Восток» и т.д., и их цвета. Самое близкое, что у меня есть, - это показать коробки с цветами и отобразить названия цветов. Я пытался использовать это: Legend in D3 circle pack diagram в качестве ссылки. Я могу приложить, как я пытался сделать легенду, но я чувствую, что это будет слишком много кода для сообщения. Вот мои данные:

{ 
"name" : "Region Olympic Medals", 
"value" : 10000, 
"children" : [ 
    { 
     "name" : "Asia", 
     "value" : 451, 
     "children" : [ 
      {"name" : "Summer Gold", "value" : 114}, 
      {"name" : "Summer Silver", "value" : 172}, 
      {"name" : "Summer Bronze", "value" : 158}, 
      {"name" : "Winter Gold", "value" : 1}, 
      {"name" : "Winter Silver", "value" : 1}, 
      {"name" : "Winter Bronze", "value" : 2} 
     ] 
    }, 
    { 
     "name" : "Australia & Oceaina", 
     "value" : 26, 
     "children" : [ 
      {"name" : "Summer Gold", "value" : 4}, 
      {"name" : "Summer Silver", "value" : 7}, 
      {"name" : "Summer Bronze", "value" : 15}, 
      {"name" : "Winter Gold", "value" : 0}, 
      {"name" : "Winter Silver", "value" : 0}, 
      {"name" : "Winter Bronze", "value" : 0} 
     ] 
    }, 
    { 
     "name" : "Caribbean", 
     "value" : 1136, 
     "children" : [ 
      {"name" : "Summer Gold", "value" : 306}, 
      {"name" : "Summer Silver", "value" : 319}, 
      {"name" : "Summer Bronze", "value" : 381}, 
      {"name" : "Winter Gold", "value" : 42}, 
      {"name" : "Winter Silver", "value" : 41}, 
      {"name" : "Winter Bronze", "value" : 47} 
     ] 
    }, 
    { 

      "name" : "Central America", 
      "value" : 26, 
      "children" : [ 
       {"name" : "Summer Gold", "value" : 4}, 
       {"name" : "Summer Silver", "value" : 3}, 
       {"name" : "Summer Bronze", "value" : 4}, 
       {"name" : "Winter Gold", "value" : 0}, 
       {"name" : "Winter Silver", "value" : 0}, 
       {"name" : "Winter Bronze", "value" : 0} 
     ] 
    }, 
    { 

     "name" : "Europe", 
     "value" : 7264, 
     "children" : [ 
      {"name" : "Summer Gold", "value" : 1924}, 
      {"name" : "Summer Silver", "value" : 1993}, 
      {"name" : "Summer Bronze", "value" : 2257}, 
      {"name" : "Winter Gold", "value" : 362}, 
      {"name" : "Winter Silver", "value" : 366}, 
      {"name" : "Winter Bronze", "value" : 362} 
     ] 
    }, 
    { 

     "name" : "Middle East", 
     "value" : 2696, 
     "children" : [ 
      {"name" : "Summer Gold", "value" : 280}, 
      {"name" : "Summer Silver", "value" : 331}, 
      {"name" : "Summer Bronze", "value" : 361}, 
      {"name" : "Winter Gold", "value" : 535}, 
      {"name" : "Winter Silver", "value" : 582}, 
      {"name" : "Winter Bronze", "value" : 607} 
     ] 
    }, 
    { 

     "name" : "North America", 
     "value" : 7, 
     "children" : [ 
      {"name" : "Summer Gold", "value" : 4}, 
      {"name" : "Summer Silver", "value" : 1}, 
      {"name" : "Summer Bronze", "value" : 2}, 
      {"name" : "Winter Gold", "value" : 0}, 
      {"name" : "Winter Silver", "value" : 0}, 
      {"name" : "Winter Bronze", "value" : 0} 
     ] 
    }, 
    { 

     "name" : "South America", 
     "value" : 6273, 
     "children" : [ 
      {"name" : "Summer Gold", "value" : 1220}, 
      {"name" : "Summer Silver", "value" : 1014}, 
      {"name" : "Summer Bronze", "value" : 335}, 
      {"name" : "Winter Gold", "value" : 1421}, 
      {"name" : "Winter Silver", "value" : 1193}, 
      {"name" : "Winter Bronze", "value" : 1090} 
     ] 
    }, 
    { 

     "name" : "Sub-Saharan Africa", 
     "value" : 1847, 
     "children" : [ 
      {"name" : "Summer Gold", "value" : 485}, 
      {"name" : "Summer Silver", "value" : 549}, 
      {"name" : "Summer Bronze", "value" : 628}, 
      {"name" : "Winter Gold", "value" : 50}, 
      {"name" : "Winter Silver", "value" : 59}, 
      {"name" : "Winter Bronze", "value" : 76} 
     ] 
    } 
] 

}

+0

Кроме того, комментарии, которые я сделал в коде, могут быть неверными. Если нет, сообщите мне, чтобы я мог их изменить. =) –

ответ

2

Чтобы создать легенду, вы можете фильтровать данные в зависимости от того есть они d.children или нет.

var legend_data = nodes.filter(function(d,i){ 
    d.original_index = i; 
    return d.children; 
    }); 

Обратите внимание, что я сохранил индекс в исходных данных устанавливается d.original_index для color атрибута позже.

Во-вторых, как показано в [например] вы ссылки, мы можем enter() наши данные легенды в новом <g> элемента, отрегулируйте х и у по мере необходимости.

var legend = canvas.append("g") 
    .attr("class", "legend") 
    .selectAll("g") 
    .data(legend_data) 
    .enter() 
     .append("g") 
     .attr("transform", function(d,i){ 
      return "translate(" + d.depth*10 + "," + i*20 + ")"; 
      }) 

// Draw rects, and color them by original_index 
legend.append("rect") 
    .attr("width", 8) 
    .attr("height", 8) 
    .style("fill", function(d){return color(d.original_index)}); 

legend.append("text") 
    .attr("x", function(d,i){ return d.depth*10 +10;}) 
    .attr("dy", "0.50em") 
    .text(function(d){return d.name;}) 

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

Адрес working fiddle Ваши данные. Сообщите мне, если что-то еще неясно.

+0

У меня возник вопрос об этом ответе, в частности о «d.orginal_index». Когда я использую это для другой диаграммы, появляется легенда, но цвета ошибочны. Для нового графика я использую категорию 10, а не 20c. Как можно изменить цвет легенды в соответствии с новой категорией цветов? –

Смежные вопросы