Skip to content

Instantly share code, notes, and snippets.

@abruzzi
Created July 15, 2020 13:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save abruzzi/ac58fc9bc4593020ab4f248362d67259 to your computer and use it in GitHub Desktop.
Save abruzzi/ac58fc9bc4593020ab4f248362d67259 to your computer and use it in GitHub Desktop.
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