Skip to content

Instantly share code, notes, and snippets.

@PedroF20
Forked from alandunning/.block
Last active July 4, 2017 16:42
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 PedroF20/98f80921fb35dd6d89e1fa5eeb629a40 to your computer and use it in GitHub Desktop.
Save PedroF20/98f80921fb35dd6d89e1fa5eeb629a40 to your computer and use it in GitHub Desktop.
Radar Chart D3 V4
height: 650
[
[
{"area": "Central ", "value": 80},
{"area": "Kirkdale", "value": 40},
{"area": "Kensington ", "value": 40},
{"area": "Everton ", "value": 90},
{"area": "Picton ", "value": 60},
{"area": "Riverside ", "value": 80}
]
]
<!DOCTYPE html>
<meta charset="utf-8">
<head>
<link href="https://fonts.googleapis.com/css?family=Fira+Sans:300,300i,400,500,700" rel="stylesheet">
</head>
<style>
body {
background-color: #F1F3F3
}
.axis {
font: 15px sans-serif;
}
.axis path,
.axis line {
fill: none;
stroke: #D4D8DA;
stroke-width: 2px;
shape-rendering: crispEdges;
}
#chart {
position: absolute;
top: 50px;
left: 100px;
}
.toolTip {
pointer-events: none;
position: absolute;
display: none;
min-width: 50px;
height: auto;
background: none repeat scroll 0 0 #ffffff;
padding: 9px 14px 6px 14px;
border-radius: 2px;
text-align: center;
line-height: 1.3;
color: #5B6770;
box-shadow: 0px 3px 9px rgba(0, 0, 0, .15);
}
.toolTip:after {
content: "";
width: 0;
height: 0;
border-left: 12px solid transparent;
border-right: 12px solid transparent;
border-top: 12px solid white;
position: absolute;
bottom: -10px;
left: 50%;
margin-left: -12px;
}
.toolTip span {
font-weight: 500;
color: #081F2C;
}
</style>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script src="RadarChart.js"></script>
<div id="chart"></div>
<script>
var width = 300,
height = 300;
// Config for the Radar chart
var config = {
w: width,
h: height,
maxValue: 100,
levels: 5,
ExtraWidthX: 300
}
//Call function to draw the Radar chart
d3.json("data.json", function(error, data) {
if (error) throw error;
RadarChart.draw("#chart", data, config);
});
var svg = d3.select('body')
.selectAll('svg')
.append('svg')
.attr("width", width)
.attr("height", height);
</script>
{
"name": "radarchartd3_v4",
"version": "0.0.1"
}
var RadarChart = {
draw: function(id, d, options){
var cfg = {
hard_skills: false,
radius: 5,
labelPadding: 0,
w: 600,
h: 600,
factor: 1,
factorLegend: .85,
levels: 3,
maxValue: 0,
radians: 2 * Math.PI,
opacityArea: 0.5,
ToRight: 5,
TranslateX: 0,
TranslateY: 0,
ExtraWidthX: 100,
ExtraWidthY: 100,
color: d3.scaleOrdinal().range(["#6F257F", "#CA0D59"])
};
if('undefined' !== typeof options){
for(var i in options){
if('undefined' !== typeof options[i]){
cfg[i] = options[i];
}
}
}
//cfg.maxValue = 100;
var allAxis = (d[0].map(function(i, j){return i.area}));
var total = allAxis.length;
var radius = cfg.factor*Math.min(cfg.w/2, cfg.h/2);
var Format = d3.format('%');
d3.select(id).select("svg").remove();
var margin = {top: 20, right: 0, bottom: 0, left: 50};
var g = d3.select(id)
.attr("class", "radar-svg")
.attr("width", cfg.w+cfg.ExtraWidthX - margin.left - margin.right)
.attr("height", cfg.h+cfg.ExtraWidthY - margin.top - margin.bottom)
.append("g")
.attr("transform", "translate(" + cfg.TranslateX + "," + cfg.TranslateY + ")");
if (cfg.hard_skills == true) {
var tip = d3.select("body")
.append("div")
.attr("class", "hard_skill_radar_tip")
.style("opacity", 0);
}
if (cfg.hard_skills == false) {
var tooltip;
}
//Circular segments
for(var j=0; j<cfg.levels; j++){
var levelFactor = cfg.factor*radius*((j+1)/cfg.levels);
g.selectAll(".levels")
.data(allAxis)
.enter()
.append("svg:line")
.attr("x1", function(d, i){return levelFactor*(1-cfg.factor*Math.sin(i*cfg.radians/total));})
.attr("y1", function(d, i){return levelFactor*(1-cfg.factor*Math.cos(i*cfg.radians/total));})
.attr("x2", function(d, i){return levelFactor*(1-cfg.factor*Math.sin((i+1)*cfg.radians/total));})
.attr("y2", function(d, i){return levelFactor*(1-cfg.factor*Math.cos((i+1)*cfg.radians/total));})
.attr("class", "line")
.style("stroke", "grey")
.style("stroke-opacity", "0.75")
.style("stroke-width", "0.3px")
.attr("transform", "translate(" + (cfg.w/2-levelFactor) + ", " + (cfg.h/2-levelFactor) + ")");
}
//Text indicating at what % each level is
for(var j=0; j<cfg.levels; j++){
var levelFactor = cfg.factor*radius*((j+1)/cfg.levels);
g.selectAll(".levels")
.data([1]) //dummy data
.enter()
.append("svg:text")
.attr("x", function(d){return levelFactor*(1-cfg.factor*Math.sin(0));})
.attr("y", function(d){return levelFactor*(1-cfg.factor*Math.cos(0));})
.attr("class", "legend")
.style("font-family", "sans-serif")
.style("font-size", "10px")
.attr("transform", "translate(" + (cfg.w/2-levelFactor + cfg.ToRight) + ", " + (cfg.h/2-levelFactor + cfg.labelPadding) + ")")
.attr("fill", "#737373")
.text((j+1)*cfg.maxValue/cfg.levels);
}
series = 0;
var axis = g.selectAll(".axis")
.data(allAxis)
.enter()
.append("g")
.attr("class", "radar-axis");
axis.append("line")
.attr("x1", cfg.w/2)
.attr("y1", cfg.h/2)
.attr("x2", function(d, i){return cfg.w/2*(1-cfg.factor*Math.sin(i*cfg.radians/total));})
.attr("y2", function(d, i){return cfg.h/2*(1-cfg.factor*Math.cos(i*cfg.radians/total));})
.attr("class", "line")
.style("stroke", "grey")
.style("stroke-width", "1px");
axis.append("text")
.attr("class", "legend")
.text(function(d){return d})
.style("font-family", "sans-serif")
.style("font-size", "11px")
.attr("text-anchor", "middle")
.attr("dy", "1.5em")
.attr("transform", function(d, i){return "translate(0, -10)"})
.attr("x", function(d, i){return cfg.w/2*(1-cfg.factorLegend*Math.sin(i*cfg.radians/total))-60*Math.sin(i*cfg.radians/total);})
.attr("y", function(d, i){return cfg.h/2*(1-Math.cos(i*cfg.radians/total))-20*Math.cos(i*cfg.radians/total);});
d.forEach(function(y, x){
dataValues = [];
g.selectAll(".nodes")
.data(y, function(j, i){
dataValues.push([
cfg.w/2*(1-(parseFloat(Math.max(j.value, 0))/cfg.maxValue)*cfg.factor*Math.sin(i*cfg.radians/total)),
cfg.h/2*(1-(parseFloat(Math.max(j.value, 0))/cfg.maxValue)*cfg.factor*Math.cos(i*cfg.radians/total))
]);
});
dataValues.push(dataValues[0]);
g.selectAll(".area")
.data([dataValues])
.enter()
.append("polygon")
.attr("class", "radar-chart-serie"+series)
.style("stroke-width", "2px")
.style("stroke", cfg.color(series))
.attr("points",function(d) {
var str="";
for(var pti=0;pti<d.length;pti++){
str=str+d[pti][0]+","+d[pti][1]+" ";
}
return str;
})
.style("fill", function(j, i){return cfg.color(series)})
.style("fill-opacity", cfg.opacityArea)
.on('mouseover', function (d){
z = "polygon."+d3.select(this).attr("class");
g.selectAll("polygon")
.transition(200)
.style("fill-opacity", 0.1);
g.selectAll(z)
.transition(200)
.style("fill-opacity", .7);
})
.on('mouseout', function(){
g.selectAll("polygon")
.transition(200)
.style("fill-opacity", cfg.opacityArea);
});
series++;
});
series=0;
if (cfg.hard_skills == false) {
var tooltip = d3.select("body").append("div").attr("class", "radar-tooltip-1");
}
d.forEach(function(y, x){
g.selectAll(".nodes")
.data(y).enter()
.append("svg:circle")
.attr("class", "radar-chart-serie"+series)
.attr('r', cfg.radius)
.attr("alt", function(j){return Math.max(j.value, 0)})
.attr("cx", function(j, i){
dataValues.push([
cfg.w/2*(1-(parseFloat(Math.max(j.value, 0))/cfg.maxValue)*cfg.factor*Math.sin(i*cfg.radians/total)),
cfg.h/2*(1-(parseFloat(Math.max(j.value, 0))/cfg.maxValue)*cfg.factor*Math.cos(i*cfg.radians/total))
]);
return cfg.w/2*(1-(Math.max(j.value, 0)/cfg.maxValue)*cfg.factor*Math.sin(i*cfg.radians/total));
})
.attr("cy", function(j, i){
return cfg.h/2*(1-(Math.max(j.value, 0)/cfg.maxValue)*cfg.factor*Math.cos(i*cfg.radians/total));
})
.attr("data-id", function(j){return j.area})
.style("fill", "#fff")
.style("stroke-width", "2px")
.style("stroke", cfg.color(series)).style("fill-opacity", .9)
.on('mouseover', function (d, i){
if (cfg.hard_skills == false) {
tooltip
.style("left", d3.event.pageX - 30 + "px")
.style("top", d3.event.pageY - 60 + "px")
.style("display", "inline-block")
.html((d.area) + "<br><span>" + (d.value) + "</span>");
}
if (cfg.hard_skills == true) {
var $table = $( "<table></table>" );
for (var i = 0; i < d.subjects.length; i++) {
var grades_array = Object.values(d.subjects[i]);
var subjects_array = Object.keys(d.subjects[i]);
for (var i = 0; i < grades_array.length; i++) {
var emp = d.subjects[i];
var $line = $("<tr></tr>");
$line.append($("<td></td>").html(subjects_array[i]));
$line.append($("<tr></tr>"));
$line.append($("<td></td>").html(grades_array[i]));
$table.append($line);
};
}
tip.html('<strong>' + "Weight: " + '</strong>' + d.weight + '%' + '<br>' +
'<strong>' + "Area average: " + '</strong>' + d.value + '<br>' +
'<strong>' + "Subject, grade: " + '</strong>' + '<br>')
.style("left", d3.event.pageX + 10 + "px")
.style("top", d3.event.pageY + "px")
.style("opacity", 1);
$table.appendTo($(".hard_skill_radar_tip"));
}
})
.on("mouseout", function(d){
if (cfg.hard_skills == false) {
tooltip.style("display", "none");
}
if (cfg.hard_skills == true) {
tip.style("opacity", 0);
}
});
series++;
});
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment