2012-05-07 1 views
5

Уважаемые читатели. Я новичок в javascript, и я столкнулся с этой проблемой. Я пытаюсь реализовать измененную версию этой силы ориентированного графа:Настройка направленного графика D3

http://mbostock.github.com/d3/ex/force.html

данные JSON генерируется на лету из PHP-скрипта. Идея состоит в том, чтобы покрасить все линии, соединяющиеся с одним конкретным узлом (определенным в сценарии php) одним цветом, а все остальные - серыми. Я пытаюсь сделать это путем сопоставления исходной переменной в файле JSON в переменную из сценария PHP и изменить цвет, когда это так, как это:

var link = svg.selectAll("line.link") 
    .data(json.links) 
    .enter().append("line") 
    .attr("class", "link") 
    .style("stroke-width", function(d) { return Math.sqrt(d.value);}) 
    .style("stroke-opacity", function(d) { return d.value/10;}) 
    .style("stroke", function(d) { 
    x = (tested == d.source) ? return '#1f77b4' : '#707070';// <-- Attempt to change the color of the link when this is true. 
    }) 

однако это не работает. Скрипт работает нормально, но без изменения цвета, если я просто делаю это

var link = svg.selectAll("line.link") 
    .data(json.links) 
    .enter().append("line") 
    .attr("class", "link") 
    .style("stroke-width", function(d) { return Math.sqrt(d.value);}) 
    .style("stroke-opacity", function(d) { return d.value/10;}) 
    .style("stroke", function(d) { 
    return '#707070'; 
    }) 

Я смотрел на это в течение нескольких дней, пытаясь выяснить, чтобы это сделать, и я застрял. Любая помощь будет принята с благодарностью!

Вот мой полный сценарий

<script type="text/javascript"> 

var width = 1200, 
    height = 1200; 

var color = d3.scale.category20(); 

var tested=<?php echo $tested_source;?>; //<-- the variable from php 

var svg = d3.select("#chart").append("svg") 
    .attr("width", width) 
    .attr("height", height); 

d3.json("data.json", function(json) { 

var force = d3.layout.force() 
    .charge(-130) 
    .linkDistance(function(d) { return 500-(50*d.value);}) 
    .size([width, height]); 

    force 
     .nodes(json.nodes) 
     .links(json.links) 
     .start(); 

    var link = svg.selectAll("line.link") 
     .data(json.links) 
     .enter().append("line") 
     .attr("class", "link") 
     .style("stroke-width", function(d) { return Math.sqrt(d.value);}) 
     .style("stroke-opacity", function(d) { return d.value/10;}) 
     .style("stroke", function(d) { 
     x = (tested == d.source) ? return '#1f77b4' : '#707070'; //<-- Attempt to change the color of the link when this is true. But is is not working... :(
     }) 


    var node = svg.selectAll("circle.node") 
     .data(json.nodes) 
    .enter().append("circle") 
     .attr("class", "node") 
     .attr("r", 12) 
     .style("fill", function(d) { return color(d.group); }) 
     .call(force.drag); 

    node.append("title") 
     .text(function(d) { return d.name; }); 

    force.on("tick", function() { 
    link.attr("x1", function(d) { return d.source.x; }) 
     .attr("y1", function(d) { return d.source.y; }) 
     .attr("x2", function(d) { return d.target.x; }) 
     .attr("y2", function(d) { return d.target.y; }); 

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

</script> 

ответ

8

d.source является объектом, вы не можете использовать ==, чтобы определить, является ли tested аналогичный объект. Have a look at this answer for more details on object equality.

Если вы хотите протестировать определенное значение объекта d.source, описанного ниже, которое, как я предполагаю, вы хотите, вам нужно указать его.

Вот объектная архитектура источник: (я использую the example you pointed поэтому данные поступают из miserables.json)

source: Object 
    group: 4 
    index: 75 
    name: "Brujon" 
    px: 865.6440689638284 
    py: 751.3426708796574 
    weight: 7 
    x: 865.9584580575608 
    y: 751.2658636251376 

Теперь, вот сломанная деталь в вашем коде:

x = (tested == d.source) ? return '#1f77b4' : '#707070';// <-- Attempt to change the color of the link when this is true. 

Это не работает, потому что возвращение неуместно. Вы смешивания тройные и return заявления, но не положить их в правильном порядке:

return test ? value_if_true : value_if_false; 

если вы хотите присвоить значение х в любом случае, вы можете сделать

x = test ? value_if_true : value_if_false; 
return x; 

You должен сделать что-то вроде этого:

return (tested == d.source) ? '#1f77b4' : '#707070';// <-- Attempt to change the color of the link when this is true. 

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

return (tested === d.source.name) ? '#1f77b4' : '#707070'; 

Кроме того, если переменная из PHP является строка, которую вы должны сделать

var tested="<?php echo $tested_source;?>"; //<-- the variable from php 

и в большинстве случаев вы должны использовать json_encode на карте Переменные PHP в javascript.

В заключение я бы рекомендовал использовать console функции в сочетании с Firebug «консольной панели s, если вы используете Firefox или Chrome Developer Tool» консоли панели s, если вы используете браузер на основе Chromium. Это позволит вам легче отлаживать ваш код.


Рабочий код

var width = 960, 
    height = 500; 

var color = d3.scale.category20(); 

var force = d3.layout.force().charge(-120).linkDistance(30).size([width, height]); 

var svg = d3.select("#chart").append("svg").attr("width", width).attr("height", height); 

var tested = 20; 

d3.json("miserables.json", function (json) { 
    force.nodes(json.nodes).links(json.links).start(); 

    var link = svg.selectAll("line.link") 
    .data(json.links) 
    .enter() 
    .append("line") 
    .attr("class", "link") 
    .style("stroke-width", function (d) { 
    return Math.sqrt(d.value); 
    }).style("stroke-opacity", function (d) { 
    return d.value/10; 
    }).style("stroke", function (d) { 
    return (tested == d.source.index) ? '#ee3322' : '#707070'; //'#1f77b4' 
    }); 

    var node = svg.selectAll("circle.node") 
    .data(json.nodes) 
    .enter() 
    .append("circle") 
    .attr("class", "node") 
    .attr("r", 5) 
    .style("fill", function (d) { 
    return color(d.group); 
    }).call(force.drag); 

    node.append("title").text(function (d) { 
    return d.name; 
    }); 

    force.on("tick", function() { 
    link.attr("x1", function (d) { 
     return d.source.x; 
    }).attr("y1", function (d) { 
     return d.source.y; 
    }).attr("x2", function (d) { 
     return d.target.x; 
    }).attr("y2", function (d) { 
     return d.target.y; 
    }); 

    node.attr("cx", function (d) { 
     return d.x; 
    }).attr("cy", function (d) { 
     return d.y; 
    }); 
    }); 
}); 
+0

Спасибо! Я полный новичок, когда дело доходит до javascript. Предложение действительно делает скрипт работать, однако он по-прежнему не меняет цвет соединительных линий. Я думаю, что может возникнуть проблема с извлечением d.source из массива json. Помогите?? – user1378824

+0

Я отредактировал свой ответ с некоторым кодом относительно исходного объекта, который вы тестируете против 'test'. Я думаю, что проблема исходит оттуда. –

+0

Спасибо за быстрый ответ. Возможно, я что-то недопонимаю, но объект, о котором вы говорите, является узлом. Я пытаюсь изменить цвет соединительных линий между узлами. Это значение определено в «Связи» в файле miserables.json. Я что-то недопонимаю? – user1378824

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

  • Нет связанных вопросов^_^