Created
April 3, 2017 17:51
-
-
Save cnaithani/9a4622f837f409e0f7ebf06083b0f0d5 to your computer and use it in GitHub Desktop.
Programming Central - D3JS – Pie Chart - Part 3
This file contains 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
<style type="text/css"> | |
#chart text { | |
fill: black; | |
font: 10px sans-serif; | |
text-anchor: end; | |
} | |
.axis text { | |
font: 10px sans-serif; | |
} | |
.axis path, .axis line { | |
fill: none; | |
/*stroke: #fff;*/ | |
shape-rendering: crispEdges; | |
} | |
body { | |
/*background: #1a1a1a;*/ | |
color: #eaeaea; | |
padding: 10px; | |
} | |
path { | |
stroke: steelblue; | |
stroke-width: 2; | |
fill: none; | |
} | |
</style> | |
<div id="chart" style="height:600px;width:600px"> | |
<div class="innerCont" style="overflow: auto; top:100px; left: 400px; height:91% ; Width:100% ;position: relative;overflow: hidden;" /> | |
</div> | |
<script src="https://code.jquery.com/jquery-1.12.4.min.js" charset="utf-8"></script> | |
<script src="https://d3js.org/d3.v2.min.js"></script> | |
<script type="text/javascript"> | |
var salesData; | |
var chartInnerDiv = '<div class="innerCont" style="overflow: auto;top:100px; left: 400px; height:91% ; Width:100% ;position: relative;overflow: hidden;"/>'; | |
var truncLengh = 30; | |
$(document).ready(function () { | |
Plot(); | |
}); | |
function Plot() { | |
TransformChartData(chartData, chartOptions, 0); | |
BuildPie("chart", chartData, chartOptions, 0) | |
} | |
function BuildPie(id, chartData, options, level) { | |
var xVarName; | |
var divisionRatio = 2.5; | |
var legendoffset = (level == 0) ? 0 : -40; | |
d3.selectAll("#" + id + " .innerCont").remove(); | |
$("#" + id).append(chartInnerDiv); | |
chart = d3.select("#" + id + " .innerCont"); | |
var yVarName = options[0].yaxis; | |
width = $(chart[0]).outerWidth(), | |
height = $(chart[0]).outerHeight(), | |
radius = Math.min(width, height) / divisionRatio; | |
if (level == 1) { | |
xVarName = options[0].xaxisl1; | |
} | |
else { | |
xVarName = options[0].xaxis; | |
} | |
var rcolor = d3.scale.ordinal().range(runningColors); | |
arc = d3.svg.arc() | |
.outerRadius(radius) | |
.innerRadius(radius - 200); | |
var arcOver = d3.svg.arc().outerRadius(radius + 20).innerRadius(radius - 180); | |
chart = chart | |
.append("svg") //append svg element inside #chart | |
.attr("width", width) //set width | |
.attr("height", height) //set height | |
.append("g") | |
.attr("transform", "translate(" + (width / divisionRatio) + "," + ((height / divisionRatio) + 30) + ")"); | |
var pie = d3.layout.pie() | |
.sort(null) | |
.value(function (d) { | |
return d.Total; | |
}); | |
var g = chart.selectAll(".arc") | |
.data(pie(runningData)) | |
.enter().append("g") | |
.attr("class", "arc"); | |
var count = 0; | |
var path = g.append("path") | |
.attr("d", arc) | |
.attr("id", function (d) { return "arc-" + (count++); }) | |
.style("opacity", function (d) { | |
return d.data["op"]; | |
}); | |
path.on("mouseenter", function (d) { | |
d3.select(this) | |
.attr("stroke", "white") | |
.transition() | |
.duration(200) | |
.attr("d", arcOver) | |
.attr("stroke-width", 1); | |
}) | |
.on("mouseleave", function (d) { | |
d3.select(this).transition() | |
.duration(200) | |
.attr("d", arc) | |
.attr("stroke", "none"); | |
}) | |
.on("click", function (d) { | |
if (this._listenToEvents) { | |
// Reset inmediatelly | |
d3.select(this).attr("transform", "translate(0,0)") | |
// Change level on click if no transition has started | |
path.each(function () { | |
this._listenToEvents = false; | |
}); | |
} | |
d3.selectAll("#" + id + " svg").remove(); | |
if (level == 1) { | |
TransformChartData(chartData, options, 0, d.data[xVarName]); | |
BuildPie(id, chartData, options, 0); | |
} | |
else { | |
var nonSortedChart = chartData.sort(function (a, b) { | |
return parseFloat(b[options[0].yaxis]) - parseFloat(a[options[0].yaxis]); | |
}); | |
TransformChartData(nonSortedChart, options, 1, d.data[xVarName]); | |
BuildPie(id, nonSortedChart, options, 1); | |
} | |
}); | |
path.append("svg:title") | |
.text(function (d) { | |
return d.data["title"] + " (" + d.data[yVarName] + ")"; | |
}); | |
path.style("fill", function (d) { | |
return rcolor(d.data[xVarName]); | |
}) | |
.transition().duration(1000).attrTween("d", tweenIn).each("end", function () { | |
this._listenToEvents = true; | |
}); | |
g.append("text") | |
.attr("transform", function (d) { return "translate(" + arc.centroid(d) + ")"; }) | |
.attr("dy", ".35em") | |
.style("text-anchor", "middle") | |
.style("opacity", 1) | |
.text(function (d) { | |
return d.data[yVarName]; | |
}); | |
count = 0; | |
var legend = chart.selectAll(".legend") | |
.data(runningData).enter() | |
.append("g").attr("class", "legend") | |
.attr("legend-id", function (d) { | |
return count++; | |
}) | |
.attr("transform", function (d, i) { | |
return "translate(15," + (parseInt("-" + (runningData.length * 10)) + i * 28 + legendoffset) + ")"; | |
}) | |
.style("cursor", "pointer") | |
.on("click", function () { | |
var oarc = d3.select("#" + id + " #arc-" + $(this).attr("legend-id")); | |
oarc.style("opacity", 0.3) | |
.attr("stroke", "white") | |
.transition() | |
.duration(200) | |
.attr("d", arcOver) | |
.attr("stroke-width", 1); | |
setTimeout(function () { | |
oarc.style("opacity", function (d) { | |
return d.data["op"]; | |
}) | |
.attr("d", arc) | |
.transition() | |
.duration(200) | |
.attr("stroke", "none"); | |
}, 1000); | |
}); | |
var leg = legend.append("rect"); | |
leg.attr("x", width / 2) | |
.attr("width", 18).attr("height", 18) | |
.style("fill", function (d) { | |
return rcolor(d[yVarName]); | |
}) | |
.style("opacity", function (d) { | |
return d["op"]; | |
}); | |
legend.append("text").attr("x", (width / 2) - 5) | |
.attr("y", 9).attr("dy", ".35em") | |
.style("text-anchor", "end").text(function (d) { | |
return d.caption; | |
}); | |
leg.append("svg:title") | |
.text(function (d) { | |
return d["title"] + " (" + d[yVarName] + ")"; | |
}); | |
function tweenOut(data) { | |
data.startAngle = data.endAngle = (2 * Math.PI); | |
var interpolation = d3.interpolate(this._current, data); | |
this._current = interpolation(0); | |
return function (t) { | |
return arc(interpolation(t)); | |
}; | |
} | |
function tweenIn(data) { | |
var interpolation = d3.interpolate({ startAngle: 0, endAngle: 0 }, data); | |
this._current = interpolation(0); | |
return function (t) { | |
return arc(interpolation(t)); | |
}; | |
} | |
} | |
function TransformChartData(chartData, opts, level, filter) { | |
var result = []; | |
var resultColors = []; | |
var counter = 0; | |
var hasMatch; | |
var xVarName; | |
var yVarName = opts[0].yaxis; | |
if (level == 1) { | |
xVarName = opts[0].xaxisl1; | |
for (var i in chartData) { | |
hasMatch = false; | |
for (var index = 0; index < result.length; ++index) { | |
var data = result[index]; | |
if ((data[xVarName] == chartData[i][xVarName]) && (chartData[i][opts[0].xaxis]) == filter) { | |
result[index][yVarName] = result[index][yVarName] + chartData[i][yVarName]; | |
hasMatch = true; | |
break; | |
} | |
} | |
if ((hasMatch == false) && ((chartData[i][opts[0].xaxis]) == filter)) { | |
if (result.length < 9) { | |
ditem = {} | |
ditem[xVarName] = chartData[i][xVarName]; | |
ditem[yVarName] = chartData[i][yVarName]; | |
ditem["caption"] = chartData[i][xVarName].substring(0, 10) + '...'; | |
ditem["title"] = chartData[i][xVarName]; | |
ditem["op"] = 1.0 - parseFloat("0." + (result.length)); | |
result.push(ditem); | |
resultColors[counter] = opts[0].color[0][chartData[i][opts[0].xaxis]]; | |
counter += 1; | |
} | |
} | |
} | |
} | |
else { | |
xVarName = opts[0].xaxis; | |
for (var i in chartData) { | |
hasMatch = false; | |
for (var index = 0; index < result.length; ++index) { | |
var data = result[index]; | |
if (data[xVarName] == chartData[i][xVarName]) { | |
result[index][yVarName] = result[index][yVarName] + chartData[i][yVarName]; | |
hasMatch = true; | |
break; | |
} | |
} | |
if (hasMatch == false) { | |
ditem = {}; | |
ditem[xVarName] = chartData[i][xVarName]; | |
ditem[yVarName] = chartData[i][yVarName]; | |
ditem["caption"] = opts[0].captions != undefined ? opts[0].captions[0][chartData[i][xVarName]] : ""; | |
ditem["title"] = opts[0].captions != undefined ? opts[0].captions[0][chartData[i][xVarName]] : ""; | |
ditem["op"] = 1; | |
result.push(ditem); | |
resultColors[counter] = opts[0].color != undefined ? opts[0].color[0][chartData[i][xVarName]] : ""; | |
counter += 1; | |
} | |
} | |
} | |
runningData = result; | |
runningColors = resultColors; | |
return; | |
} | |
chartOptions = [{ | |
"captions": [{ "INDIA": "INDIA", "CANADA": "CANADA", "USA": "USA" }], | |
"color": [{ "INDIA": "#FFA500", "CANADA": "#0070C0", "USA": "#ff0000" }], | |
"xaxis": "Country", | |
"xaxisl1": "Model", | |
"yaxis": "Total" | |
}] | |
var chartData = [ | |
{ | |
"Country": "USA", | |
"Model": "Model 1", | |
"Total": 487 | |
}, | |
{ | |
"Country": "USA", | |
"Model": "Model 2", | |
"Total": 185 | |
}, | |
{ | |
"Country": "USA", | |
"Model": "Model 3", | |
"Total": 140 | |
}, | |
{ | |
"Country": "USA", | |
"Model": "Model 4", | |
"Total": 108 | |
}, | |
{ | |
"Country": "USA", | |
"Model": "Model 5", | |
"Total": 26 | |
}, | |
{ | |
"Country": "USA", | |
"Model": "Model 6", | |
"Total": 106 | |
}, | |
{ | |
"Country": "USA", | |
"Model": "Model 7", | |
"Total": 27 | |
}, | |
{ | |
"Country": "USA", | |
"Model": "Model 8", | |
"Total": 44 | |
}, | |
{ | |
"Country": "USA", | |
"Model": "Model 9", | |
"Total": 96 | |
}, | |
{ | |
"Country": "INDIA", | |
"Model": "Model 1", | |
"Total": 411 | |
}, | |
{ | |
"Country": "INDIA", | |
"Model": "Model 2", | |
"Total": 33 | |
}, | |
{ | |
"Country": "INDIA", | |
"Model": "Model 3", | |
"Total": 32 | |
}, | |
{ | |
"Country": "INDIA", | |
"Model": "Model 4", | |
"Total": 29 | |
}, | |
{ | |
"Country": "INDIA", | |
"Model": "Model 5", | |
"Total": 29 | |
}, | |
{ | |
"Country": "CANADA", | |
"Model": "Model 1", | |
"Total": 7 | |
}, | |
{ | |
"Country": "CANADA", | |
"Model": "Model 2", | |
"Total": 20 | |
}, | |
{ | |
"Country": "CANADA", | |
"Model": "Model 3", | |
"Total": 232 | |
}, | |
{ | |
"Country": "CANADA", | |
"Model": "Model 4", | |
"Total": 117 | |
} | |
]; | |
</script> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment