Created
July 15, 2020 13:28
-
-
Save abruzzi/25d716a88bd000aee7c5817a8043086f 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 shapeChart(categories) { | |
var width = 200, | |
height = 200; | |
var outerRadius = 50; | |
var ratingScale = 10; | |
var angle = d3.scaleLinear() | |
.range([0, 2 * Math.PI]); | |
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") | |
.merge(svg) | |
.append("g") | |
.attr("width", width) | |
.attr("height", height) | |
.attr("transform", "translate(" + (width / 2 - 10) + "," + (height / 2 - 10) + ")"); | |
graph.selectAll(".title") | |
.data([title]) | |
.enter().append("text") | |
.attr("class", "title") | |
.attr("x", (0)) | |
.attr("y", (height / 2 - 24)) | |
.attr("text-anchor", "middle") | |
.text(d => d); | |
angle.domain([0, series.length]); | |
radius.domain([0, -outerRadius]); | |
const lineRadial = d3.radialLine() | |
.radius(x => x) | |
.angle((d, i) => angle(i)) | |
.curve(d3.curveCardinal); | |
const ploygonRadial = d3.radialLine() | |
.radius(x => x) | |
.angle((d, i) => angle(i)); | |
graph.selectAll(".axis") | |
.data(d3.range(series.length)) | |
.enter().append("g") | |
.attr("class", "axis") | |
.attr("stroke-dasharray", ("2,2")) | |
.attr("transform", function (d) { | |
return "rotate(" + angle(d) * 180 / Math.PI + ")"; | |
}) | |
.call(d3.axisLeft(radius.copy().range([0, -outerRadius])) | |
.tickSizeOuter(0)); | |
var colorRange = ['#F44CAC', '#EC148C']; | |
var color = d3.scaleLinear().range(colorRange).domain([1, 2, 3, 4]); | |
graph.append("defs") | |
.append("radialGradient") | |
.attr("id", "sun-gradient") | |
.selectAll("stop") | |
.data([ | |
{offset: "0%", color: color(1)}, | |
{offset: "25%", color: color(2)}, | |
{offset: "75%", color: color(3)}, | |
{offset: "100%", color: color(4)} | |
]) | |
.enter().append("stop") | |
.attr("offset", function(d) { return d.offset; }) | |
.attr("stop-color", function(d) { return d.color; }); | |
const id = _.uniqueId('id_'); | |
const clip = graph.append("defs") | |
.append("clipPath") | |
.attr('id',`clip-${id}`) | |
.selectAll('.shape') | |
.data([_.map(series, function (x) { | |
return x * ratingScale | |
})]) | |
.enter() | |
.append('path') | |
.attr('class', 'shape') | |
.attr('d', d => lineRadial(d)); | |
graph.append("circle") | |
.attr("r", outerRadius) | |
.attr("clip-path", `url(#clip-${id})`) | |
.style("fill", "url(#sun-gradient)"); | |
graph.selectAll('.shape-baseline') | |
.data([_.fill(Array(series.length+1), outerRadius)]) | |
.enter() | |
.append('path') | |
.attr('class', 'shape-baseline') | |
.attr('d', d => ploygonRadial(d)); | |
if (legend) { | |
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 - 70) | |
.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 - 70)) + ",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; | |
} | |
return chart; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment