2016-10-12 2 views
-2

사용자가 주문에 따라 문자를 연결해야하는 테스트 작업을 설계하고 싶습니다. 예를 들어 connect (1) ~ (2)를 누른 다음 (2) ~ (3)을 입력하십시오.JSfiddle을 사용하여 연결된 그래프 작업

나는 JSfiddle을 사용하여 원을 만들었습니다. 새로 고침 할 때마다 서클의 위치가 바뀌며 특정 순서로 서클을 만들 수 있습니까?

(function() { 

var width = 900, 
    height = 650; 

var radius = 30; /* radius of circles */ 
var numCircles = 10; /* number of circles - you must update link source/target values to match changes in the number of circles */ 

var d3color = d3.interpolateRgb("#BAE4B3", "#006D2C"); /* color range for flow lines */ 

//A LIST OF LINKS BETWEEN CIRCLES 
var links = [ 
    { 
    source: 0, 
    target: 5, 
    strength: Math.round(Math.random() * 10)}, 
{ 
    source: 0, 
    target: 2, 
    strength: Math.round(Math.random() * 10)}, 
{ 
    source: 1, 
    target: 3, 
    strength: Math.round(Math.random() * 10)}, 
{ 
    source: 2, 
    target: 4, 
    strength: Math.round(Math.random() * 10)}, 
{ 
    source: 3, 
    target: 5, 
    strength: Math.round(Math.random() * 10)}, 
{ 
    source: 5, 
    target: 0, 
    strength: Math.round(Math.random() * 10)}, 
{ 
    source: 2, 
    target: 0, 
    strength: Math.round(Math.random() * 10)}, 
{ 
    source: 3, 
    target: 1, 
    strength: Math.round(Math.random() * 10)} 
]; 

function createDefs(defs) { 
    var dropShadowFilter = defs.append('svg:filter').attr('id', 'dropShadow'); 
    dropShadowFilter.append('svg:feGaussianBlur').attr('in', 'SourceAlpha').attr('stdDeviation', 1); 
    dropShadowFilter.append('svg:feOffset').attr('dx', 0).attr('dy', 1).attr('result', 'offsetblur'); 
    var feMerge = dropShadowFilter.append('svg:feMerge'); 
    feMerge.append('svg:feMergeNode'); 
    feMerge.append('svg:feMergeNode').attr('in', "SourceGraphic"); 
} 

var drag = d3.behavior.drag().origin(Object).on("drag", function() { 
    dragmove(this); 
}); 

//RANDOMLY GENERATE COORDINATES FOR CIRCLES 
var circles = d3.range(numCircles).map(function(i, d) { 
    return [Math.round(50 + (i/numCircles) * (width - 50)), Math.round(30 + Math.random() * (height - 80))]; 
}); 

//GLOBAL STRENGTH SCALE 
var strength_scale = d3.scale.linear().range([2, 10]) /* thickness range for flow lines */ 
.domain([0, d3.max(links, function(d) { 
    return d.strength; 
})]); 

var color_scale = d3.scale.linear().range([0, 1]).domain([0, d3.max(links, function(d) { 
    return d.strength; 
})]); 

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

var g_lines = svg.append("g").attr("class", "lines"); 
var g_circles = svg.append("g").attr("class", "circles"); 
var g_midpoints = svg.append("g").attr("class", "midpoints"); 

//SHADOW DEFINITION 
createDefs(svg.append('svg:defs')); 

$.each(circles, function(i, d) { 
    g_circles.append("circle").attr('filter', 'url(#dropShadow)').attr("class", "circle").attr("id", "circle" + i).attr("r", radius).attr("cx", d[0]).attr("cy", d[1]).call(drag); 
}); 

g_lines.selectAll(".link_line").data(links).enter().append("path").attr("class", "link_line").attr("fill", function(d) { 
    return d3color(color_scale(d.strength)); 
}).attr("id", function(i, d) { 
    return "link_line" + d; 
}).attr("d", function(d) { 
    return drawCurve(d); 
}); 

function dragmove(dragged) { 
    var x = d3.select(dragged).attr("cx"); 
    var y = d3.select(dragged).attr("cy"); 
    d3.select(dragged).attr("cx", Math.max(radius, Math.min(width - radius, +x + d3.event.dx))).attr("cy", Math.max(radius, Math.min(height - radius, +y + d3.event.dy))); 
    $.each(links, function(i, link) { 
     if (link.source == dragged.id.match(/\d+/)[0] || link.target == dragged.id.match(/\d+/)[0]) { 
      d3.select('#link_line' + i).attr("d", function(d) { 
       return drawCurve(d); 
      }); 
     } 
    }); 
} 

function drawCurve(d) { 
    var slope = Math.atan2((+d3.select('#circle' + d.target).attr("cy") - d3.select('#circle' + d.source).attr("cy")), (+d3.select('#circle' + d.target).attr("cx") - d3.select('#circle' + d.source).attr("cx"))); 
    var slopePlus90 = Math.atan2((+d3.select('#circle' + d.target).attr("cy") - d3.select('#circle' + d.source).attr("cy")), (+d3.select('#circle' + d.target).attr("cx") - d3.select('#circle' + d.source).attr("cx"))) + (Math.PI/2); 

    var sourceX = +d3.select('#circle' + d.source).attr("cx"); 
    var sourceY = +d3.select('#circle' + d.source).attr("cy"); 
    var targetX = +d3.select('#circle' + d.target).attr("cx"); 
    var targetY = +d3.select('#circle' + d.target).attr("cy"); 

    var arrowOffset = 20; 
    var points = []; 
    points.push([sourceX + radius * Math.cos(slope) - strength_scale(d.strength) * Math.cos(slopePlus90), sourceY + radius * Math.sin(slope) - strength_scale(d.strength) * Math.sin(slopePlus90)]); 
    points.push([sourceX + radius * Math.cos(slope), sourceY + radius * Math.sin(slope)]); 
    points.push([targetX - radius * Math.cos(slope), targetY - radius * Math.sin(slope)]); 
    points.push([targetX - (radius + arrowOffset) * Math.cos(slope) - strength_scale(d.strength + (arrowOffset/2)) * Math.cos(slopePlus90), targetY - (radius + arrowOffset) * Math.sin(slope) - strength_scale(d.strength + (arrowOffset/2)) * Math.sin(slopePlus90)]); 
    points.push([targetX - (radius + arrowOffset) * Math.cos(slope) - strength_scale(d.strength) * Math.cos(slopePlus90), targetY - (radius + arrowOffset) * Math.sin(slope) - strength_scale(d.strength) * Math.sin(slopePlus90)]); 
    return d3LineLinear(points) + "Z"; 
} 
})(); 
+0

