Created
February 6, 2017 03:05
-
-
Save SergProduction/33d019c9c47713ead345e2f92136aa95 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous"> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.4.3/d3.js"></script> | |
<style> | |
svg line{ | |
stroke: grey; | |
stroke-width: 2; | |
} | |
svg path{ | |
stroke: #808080; | |
stroke-width: 2; | |
fill: none; | |
} | |
.Node{ | |
border: 1px solid #b00082; | |
border-radius: 5px; | |
} | |
ul{ | |
margin: 0; | |
padding: 0 5px; | |
list-style-type: none; | |
} | |
li{ | |
border-bottom: 1px solid #000; | |
} | |
.node-head{ | |
width: 100%; | |
background: #b00082; | |
height: 25px; | |
color: #fff; | |
padding: 0 0 0 5px; | |
text-align: center; | |
} | |
</style> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var width = document.documentElement.clientWidth - 100, | |
height = document.documentElement.clientHeight - 100; | |
var paths = []; | |
var addNodeButt = d3.select("body").append('button') | |
.text('add Node') | |
var nodeNameInput = d3.select("body").append('input') | |
.attr('type','text') | |
.attr('placeholder','name Node') | |
d3.select("body").append('br') | |
var svg = d3.select("body").append("svg"); | |
svg.attr("height", height) | |
.attr("width", width) | |
.style('border','1px solid #ddd') | |
// функция, создающая по массиву точек линии | |
var line = d3.line() | |
.x( d => d.x ) | |
.y( d => d.y ) | |
.curve(d3.curveCatmullRom.alpha(1)) | |
addNodeButt.on('click', function(data, i){ | |
addNode() | |
}) | |
function addNode(){ | |
var nodeName = nodeNameInput.property('value') | |
nodeNameInput.property('value', '') | |
paths.push({id: nodeName}) | |
var fo = svg.append('foreignObject') | |
.attr('x', 20) | |
.attr('y', 20) | |
.attr('width', 120) | |
.attr('height', 200) | |
.attr('class', 'Node') | |
var body = fo.append('xhtml:body') | |
var head = body.append('div') | |
.classed('node-head', true) | |
head.call( | |
d3.drag() | |
.subject(differencePosition) | |
.container( () => svg.node() ) | |
.filter( () => d3.event.target == head.node() ) | |
.on('start', moveNode) | |
) | |
function differencePosition(){ | |
var x = parseInt( fo.attr('x') ) | |
var y = parseInt( fo.attr('y') ) | |
return {x,y} | |
} | |
function moveNode(){ | |
console.log(d3.event) | |
var {x, y} = d3.event.subject | |
var x1 = ( d3.event.x - x ); | |
var y1 = ( d3.event.y - y ); | |
id = paths.findIndex( el => el.id == nodeName ) | |
if( paths[ id ].sigin ){ | |
var parentId = paths[ id ].sigin; | |
parentId = paths.findIndex( el => el.id == parentId ) | |
var data = paths[ parentId ].data; | |
var d2x = data[ 2 ].x - d3.event.x | |
var d2y = data[ 2 ].y - d3.event.y | |
var d3x = data[ 3 ].x - d3.event.x | |
var d3y = data[ 3 ].y - d3.event.y | |
} | |
if( paths[ id ].data ){ | |
var data = paths[ id ].data | |
var d0x = data[ 0 ].x - d3.event.x | |
var d0y = data[ 0 ].y - d3.event.y | |
var d1x = data[ 1 ].x - d3.event.x | |
var d1y = data[ 1 ].y - d3.event.y | |
} | |
d3.event.on('drag', () => { | |
var x2 = x1 + d3.event.x | |
var y2 = y1 + d3.event.y | |
fo.attr('x', x2 ) | |
.attr('y', y2 ) | |
if( paths[ id ].sigin ){ | |
var parentId = paths[ id ].sigin; | |
parentId = paths.findIndex( el => el.id == parentId ) | |
var data = paths[ parentId ].data; | |
data[ 2 ] = {x: d2x + d3.event.x, y: d2y + d3.event.y} | |
data[ 3 ] = {x: d3x + d3.event.x, y: d3y + d3.event.y} | |
var path = paths[ parentId ].path | |
path.attr('d', line(data) ) | |
} | |
if( paths[ id ].data ){ | |
var data = paths[ id ].data | |
data[ 0 ] = {x: d0x + d3.event.x, y: d0y + d3.event.y} | |
data[ 1 ] = {x: d1x + d3.event.x, y: d1y + d3.event.y} | |
var path = paths[ id ].path | |
path.attr('d', line(data) ) | |
} | |
}); | |
} | |
head.text( nodeName ) | |
var sigin = head.append('span') | |
.classed('glyphicon glyphicon-log-in', true) | |
.attr('data-in',nodeName) | |
.style('float','left') | |
.style('margin','3px 5px 0 0'); | |
var add = head.append('span') | |
.classed('glyphicon glyphicon-plus-sign', true) | |
.style('color', '#fff') | |
.style('margin', '5px') | |
.style('float', 'right') | |
var input = body.append('input') | |
.attr('type', 'text') | |
.attr('placeholder','name line') | |
.style('width', '100%') | |
.style('border-width', '0 0 1px 0') | |
.style('padding', '0 5px') | |
add.on('click', () => { | |
if( !input.property('value') ) return | |
var li = ul.append('li') | |
.text(input.property('value')) | |
input.property('value', '') | |
var addCurve = li.append('span') | |
.classed('glyphicon glyphicon-log-out', true) | |
.style('float','right') | |
.style('margin-top','3px'); | |
addCurve.call(d3.drag() | |
.container( () => svg.node() ) | |
.on('start', newConnect )) | |
function newConnect(){ | |
var data = [ | |
{ | |
x: d3.event.x, | |
y: d3.event.y | |
}, | |
{ | |
x: d3.event.x + 40, | |
y: d3.event.y | |
}, | |
{ | |
x: d3.event.x + 40, | |
y: d3.event.y | |
}, | |
{ | |
x: d3.event.x + 40, | |
y: d3.event.y | |
}] | |
id = paths.findIndex((el) => el.id == nodeName) | |
paths[ id ].data = data | |
var active = svg.append('path') | |
.attr('d', line(data) ) | |
d3.event.on('drag', () => { | |
data[ 2 ] = {x: d3.event.x - 40, y: d3.event.y} | |
data[ 3 ] = {x: d3.event.x, y: d3.event.y} | |
active.attr('d', line(data) ) | |
}) | |
d3.event.on('end', () => { | |
var data; | |
var source = d3.select( d3.event.sourceEvent.target ) | |
if( source.attr('data-in') ){ | |
var child = paths.findIndex( el => el.id == source.attr('data-in') ) | |
paths[ child ].sigin = nodeName | |
paths[ id ].path = active | |
} | |
else{ | |
delete paths[ id ].data | |
active.remove() | |
} | |
}) | |
} | |
}) | |
var ul = body.append('ul') | |
} |
Author
SergProduction
commented
Feb 6, 2017
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment