2013-04-17 4 views
16

Я выполнил следующий график с ребрами, обработанными d3.svg.diagonal(). Тем не менее, когда я пытаюсь заменить диагональ на d3.svg.line(), она, похоже, не тянет данные цели и источника. Что мне не хватает? Я что-то не понимаю о d3.svg.line?D3: Подставляя d3.svg.diagonal() с d3.svg.line()

enter image description here

Ниже приведен код, который я имею в виду, а затем полный код:

var line = d3.svg.line() 
    .x(function(d) { return d.lx; }) 
    .y(function(d) { return d.ly; }); 

...

var link= svg.selectAll("path") 
    .data(links) 
    .enter().append("path") 
    .attr("d",d3.svg.diagonal()) 
    .attr("class", ".link") 
    .attr("stroke", "black") 
    .attr("stroke-width", "2px") 
    .attr("shape-rendering", "auto") 
    .attr("fill", "none"); 

Весь код:

var margin = {top: 20, right: 20, bottom: 20, left: 20}, 
    width =1500, 
    height = 1500, 
    diameter = Math.min(width, height), 
    radius = diameter/2; 


var balloon = d3.layout.balloon() 
    .size([width, height]) 
    .value(function(d) { return d.size; }) 
    .gap(50)     

var line = d3.svg.line() 
    .x(function(d) { return d.lx; }) 
    .y(function(d) { return d.ly; }); 


var svg = d3.select("body").append("svg") 
    .attr("width", width + margin.left + margin.right) 
    .attr("height", height + margin.top + margin.bottom) 
    .append("g") 
    .attr("transform", "translate(" + (margin.left + radius) + "," + (margin.top + radius) + ")") 

    root = "flare.json"; 
    root.y0 = height/2; 
    root.x0 = width/2; 

d3.json("flare.json", function(root) { 
    var nodes = balloon.nodes(root), 
     links = balloon.links(nodes); 


var link= svg.selectAll("path") 
    .data(links) 
    .enter().append("path") 
    .attr("d",d3.svg.diagonal()) 
    .attr("class", ".link") 
    .attr("stroke", "black") 
    .attr("stroke-width", "2px") 
    .attr("shape-rendering", "auto") 
    .attr("fill", "none"); 

    var node = svg.selectAll("g.node") 
    .data(nodes) 
    .enter() 
    .append("g") 
    .attr("class", "node"); 

    node.append("circle") 
     .attr("r", function(d) { return d.r; }) 
     .attr("cx", function(d) { return d.x; }) 
     .attr("cy", function(d) { return d.y; }); 

    node.append("text") 
     .attr("dx", function(d) { return d.x }) 
     .attr("dy", function(d) { return d.y }) 
     .attr("font-size", "5px") 
     .attr("fill", "white") 
     .style("text-anchor", function(d) { return d.children ? "middle" : "middle"; }) 
     .text(function(d) { return d.name; }) 
}); 

Сравнение того, как атрибут d svg исчезает при использовании «строки». enter image description here enter image description here

+0

Вы, кажется, не использовать 'line' где-нибудь в

Вы должны обернуть его в другой функции, как это код. Атрибут 'd' пути все еще задается с помощью' d3.svg.diagonal'. –

+0

Да, но когда я подставляю «строку» для «d3.svg.diagonal()» 0, это нарушает vis. Не могу понять, почему. –

+0

Как это сломается? –

ответ

1

Просто установите атрибут ссылки d на линии:

.attr("d", line) 
+0

Да, но когда я подставляю «строку» для «d3.svg.diagonal()» 0, это нарушает vis. –

+0

Можете ли вы создать небольшой пример на jsFiddle? –

+0

Я пробовал, но исходный код с макетом шара находится на github, и он, похоже, не принимает его. –

1

У меня была такая же проблема ... Там в jsFiddle here.

Обратите внимание, что смена line на diagonal заставит его работать.

+0

Мое предложение было бы написать код от jsFiddle здесь, так как он не всегда надежный и до. Тогда конкретный ответ будет доступен в этом ответе без необходимости перехода на внешний веб-сайт. – Taryn

+1

@mobeets Вы должны передать правильный ввод в 'line()'. Вы можете сделать эту оболочку 'line()' на другой функции как recomend @ elusive-code или вернуться к 'line()' правильные входные значения, как вы можете видеть на [мой мод вашей скрипки] (http: // jsfiddle. нетто/qsEbd/213 /). – jkutianski

2

Возможно герметизирующего диагональную функцию и редактирования его параметров может работать для вас:

var diagonal = d3.svg.diagonal(); 
var new_diagonal = function (obj, a, b) { 
    //Here you may change the reference a bit. 
    var nobj = { 
     source : { 
      x: obj.source.x, 
      y: obj.source.y 
     }, 
     target : { 
      x: obj.target.x, 
      y: obj.target.y 
     } 
    } 
    return diagonal.apply(this, [nobj, a, b]); 
} 
var link= svg.selectAll("path") 
    .data(links) 
    .enter().append("path") 
    .attr("d",new_diagonal) 
    .attr("class", ".link") 
    .attr("stroke", "black") 
    .attr("stroke-width", "2px") 
    .attr("shape-rendering", "auto") 
    .attr("fill", "none"); 
21

Вопрос довольно устаревшей, но так как я не вижу ответа, и кто-то может столкнуться с той же проблемой, здесь ,

Причина простая замена диагонального с линии не работает, потому что d3.svg.line и d3.svg.diagonal различных результатов:

  • d3. svg.diagonal возвращает функцию, которая принимает значение и его индекс и преобразует его в путь с использованием проекции. Другими словами diagonal.projection определяет, как функция получит координаты точек из предоставленной базы данных.
  • d3.svg.line возвращает функцию, которая принимает массив точек линии и преобразует ее в путь. Методы line.x и line.y определяют как координаты точки полученной из одного элемента массива прилагаемого

D3 SVG-Shapes reference

SVG Paths and D3.js

Таким образом, вы не можете использовать результат из d3.svg.line непосредственно в вариантах d3 (по крайней мере, когда вы хотите нарисовать несколько строк). mobeets разместил

var line = d3.svg.line() 
       .x(function(point) { return point.lx; }) 
       .y(function(point) { return point.ly; }); 

function lineData(d){ 
    // i'm assuming here that supplied datum 
    // is a link between 'source' and 'target' 
    var points = [ 
     {lx: d.source.x, ly: d.source.y}, 
     {lx: d.target.x, ly: d.target.y} 
    ]; 
    return line(points); 
} 

// usage: 
var link= svg.selectAll("path") 
    .data(links) 
    .enter().append("path") 
    .attr("d",lineData) 
    .attr("class", ".link") 
    .attr("stroke", "black") 
    .attr("stroke-width", "2px") 
    .attr("shape-rendering", "auto") 
    .attr("fill", "none"); 

Вот рабочая версия jsFiddle:: jsFiddle

+1

Я думаю, что '.attr (" d ", function (d) {return line ([{lx: d.target.x, ly: d.target.y}, {lx: d.source.x, ly : d.source.y}]);}); ' - лучший способ сделать это вместо wrap' line() 'в глобальной функции. – jkutianski

+0

Дополнительные пункты для обеспечения замены на «диагональ» для этого контекста, неуловимого кода, а не предоставления альтернативного решения. Это больше, чем через полтора года, и, как вы сказали, «кто-то может столкнуться с той же проблемой» (я). Я не нашел это решение в такой простой форме нигде, и наверняка найдутся некоторые люди, которые хотят его когда-нибудь. – Mars

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