This is the alpha version of my visualization for the video game sales history. In this visualizaion, I create a line chart to demonstrate few different platforms game copie sales line chart.
This data is from Video Game Sales and Ratings. The game sales data is collected from VGChartz with corresponding ratings from Metacritic.
This dataset is about video games from different platforms and their ratings and sales from different region.
forked from curran's block: Line Chart with Circles
forked from curran's block: Data Table Summary
forked from YouthBread's block: Data Table Summary - Video Game
xxxxxxxxxx
<html>
<head>
<meta charset="utf-8">
<title>Data Summary</title>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script src="https://d3js.org/d3.v4.min.js"></script>
<link href="https://fonts.googleapis.com/css?family=Open+Sans:400,400i,700" rel="stylesheet">
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3-legend/2.24.0/d3-legend.min.js"></script>
<style>
body {
margin: 0px;
}
.tick text, .legendCells text {
fill: #111111;
font-size: 10pt;
font-family: 'Open Sans', sans-serif;
}
.axis-label, .legend-label {
fill: #AAAAAA;
font-size: 10pt;
font-family: 'Open Sans', sans-serif;
}
.subtitle {
font-size: 35pt;
font-family: 'Open Sans', sans-serif;
alignment-baseline: middle;
fill: #001f3f;
}
circle:hover {
fill: #F012BE;
}
div.tooltip {
position: absolute;
text-align: center;
width: 200px;
height: 50px;
vertical-align: middle;
line-height: 30px;
font-family:'Open Sans', sans-serif;
background: #FFDC00;
border: 0px;
border-radius: 8px;
pointer-events: none;
}
</style>
</head>
<body>
<script>
const parseTime = d3.timeParse("%Y");
const colorLabel = 'Platform';
const margin = { left: 120, right: 120, top: 20, bottom: 120 };
const svg = d3.select("body").append("svg")
.attr("width", 1000)
.attr("height", 500);
const width = svg.attr('width');
const height = svg.attr('height');
const innerWidth = width - margin.left - margin.right;
const innerHeight = height - margin.top - margin.bottom;
const g = svg.append('g')
.attr('transform', `translate(${margin.left},${margin.top+50})`);
const colorLegendG = g.append('g')
.attr('transform', `translate(${innerWidth - 100}, 50)`);
const xScale = d3.scaleTime();
const yScale = d3.scaleLinear();
const colorScale = d3.scaleOrdinal()
.range(d3.schemeCategory10);
const xAxisG = g.append('g')
.attr('transform', `translate(0, ${innerHeight})`);
const yAxisG = g.append('g');
xAxisG.append('text')
.attr('class', 'axis-label')
.attr('x', innerWidth / 2)
.attr('y', 50)
.text('Year');
yAxisG.append('text')
.attr('class', 'axis-label')
.attr('x', -innerHeight / 2)
.attr('y', -60)
.attr('transform', `rotate(-90)`)
.style('text-anchor', 'middle')
.text('Global Sales');
const xAxis = d3.axisBottom()
.scale(xScale)
.ticks(20)
.tickPadding(10)
.tickSize(5);
const yAxis = d3.axisLeft()
.scale(yScale)
.ticks(10)
.tickPadding(15)
.tickSize(5);
var temp = d3.select('body').append('div')
.attr('class', 'tooltip')
.style('opacity', 0);
g.append('text')
.attr('class', 'subtitle')
.attr('x', -50)
.attr('y', margin.top-50)
.style('font-weight', 'bold')
.text('New age game platform\'s game sales');
colorLegendG.append('text')
.attr('class', 'legend-label')
.attr('x', -30)
.attr('y', -20)
.text(colorLabel);
const colorLegend = d3.legendColor()
.scale(colorScale)
.shape('square');
var temp = d3.select('body').append('div')
.attr('class', 'tooltip')
.style('opacity', 0);
var line = d3.line()
.x(function(d) {return xScale(parseTime(d.key));})
.y(function(d) {return yScale(d.value);});
d3.csv('vgsales_r.csv', data => {
var temp_data = data.filter(function(d) {
return d.Year_of_Release != "N/A" && (d.Platform == "PS3" ||
d.Platform == "PS4" ||
d.Platform == "X360" ||
d.Platform == "XOne" )})
xScale
.domain(d3.extent(temp_data, d=>parseTime(d.Year_of_Release)))
.range([0, innerWidth])
.nice();
yScale
.domain([0,210])
.range([innerHeight, 0])
.nice();
temp_data = d3.nest()
.key(function(d) { return d.Platform; })
.key(function(d) { return d.Year_of_Release; }).sortKeys(d3.ascending)
.rollup(function(v) {return Number((d3.sum(v, d=>d.Global_Sales)).toFixed(1));})
.entries(temp_data);
for (i=0;i<temp_data.length;i++) {
g.append('path')
.datum(temp_data[i].values)
.attr("fill", "none")
.attr("stroke", colorScale(temp_data[i].key))
.attr("stroke-linejoin", "round")
.attr("stroke-linecap", "round")
.attr("stroke-width", 5)
.attr("d", line);
}
for (i=0;i<temp_data.length;i++){
var pn = temp_data[i].key;
for (j=0; j<temp_data[i].values.length;j++){
g.append('circle')
.datum(temp_data[i].values[j])
.attr('cx', d => xScale(parseTime(d.key)))
.attr('cy', d => yScale(d.value))
.attr('pn', pn)
.attr('fill', '#0074D9')
.attr('fill-opacity', 0.6)
.attr('r', 3.5)
.on("mouseover", function(d) {
temp.transition()
.duration(200)
.style("opacity", 1);
temp.html("Global Sale:"+d.value+' Million'+'<br>')
.style("left", (d3.event.pageX - 120) + "px")
.style("top", (d3.event.pageY - 20) + "px");
})
.on("mouseout", function(d) {
temp.transition()
.duration(500)
.style("opacity", 0);
});
}
}
xAxisG.call(xAxis);
yAxisG.call(yAxis);
colorLegendG.call(colorLegend)
.selectAll('.cell text')
.attr('dy', '0.1em');
});
</script>
</body>
</html>
https://d3js.org/d3.v4.min.js
https://d3js.org/d3.v4.min.js
https://cdnjs.cloudflare.com/ajax/libs/d3-legend/2.24.0/d3-legend.min.js