Skip to content

Instantly share code, notes, and snippets.

@TaraZhu
Last active October 17, 2017 20:12
Show Gist options
  • Save TaraZhu/e267d33bc4ecb0009d3b37e2202aad36 to your computer and use it in GitHub Desktop.
Save TaraZhu/e267d33bc4ecb0009d3b37e2202aad36 to your computer and use it in GitHub Desktop.
Pokemon_visualization
license: mit

Built with blockbuilder.org

This dataset is about Pokemon with stats and types, the raw csv file can be found here in Kaggle.

More about this theme click this link.

This radar chart shows the HP, Attack, Defense, Sp. Atk, Sp. Def and Speed score of Pokemon Bulbasaur.

Radar chart forked from Alan Dunning’s Block.

[
[
{"area": "HP", "value": 45},
{"area": "Attack", "value": 49},
{"area": "Defense", "value": 49},
{"area": "Sp. Atk", "value": 65},
{"area": "Sp. Def", "value": 65},
{"area": "Speed", "value": 45}
]
]
<!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>
var RadarChart = {
draw: function(id, d, options){
var cfg = {
radius: 5,
w: 600,
h: 600,
factor: 1,
factorLegend: .85,
levels: 3,
maxValue: 0,
radians: 2 * Math.PI,
opacityArea: 0.5,
ToRight: 5,
TranslateX: 80,
TranslateY: 30,
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 g = d3.select(id)
.append("svg")
.attr("width", cfg.w+cfg.ExtraWidthX)
.attr("height", cfg.h+cfg.ExtraWidthY)
.append("g")
.attr("transform", "translate(" + cfg.TranslateX + "," + cfg.TranslateY + ")");
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) + ")")
.attr("fill", "#737373")
.text((j+1)*100/cfg.levels);
}
series = 0;
var axis = g.selectAll(".axis")
.data(allAxis)
.enter()
.append("g")
.attr("class", "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;
var tooltip = d3.select("body").append("div").attr("class", "toolTip");
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){
console.log(d.area)
tooltip
.style("left", d3.event.pageX - 40 + "px")
.style("top", d3.event.pageY - 80 + "px")
.style("display", "inline-block")
.html((d.area) + "<br><span>" + (d.value) + "</span>");
})
.on("mouseout", function(d){ tooltip.style("display", "none");});
series++;
});
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment