2013-07-01 2 views
12

Я застрял в этой проблеме в течение нескольких дней.Добавление нескольких svg-текстов с d3

Так у меня есть набор данных объектов следующего вида:

dataset = [{metric:"revenue",value:0.03},{metric:"sales", value:0.15},{metric:"churn", value: 0.06},{metric:"logins", value: 0.45}] 

Следующий код будет отображать 4 метрические имена в виде решетки (сетчатых, meshx являются координаты точек сетки и meshsize является размер сетки, так что это просто положить текст в середине квадрата сетки):

svg.selectAll("text") 
    .data(dataset) 
    .enter() 
    .append("text") 
    .text(function(d){ 
     return d.metric; 
    }) 
    .attr("y",function(d,i){ 
     return meshy[i] + meshsize/2; 
    }) 
    .attr("x", function(d,i){ 
     return meshx[i] + meshsize/2; 
    }) 
    .attr("font-size",25) 
    .attr("font-family","serif") 
    .attr("text-anchor","middle") 
    .attr("font-weight","bold"); 

Теперь я хотел бы поставить значение метрики справа под метрическим именем так:

svg.append("text") 
    .data(dataset) 
    .text(function(d){ 
     return (d.value); 
    }) 
    .attr("y",function(d,i){ 
     return meshy[i] + meshsize/2 + 20; 
    }) 
    .attr("x", function(d,i){ 
     return meshx[i] + meshsize/2 ; 
    }) 
    .attr("font-size",25) 
    .attr("font-family","serif") 
    .attr("text-anchor","middle") 
    .attr("font-weight","bold"); 

Но это только возвращает значение под именем метрики для FIRST-метрики, другие 3 значения текста даже не в DOM. Я пробовал несколько подходов, включая замену .text на .html, как описано здесь: https://github.com/mbostock/d3/wiki/Selections#wiki-html без успеха. Я также попытался добавить элементы абзаца вместо этого - это работает, но элементы p расположены ниже тела svg в списке без очевидного способа переместить их в нужное положение. Вышеприведенный код ближе всего подходит для получения того, что мне нужно, но по какой-то причине появляется только первый текст значения. Тем не менее, я открыт для любого подхода в d3, который выполняет эту работу: 4 метрических имени со значениями прямо под ними

ответ

32

В вашем втором блоке кода вы добавляете только один элемент text, поэтому только один из них появляться. Что вам нужно сделать, так это добавить текст, похожий на ваш первый блок, т. Е. С выбором .enter(). Для этого у вас есть два варианта. Вы можете либо сохранить, либо повторно использовать выбор .enter(), либо назначить разные классы двум типам текста, чтобы они могли различать их.

Вариант 1:

var texts = svg.selectAll("text") 
       .data(dataset) 
       .enter(); 

texts.append("text") 
    .text(function(d){ 
        return d.metric; 
       }) 
    // set position etc. 

texts.append("text") 
    .text(function(d){ 
        return d.value; 
       }) 
    // set position etc. 

Вариант 2:

svg.selectAll("text.title") 
       .data(dataset) 
       .enter() 
       .append("text") 
       .attr("class", "title") 
       .text(function(d){ 
        return d.metric; 
       }) 
    // set position etc. 

svg.selectAll("text.value") 
       .data(dataset) 
       .enter() 
       .append("text") 
       .attr("class", "value") 
       .text(function(d){ 
        return d.value; 
       }) 
    // set position etc. 

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

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