정 이제 우리가 얘기하는 것 때문에 또한, 태그를 업데이트하십시오 질문을 업데이트했는지, 좋은 –

+0

안녕 @tofi입니다 자바 스크립트 문제 (즉, 파이썬이나 자바가 아니라)에 대해 더 이상 :) – fresskoma

답변

0

정 시각화에 대한 좋은 선택지이며, 또한 내가 또한 일반적으로 상당히 것으로 나타났습니다 등, 재배 선, 임의 그래프 작성을위한 몇 가지 다른 메커니즘을 포함하여 가능한 그래프 알고리즘, 상당히 좋은 세트가 있습니다 확장이 용이하고 필요할 때 적용 할 수 있습니다.

또는 JGraphT, 간단하면서도 강력한 API :

UndirectedGraph<String, DefaultEdge> g = 
    new SimpleGraph<String, DefaultEdge>(DefaultEdge.class); 

String v1 = "v1"; 
String v2 = "v2"; 
String v3 = "v3"; 
String v4 = "v4"; 

// add the vertices 
g.addVertex(v1); 
g.addVertex(v2); 
g.addVertex(v3); 
g.addVertex(v4); 

// add edges to create a circuit 
g.addEdge(v1, v2); 
g.addEdge(v2, v3); 
g.addEdge(v3, v4); 
g.addEdge(v4, v1);