Skip to content

Instantly share code, notes, and snippets.

@michaelcolenso
Last active October 17, 2015 09:17
Show Gist options
  • Save michaelcolenso/4fe1c66b45136458d8b0 to your computer and use it in GitHub Desktop.
Save michaelcolenso/4fe1c66b45136458d8b0 to your computer and use it in GitHub Desktop.
<!DOCTYPE html>
<meta charset="utf-8">
<head>
<style>
.node {
stroke: #000;
stroke-width: 1.5px;
}
.link {
stroke: #999;
stroke-width: 1.5px;
}
body {
background: #fff;
}
.node {
cursor: pointer;
}
.node circle {
/*fill: #fff;
stroke: steelblue;*/
stroke-width: 3px;
}
.node text {
font: 16px sans-serif;
fill: #777;
}
.link {
fill: none;
stroke: #ccc;
stroke-width: 2px;
}
.tree {
margin-bottom: 10px;
overflow: auto;
}
#test .arc2 {
stroke-weight: 0.1;
fill: #3660b0;
}
#outer {
background: #fff;
border-radius: 5px;
color: #000;
}
#div1,
#div2,
#div3,
#div4 {
width: 33%;
height: auto;
box-sizing: border-box;
float: left;
}
#div2 .arc {
stroke-weight: 0.1;
fill: #f0a417;
}
#div2 .arc2 {
stroke-weight: 0.1;
fill: #b00d08;
}
#div3 .arc {
stroke-weight: 0.1;
fill: #1d871b;
}
.selectedRadial {
border-radius: 3px;
background: #f4f4f4;
color: #000;
box-shadow: 0 1px 5px rgba(0, 0, 0, 0.4);
-moz-box-shadow: 0 1px 5px rgba(0, 0, 0, 0.4);
border: 1px solid rgba(200, 200, 200, 0.85);
}
.radial {
border-radius: 3px;
background: #FFFFFF;
color: #000;
}
.background {
fill: #FFFFFF;
fill-opacity: 1;
}
.component {
fill: #e1e1e1;
}
.component .label {
font-family: Myriad, "Helvetic Neue", Helvetica, Arial;
text-anchor: middle;
fill: #000;
}
.arc {
stroke-weight: 0.1;
fill: #4e8fff;
}
.arc2 {
stroke-weight: 0.1;
fill: #3660b0;
}
.label {
font-family: Myriad, "Helvetic Neue", Helvetica, Arial;
text-anchor: middle;
}
.radial-svg {
display: block;
margin: 0 auto;
}
</style>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.6/d3.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
</head>
<body>
<div id="forest">
<div id="tree"></div>
<div id='outer'>
<div id="main">
<div id="div1"></div>
<div id="div2"></div>
<div id="div3"></div>
<div id="div4"></div>
</div>
</div>
</div>
<script>
//build tree
function BuildVerticaLTree(treeData, treeContainerDom) {
var margin = {
top: 90,
right: 120,
bottom: 20,
left: 120
};
var width = 960 - margin.right - margin.left;
var height = 500 - margin.top - margin.bottom;
var i = 0;
var duration = 1000;
var tree = d3.layout.tree()
.size([height, width]);
var diagonal = d3.svg.diagonal()
.projection(function(d) {
return [d.x, d.y];
});
var svg = d3.select(treeContainerDom).append("svg")
.attr("width", width + margin.right + margin.left)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
root = treeData;
update(root);
function update(source) {
start();
// Compute the new tree layout.
var nodes = tree.nodes(root).reverse(),
links = tree.links(nodes);
// Normalize for fixed-depth.
nodes.forEach(function(d) {
d.y = d.depth * 100;
});
// Declare the nodes…
var node = svg.selectAll("g.node")
.data(nodes, function(d) {
return d.id || (d.id = ++i);
});
// Enter the nodes.
var nodeEnter = node.enter().append("g")
.attr("class", "node")
.attr("transform", function(d) {
return "translate(" + source.x0 + "," + source.y0 + ")";
}).on("click", nodeclick);
nodeEnter.append("circle")
.attr("r", 2)
.attr("stroke", function(d) {
return d.children || d._children ? "steelblue" : "#00c13f";
})
.style("fill", function(d) {
return d.children || d._children ? "lightsteelblue" : "#fff";
});
nodeEnter.append("text")
.attr("y", function(d) {
return d.children || d._children ? -20 : 20;
})
.attr("dy", ".39em")
.attr("text-anchor", "middle")
.text(function(d) {
return d.name;
})
.style("fill-opacity", "0.1");
// Transition nodes to their new position.
//horizontal tree
var nodeUpdate = node.transition()
.duration(duration)
.attr("transform", function(d) {
return "translate(" + d.x + "," + d.y + ")";
});
nodeUpdate.select("circle")
.attr("r", 8)
.style("fill", function(d) {
return d._children ? "lightsteelblue" : "#fff";
});
nodeUpdate.select("text")
.style("fill-opacity", .8);
// Transition exiting nodes to the parent's new position.
var nodeExit = node.exit().transition()
.duration(duration)
.attr("transform", function(d) {
return "translate(" + source.x + "," + source.y + ")";
})
.remove();
nodeExit.select("circle")
.attr("r", 1e-6);
nodeExit.select("text")
.style("fill-opacity", 1e-6);
// Update the links…
// Declare the links…
var link = svg.selectAll("path.link")
.data(links, function(d) {
return d.target.id;
});
// Enter the links.
link.enter().insert("path", "g")
.attr("class", "link")
.attr("d", function(d) {
var o = {
x: source.x0,
y: source.y0
};
return diagonal({
source: o,
target: o
});
});
// Transition links to their new position.
link.transition()
.duration(duration)
.attr("d", diagonal);
// Transition exiting nodes to the parent's new position.
link.exit().transition()
.duration(duration)
.attr("d", function(d) {
var o = {
x: source.x,
y: source.y
};
return diagonal({
source: o,
target: o
});
})
.remove();
// Stash the old positions for transition.
nodes.forEach(function(d) {
d.x0 = d.x;
d.y0 = d.y;
});
}
// Toggle children on click.
function nodeclick(d) {
if (d.children) {
d._children = d.children;
d.children = null;
} else {
d.children = d._children;
d._children = null;
}
update(d);
}
}
var treeData = {
"name": "BELOVED PARENT",
"children": [{
"name": "SON",
"children": [{
"name": "grandchild",
"children": [{
"name": "great-grandchild"
}]
}, {
"name": "grandchild",
"children": []
}]
}, {
"name": "DAUGHTER",
"children": []
}]
};
BuildVerticaLTree(treeData, "#tree");
});
//tree-built
//begin-radial
var div1 = d3.select(document.getElementById('div1'));
var div2 = d3.select(document.getElementById('div2'));
var div3 = d3.select(document.getElementById('div3'));
var div4 = d3.select(document.getElementById('div4'));
function onClick1() {
deselect();
div1.attr("class", "selectedRadial");
}
function onClick2() {
deselect();
div2.attr("class", "selectedRadial");
}
function onClick3() {
deselect();
div3.attr("class", "selectedRadial");
}
function labelFunction(val, min, max) {
}
function deselect() {
div1.attr("class", "radial");
div2.attr("class", "radial");
div3.attr("class", "radial");
}
function start() {
var rp1 = radialProgress(document.getElementById('div1'))
.label("METRIC")
.onClick(onClick1)
.diameter(150)
.value(78)
.render();
var rp2 = radialProgress(document.getElementById('div2'))
.label("SYNERGY")
.onClick(onClick2)
.diameter(150)
.value(160)
.render();
var rp3 = radialProgress(document.getElementById('div3'))
.label("STATISTIC")
.onClick(onClick3)
.diameter(150)
.minValue(100)
.maxValue(200)
.value(150)
.render();
}
function radialProgress(parent) {
var _data = null,
_duration = 700,
_selection,
_margin = {
top: 0,
right: 0,
bottom: 30,
left: 0
},
__width = 300,
__height = 300,
_diameter,
_label = "",
_fontSize = 10;
var _mouseClick;
var _value = 0,
_minValue = 0,
_maxValue = 100;
var _currentArc = 0,
_currentArc2 = 0,
_currentValue = 0;
var _arc = d3.svg.arc()
.startAngle(0 * (Math.PI / 180)); //just radians
var _arc2 = d3.svg.arc()
.startAngle(0 * (Math.PI / 180))
.endAngle(0); //just radians
_selection = d3.select(parent);
function component() {
_selection.each(function(data) {
// Select the svg element, if it exists.
var svg = d3.select(this).selectAll("svg").data([data]);
var enter = svg.enter().append("svg").attr("class", "radial-svg").append("g");
measure();
svg.attr("width", __width)
.attr("height", __height);
var background = enter.append("g").attr("class", "component")
.attr("cursor", "pointer")
.on("click", onMouseClick);
_arc.endAngle(360 * (Math.PI / 180))
background.append("rect")
.attr("class", "background")
.attr("width", _width)
.attr("height", _height);
background.append("path")
.attr("transform", "translate(" + _width / 2 + "," + _width / 2 + ")")
.attr("d", _arc);
background.append("text")
.attr("class", "label")
.attr("transform", "translate(" + _width / 2 + "," + (_width + _fontSize) + ")")
.text(_label);
var g = svg.select("g")
.attr("transform", "translate(" + _margin.left + "," + _margin.top + ")");
_arc.endAngle(_currentArc);
enter.append("g").attr("class", "arcs");
var path = svg.select(".arcs").selectAll(".arc").data(data);
path.enter().append("path")
.attr("class", "arc")
.attr("transform", "translate(" + _width / 2 + "," + _width / 2 + ")")
.attr("d", _arc);
//Another path in case we exceed 100%
var path2 = svg.select(".arcs").selectAll(".arc2").data(data);
path2.enter().append("path")
.attr("class", "arc2")
.attr("transform", "translate(" + _width / 2 + "," + _width / 2 + ")")
.attr("d", _arc2);
enter.append("g").attr("class", "labels");
var label = svg.select(".labels").selectAll(".label").data(data);
label.enter().append("text")
.attr("class", "label")
.attr("y", _width / 2 + _fontSize / 3)
.attr("x", _width / 2)
.attr("cursor", "pointer")
.attr("width", _width)
.text(function(d) {
return Math.round((_value - _minValue) / (_maxValue - _minValue) * 100) + "%"
})
.style("font-size", _fontSize + "px")
.on("click", onMouseClick);
path.exit().transition().duration(500).attr("x", 1000).remove();
layout(svg);
function layout(svg) {
var ratio = (_value - _minValue) / (_maxValue - _minValue);
var endAngle = Math.min(360 * ratio, 360);
endAngle = endAngle * Math.PI / 180;
path.datum(endAngle);
path.transition().duration(_duration)
.attrTween("d", arcTween);
if (ratio > 1) {
path2.datum(Math.min(360 * (ratio - 1), 360) * Math.PI / 180);
path2.transition().delay(_duration).duration(_duration)
.attrTween("d", arcTween2);
}
label.datum(Math.round(ratio * 100));
label.transition().duration(_duration)
.tween("text", labelTween);
}
});
function onMouseClick(d) {
if (typeof _mouseClick == "function") {
_mouseClick.call();
}
}
}
function labelTween(a) {
var i = d3.interpolate(_currentValue, a);
_currentValue = i(0);
return function(t) {
_currentValue = i(t);
this.textContent = Math.round(i(t)) + "%";
}
}
function arcTween(a) {
var i = d3.interpolate(_currentArc, a);
return function(t) {
_currentArc = i(t);
return _arc.endAngle(i(t))();
};
}
function arcTween2(a) {
var i = d3.interpolate(_currentArc2, a);
return function(t) {
return _arc2.endAngle(i(t))();
};
}
function measure() {
_width = _diameter - _margin.right - _margin.left - _margin.top - _margin.bottom;
_height = _width;
_fontSize = _width * .2;
_arc.outerRadius(_width / 2);
_arc.innerRadius(_width / 2 * .85);
_arc2.outerRadius(_width / 2 * .85);
_arc2.innerRadius(_width / 2 * .85 - (_width / 2 * .15));
}
component.render = function() {
measure();
component();
return component;
}
component.value = function(_) {
if (!arguments.length) return _value;
_value = [_];
_selection.datum([_value]);
return component;
}
component.margin = function(_) {
if (!arguments.length) return _margin;
_margin = _;
return component;
};
component.diameter = function(_) {
if (!arguments.length) return _diameter
_diameter = _;
return component;
};
component.minValue = function(_) {
if (!arguments.length) return _minValue;
_minValue = _;
return component;
};
component.maxValue = function(_) {
if (!arguments.length) return _maxValue;
_maxValue = _;
return component;
};
component.label = function(_) {
if (!arguments.length) return _label;
_label = _;
return component;
};
component._duration = function(_) {
if (!arguments.length) return _duration;
_duration = _;
return component;
};
component.onClick = function(_) {
if (!arguments.length) return _mouseClick;
_mouseClick = _;
return component;
}
return component;
//end-radial
</script>
</body>
</html>

node tree and radial progress meters

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment