Loving d3js, such a fun library! Got inspiration from this: https://github.com/mbostock/d3/wiki/Force-Layout
A Pen by Choon Ken Ding on CodePen.
Loving d3js, such a fun library! Got inspiration from this: https://github.com/mbostock/d3/wiki/Force-Layout
A Pen by Choon Ken Ding on CodePen.
<html> | |
<head> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script> | |
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css"> | |
</head> | |
<body> | |
<div class="container"> | |
<form role="form"> | |
<div class="row"> | |
<div class="col-lg-5 col-lg-offset-2"> | |
<div class="form-group"> | |
<h1><span class="glyphicon glyphicon-tower"></span> Map your ideas!</h1> | |
<label for="nodeParent" class="col-lg-4">Parent Idea</label> | |
<div class="col-lg-8"> | |
<select class="form-control" id="nodeParent"></select> | |
</div><!-- /.col-lg-8 --> | |
</div><!--/.form-group --> | |
<div class="form-group"> | |
<label for="nodeEntry" class="col-lg-4">Baby Idea</label> | |
<div class="col-lg-8"> | |
<input type="text" id="nodeEntry" class="form-control" placeholder="Begin world domination" /> | |
</div><!-- /.col-lg-8 --> | |
</div><!--/.form-group --> | |
<label for="nodeDesc" class="col-lg-4">Description</label> | |
<div class="col-lg-8"> | |
<textarea id="nodeDesc" class="form-control" row="3" placeholder="Description of world domination"></textarea> | |
</div><!-- /.col-lg-8 --> | |
<div class="col-lg-offset-4 col-lg-8"> | |
<button class="btn btn-success btn-lg" type="button" id="nodeBtn"><span class="glyphicon glyphicon-globe"></span> Go!</button> | |
</div><!-- /.form-group --> | |
</div><!-- /.col-lg-5 --> | |
<div class="col-lg-5"> | |
<div id="ideaDisplay"></div> | |
<div id="descDisplay"></div> | |
</div> | |
</div><!-- /.row --> | |
</form> | |
</div><!-- /.container --> | |
<!-- Including jQuery and bootstrap libraries --> | |
<script src="http://code.jquery.com/jquery-1.10.1.min.js"></script> | |
<script src="//netdna.bootstrapcdn.com/bootstrap/3.0.0/js/bootstrap.min.js"></script> | |
</body> | |
</html> |
Loving d3js, such a fun library! Got inspiration from this: https://github.com/mbostock/d3/wiki/Force-Layout
A Pen by Choon Ken Ding on CodePen.
var ideas = []; | |
var ideaLinks = []; | |
// Creating a quick Hashmap | |
var map = {}; | |
// D3js part | |
var width = 960; | |
var height = 500; | |
var svg = d3.select("body").append("svg") | |
.attr("width", width) | |
.attr("height", height); | |
var force = d3.layout.force() | |
.nodes(ideas) | |
.links(ideaLinks) | |
.charge(-400) | |
.linkDistance(50) | |
.size([width, height]); | |
var node = svg.selectAll(".node"); | |
var link = svg.selectAll(".link"); | |
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;}); | |
}); | |
function start(){ | |
link = link.data(force.links()); | |
link.enter().insert("line",".node").attr("class","link"); | |
node = node.data(force.nodes()); | |
node.enter().append("circle").attr("r",8) | |
.on("mouseover",mouseover) | |
.on("mouseout",mouseout) | |
.call(force.drag); | |
node.append("title").text(function(d){return d.node}); | |
//node.on("mouseover",mouseover) | |
//.call(force.drag); | |
force.start(); | |
} | |
// Creating events | |
$('#nodeBtn').click(function(){ | |
var idea = $('#nodeEntry').val(); | |
var desc = $('#nodeDesc').val(); | |
var parent = $('#nodeParent').val(); | |
ideas.push({"node":idea,"desc":desc}); | |
if(map[idea] == null){ | |
map[idea] = ideas.length - 1; | |
} | |
if(parent != null && parent != "No Parent"){ | |
ideaLinks.push({"source":map[parent],"target":map[idea],value:5}); | |
}else if(parent == null){ | |
$('#nodeParent').append('<option>No Parent</option>'); | |
} | |
$('#nodeParent').append('<option>'+idea+'</option>'); | |
start(); | |
}); | |
function mouseover(d) { | |
d3.select(this).transition() | |
.duration(750) | |
.attr("r", 16) | |
.style("fill","#2ca02c"); | |
d3.select("#ideaDisplay").text(d.node).attr("class","well animated fadeInLeft"); | |
d3.select("#descDisplay").text(d.desc).attr("class","well animated fadeInLeft"); | |
} | |
function mouseout() { | |
d3.select(this).transition() | |
.duration(750) | |
.attr("r", 8) | |
.style("fill","#000"); | |
d3.select("#ideaDisplay").text("") | |
.attr("class","animated fadeOutRight"); | |
d3.select("#descDisplay").text("").attr("class","animated fadeOutRight"); | |
} | |
body{ | |
padding-top:20px; | |
} | |
div{ | |
padding-bottom:5px; | |
} | |
#ideaDisplay{ | |
font-size:16px; | |
font-weight:bold; | |
} | |
#descDisplay{ | |
font-size:12px; | |
} | |
.node { | |
stroke: #fff; | |
stroke-width: 3.5px; | |
} | |
.link { | |
stroke: #999; | |
stroke-opacity: .6; | |
} | |
/** animate.css **/ | |
.animated{-webkit-animation-fill-mode:both;-moz-animation-fill-mode:both;-ms-animation-fill-mode:both;-o-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-duration:1s;-moz-animation-duration:1s;-ms-animation-duration:1s;-o-animation-duration:1s;animation-duration:1s;}.animated.hinge{-webkit-animation-duration:1s;-moz-animation-duration:1s;-ms-animation-duration:1s;-o-animation-duration:1s;animation-duration:1s;}@-webkit-keyframes fadeInLeft { | |
0% { | |
opacity: 0; | |
-webkit-transform: translateX(-20px); | |
} 100% { | |
opacity: 1; | |
-webkit-transform: translateX(0); | |
} | |
} | |
@-moz-keyframes fadeInLeft { | |
0% { | |
opacity: 0; | |
-moz-transform: translateX(-20px); | |
} | |
100% { | |
opacity: 1; | |
-moz-transform: translateX(0); | |
} | |
} | |
@-o-keyframes fadeInLeft { | |
0% { | |
opacity: 0; | |
-o-transform: translateX(-20px); | |
} | |
100% { | |
opacity: 1; | |
-o-transform: translateX(0); | |
} | |
} | |
@keyframes fadeInLeft { | |
0% { | |
opacity: 0; | |
transform: translateX(-20px); | |
} | |
100% { | |
opacity: 1; | |
transform: translateX(0); | |
} | |
} | |
.fadeInLeft { | |
-webkit-animation-name: fadeInLeft; | |
-moz-animation-name: fadeInLeft; | |
-o-animation-name: fadeInLeft; | |
animation-name: fadeInLeft; | |
} | |
@-webkit-keyframes fadeOutRight { | |
0% { | |
opacity: 1; | |
-webkit-transform: translateX(0); | |
} | |
100% { | |
opacity: 0; | |
-webkit-transform: translateX(20px); | |
} | |
} | |
@-moz-keyframes fadeOutRight { | |
0% { | |
opacity: 1; | |
-moz-transform: translateX(0); | |
} | |
100% { | |
opacity: 0; | |
-moz-transform: translateX(20px); | |
} | |
} | |
@-o-keyframes fadeOutRight { | |
0% { | |
opacity: 1; | |
-o-transform: translateX(0); | |
} | |
100% { | |
opacity: 0; | |
-o-transform: translateX(20px); | |
} | |
} | |
@keyframes fadeOutRight { | |
0% { | |
opacity: 1; | |
transform: translateX(0); | |
} | |
100% { | |
opacity: 0; | |
transform: translateX(20px); | |
} | |
} | |
.fadeOutRight { | |
-webkit-animation-name: fadeOutRight; | |
-moz-animation-name: fadeOutRight; | |
-o-animation-name: fadeOutRight; | |
animation-name: fadeOutRight; | |
} |