d3.select("#exportit").on("click", generateit); function generateit(){ var data = ''; var circles = svg.selectAll("circle"); var json_circles = JSON.stringify(circles.data()); data += 'var jsonCircles = '+json_circles+';<br><br>'; var lines = svg.selectAll(".line"); var json_lines = JSON.stringify(lines.data()); data += 'var jsonLines = '+json_lines+';'; d3.select("#console").html(data); } var width = 500, height = 500; var svg = d3.select("#d3").append("svg") .attr("width", width) .attr("height", height); var rect = svg.append("rect") .attr("width", "100%") .attr("height", "100%") .on("click",drawcircle) var drag = d3.behavior.drag() .origin(Object) .on("drag", function(){ dragmove(this); }) var line = d3.svg.line() .x(function(d) { return d.x; }) .y(function(d) { return d.y; }) .interpolate("basis"); function dragmove(dragged) { var x = d3.select(dragged).attr("cx"); var y = d3.select(dragged).attr("cy"); var cradius = d3.select(dragged).attr("r"); var cx = Math.min(width,+x + d3.event.dx); var cy = Math.min(height,+y + d3.event.dy); var draggedCircles = [{ "x": cx, "y": cy, "radius": cradius }]; d3.select(dragged) .data(draggedCircles) .attr("cx", function (d) { return d.x; }) .attr("cy", function (d) { return d.y; }); //move text when other things move d3.select(dragged.nextSibling) .attr('x', cx) .attr('y', cy+4) redrawlines(); } function redrawlines() { var circles = svg.selectAll("circle"); var obj = []; for (a = 0; a < circles[0].length; a++) { if(a > 0){ var x1 = circles[0][a-1].attributes.cx.value; var y1 = circles[0][a-1].attributes.cy.value; var x2 = circles[0][a].attributes.cx.value; var y2 = circles[0][a].attributes.cy.value; var linearr = [{x:x1,y:y1},{x:x2,y:y2}]; obj.push(linearr); } } d3.selectAll(".line") .data(obj) .attr("d", line); } function drawcircle(d,i) { //get mouse coords var x = d3.mouse(this)[0]; var y = d3.mouse(this)[1]; //lets do it with data instead of manual above var jsonCircles = [{ "x": x, "y": y, "radius": 10 }]; var count = svg.selectAll("circle")[0].length; var g = svg.append("g"); g.append("circle") .data(jsonCircles) .attr("class", "circle") .attr("cx", function (d) { return d.x; }) .attr("cy", function (d) { return d.y; }) .attr("r", function (d) { return d.radius; }) .call(drag); //drag magic - built in d3 behavior: https://github.com/mbostock/d3/wiki/Drag-Behavior#wiki-drag g.append('svg:text') .attr('x', x) .attr('y', y+4) .attr('class', 'id') .text(count); //if this is first cicle, do not draw lines var circles = svg.selectAll("circle"); if(circles[0].length > 1){ var x1 = circles[0][circles[0].length-1].attributes.cx.value; var y1 = circles[0][circles[0].length-1].attributes.cy.value; var x2 = circles[0][circles[0].length-2].attributes.cx.value; var y2 = circles[0][circles[0].length-2].attributes.cy.value; var linearr = [{x:x1,y:y1},{x:x2,y:y2}]; svg.append("path") .data([linearr]) .attr("class", "line") .attr("d", line); } }
<div id="exportit">Export</div> <div id="d3"></div> <div id="console"></div>
#d3 svg{ fill:#fff; border:2px solid #000; } rect { cursor: crosshair; } .line{ stroke-width: 3px; fill:none; stroke: #000000; } .circle{ stroke-width: 1.5px; cursor:pointer; fill:green; } text { font: 12px sans-serif; pointer-events: none; } text.id { text-anchor: middle; font-weight: bold; } #exportit { background:#000; cursor:pointer; color:#fff; width:45px; padding:2px 4px; }