Created
July 15, 2020 13:29
-
-
Save abruzzi/ac58fc9bc4593020ab4f248362d67259 to your computer and use it in GitHub Desktop.
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
function detailChart(categories) { | |
var width = 800, | |
height = 800; | |
var outerRadius = 300; | |
var ratingScale = 45; | |
var references = []; | |
var angle = d3.scaleLinear() | |
.range([-180, 180]); | |
var radius = d3.scaleLinear() | |
.range([0, outerRadius]); | |
var title = ''; | |
var legend = false; | |
function chart(selection) { | |
selection.each(function (series) { | |
const svg = d3.select(this).selectAll("svg").data([series]); | |
const graph = svg.enter().append("svg") | |
.attr("width", width+80) | |
.attr("height", height+80) | |
.merge(svg) | |
.append("g") | |
.attr("width", width) | |
.attr("height", height) | |
.attr("transform", "translate(" + (width / 2 ) + "," + (height / 2) + ")"); | |
const category = [148, 39, 19, 21, 16, 11, 19]; | |
const categoryLabel = ["Technical", "Testing", "Consulting", "Domain", "BA / XD", "Management", "Language"]; | |
const grayColorScale = d3.scaleOrdinal() | |
.range(["#EAEAEA"]); | |
const arc = d3.arc() | |
.outerRadius(outerRadius) | |
.innerRadius(outerRadius - 30); | |
const pie = d3.pie() | |
.sort(null) | |
.padAngle(0.005) | |
.value(d => d); | |
var g = graph.selectAll(".arc") | |
.data(pie(category)) | |
.enter() | |
.append("g") | |
.attr("class", "arc"); | |
g.append("path") | |
.attr("d", arc) | |
.style("fill", function(d) { return grayColorScale(d.data); }) | |
.each(function(d,i) { | |
//A regular expression that captures all in between the start of a string | |
//(denoted by ^) and the first capital letter L | |
var firstArcSection = /(^.+?)L/; | |
//The [1] gives back the expression between the () (thus not the L as well) | |
//which is exactly the arc statement | |
var newArc = firstArcSection.exec( d3.select(this).attr("d") )[1]; | |
//Replace all the comma's so that IE can handle it -_- | |
//The g after the / is a modifier that "find all matches rather than | |
//stopping after the first match" | |
newArc = newArc.replace(/,/g , " "); | |
//Create a new invisible arc that the text can flow along | |
graph.append("path") | |
.attr("class", "hidden") | |
.attr("id", "arc_"+i) | |
.attr("d", newArc) | |
.style("fill", "none"); | |
}); | |
graph.selectAll(".categoryLabel") | |
.data(categoryLabel) | |
.enter().append("text") | |
.attr("class", "categoryLabel") | |
.attr("x", 0) | |
.attr("dy", 18) | |
.append("textPath") | |
.attr("startOffset","50%") | |
.attr("xlink:href",function(d,i){return "#arc_"+i;}) | |
.text(d => d); | |
graph.selectAll(".title") | |
.data([title]) | |
.enter().append("text") | |
.attr("class", "title") | |
.attr("x", 0) | |
.attr("y", (height)/2-outerRadius-80) | |
.attr("text-anchor", "middle") | |
.text(d => d); | |
angle.domain([0, series.length]); | |
radius.domain([-outerRadius, outerRadius]); | |
var angleForLine = d3.scaleLinear() | |
.range([0, 2 * Math.PI]) | |
.domain([0, series.length]); | |
const lineRadial = d3.radialLine() | |
.radius(x => radius(x)) | |
.angle((d, i) => angleForLine(i)) | |
.curve(d3.curveCardinal); | |
const colorScale = d3.scaleLinear() | |
.domain([-outerRadius, 0, outerRadius]) | |
.range(["#2c7bb6", "#ffff8c", "#d7191c"]) | |
.interpolate(d3.interpolateHcl); | |
graph.selectAll(".bar") | |
.data(_.map(series, function (x) { | |
return x * ratingScale | |
})) | |
.enter() | |
.append("rect") | |
.attr("class", "bar") | |
.attr('value', function(d, i) {return d/ratingScale}) | |
.attr("transform", function(d, i) { | |
return "rotate(" + angle(i) + ")"; | |
}) | |
.attr("width", 6) | |
.attr("height", function(d, i) { | |
return Math.abs(d - references[i]*ratingScale); | |
}) | |
.attr("rx", 3) | |
.attr("ry", 3) | |
.attr("x", -3) | |
.attr("y", function(d, i) { | |
if(references[i]*ratingScale > d) { | |
return radius(references[i]*ratingScale) - Math.abs(d - references[i]*ratingScale) ; | |
} else { | |
return radius(references[i]*ratingScale); | |
} | |
}) | |
.style("fill", function(d, i) { return colorScale(d - references[i]*ratingScale); }); | |
graph.selectAll('.shape') | |
.data([_.map(references, function (x) { | |
return x * ratingScale | |
})]) | |
.enter() | |
.append('path') | |
.attr('class', 'shape') | |
.attr('d', d => lineRadial(d)); | |
const ga = graph.append("g") | |
.merge(graph) | |
.attr("class", "a axis") | |
.attr("transform", "translate(" + (0) + "," + (0) + ")") | |
.selectAll("g") | |
.data(d3.range(0, 360, 360 / (series.length))) | |
.enter().append("g") | |
.attr("transform", function (d) { | |
return "rotate(" + (d - 90) + ")"; | |
}); | |
ga.append("text") | |
.merge(ga) | |
.attr("class", "legend-text") | |
.attr("x", Math.min(width, height) / 2 - 80) | |
.attr("dy", ".30em") | |
.style("text-anchor", function (d) { | |
return d < 360 && d > 180 ? "end" : null; | |
}) | |
.attr("transform", function (d) { | |
return d < 360 && d > 180 ? "rotate(180 " + ((Math.min(width, height) / 2 - 80)) + ",0)" : null; | |
}) | |
.text((d, i) => categories[i]); | |
}); | |
} | |
chart.margin = function (_) { | |
if (!arguments.length) return margin; | |
margin = _; | |
return chart; | |
}; | |
chart.title = function (_) { | |
if (!arguments.length) return title; | |
title = _; | |
return chart; | |
}; | |
chart.width = function (_) { | |
if (!arguments.length) return width; | |
width = _; | |
return chart; | |
}; | |
chart.height = function (_) { | |
if (!arguments.length) return height; | |
height = _; | |
return chart; | |
}; | |
chart.legend = function (_) { | |
if (!arguments.length) return legend; | |
legend = _; | |
return chart; | |
} | |
chart.references = function (_) { | |
if (!arguments.length) return references; | |
references = _; | |
return chart; | |
} | |
return chart; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment