Part of the Data Visualization Course in IE School of Human Sciences and Technology. Code was adapted from YouthBrea's block: Scatter Plot and changed to the match the dataset that was used.
An example scatter plot with color legend using D3 and d3-legend.
This scatter plot shows the dataset of Movies. Originally published at http://app.rawgraphs.io/, this small dataset records Movies records, including the Production budget, Box Office returns, ROI and IMDB ratings.
In this scatter plot, Y axis is the ratings present on the IMDB site and X axis is representing the production budget for each movie. Each circle one movie and the size of the circle represents the ROI for the movie. Each colour of the circle represents a different genre and hovering over the circle would show the name of the movie and the ROI of the specific movie.
forked from YouthBread's block: Scatter Plot
xxxxxxxxxx
//<!-- This vizualization aims to show the relationship of Rating, Production Budget and ROI from the Movies dataset.The first few lines import the d3 library and the Montseraat font from Google fonts. -->
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<script src="https://d3js.org/d3.v4.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3-legend/2.24.0/d3-legend.min.js"></script>
<link href="https://fonts.googleapis.com/css?family=Montserrat:400,400i,700" rel="stylesheet">
<title>Scatter Plot_Group H</title>
<!-- The following section defines the style of the section. It sets the font size, font style and colour of the ticker, axis and subtitle (Movie Rating) individually. It also includes what should happen when there is a hover action performed over the circle elements. The div.tooltip further develops the output of the display function. -->
<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: 29pt;
font-family: 'Open Sans', sans-serif;
alignment-baseline: auto;
fill: #001f3f;
}
circle:hover {
fill: #FFDC00;
}
div.tooltip {
position: absolute;
text-align: center;
width: 200px;
height: 90px;
vertical-align: middle;
line-height: 30px;
font-family:'Open Sans', serif;
background: #FFDC00;
border: 0px;
border-radius: 8px;
pointer-events: none;
}
</style>
</head>
<body>
<script>
// Initializing the VALUES and LABELS for the x,y axis and the radius of the circle and the legend value.The '+' before the variables converts the inputs into numeric variables.
var xValue = d => +d.Rating_IMDB;
var xLabel = 'Rating';
var yValue = d => +d.Prod_Budget;
var yLabel = 'Production Budget';
var rValue = d => +d.ROI ;
var colorValue = d => d.Genre;
var colorLabel = 'Genre';
// Initializing the edge margins of the visualization.
const margin = { left: 80, right: 210, top: 20, bottom: 150 };
// Initializing the SVG space.
const svg = d3.select("body").append("svg")
.attr("width", 1000)
.attr("height", 500);
// The innerWidth and innerHeight refers to the inner dimension of the group which will be used further down as a baseline to position other elements.
var width = svg.attr('width');
var height = svg.attr('height');
var innerWidth = width - margin.left - margin.right;
var innerHeight = height - margin.top - margin.bottom;
const g = svg.append('g')
.attr('transform', `translate(${margin.left},${margin.top+50})`);
var xAxisG = g.append('g')
.attr('transform', `translate(0, ${innerHeight})`);
var yAxisG = g.append('g');
// This part basically places the legend with the colors where we want it
var colorLegendG = g.append('g')
.attr('transform', `translate(${innerWidth - -20}, 191)`);
var temp = d3.select('body').append('div')
.attr('class', 'tooltip')
.style('opacity', 0.5);
// We are using the variable we created earlier and appending them to the svg element.
g.append('text')
.attr('class', 'subtitle')
.attr('x', 0)
.attr('y', margin.top-50)
.style('font-weight', 'bold')
.text('Movie Rating');
xAxisG.append('text')
.attr('class', 'axis-label')
.attr('x', innerWidth / 2)
.attr('y', 50)
.text(xLabel);
yAxisG.append('text')
.attr('class', 'axis-label')
.attr('x', -innerHeight / 2)
.attr('y', -60)
.attr('transform', `rotate(-90)`)
.style('text-anchor', 'middle')
.text(yLabel);
colorLegendG.append('text')
.attr('class', 'legend-label')
.attr('x', -30)
.attr('y', -20)
.text(colorLabel);
// Defining the X and Y axis and using Linear and Ordinal scaling based on the inputs. Scale basically maps value to a visual display encoding, such as a pixel position.
var xScale = d3.scaleLinear();
var yScale = d3.scaleLinear();
var rScale = d3.scaleLinear().domain([0, 0.5])
.range([0, 30]);
const colorScale = d3.scaleOrdinal()
.range(d3.schemeCategory10);
// Implementing the scale on the correct axis.
const xAxis = d3.axisBottom()
.scale(xScale)
.ticks(20)
.tickPadding(10)
.tickSize(5);
const yAxis = d3.axisLeft()
.scale(yScale)
.ticks(10)
.tickPadding(15)
.tickSize(5);
const colorLegend = d3.legendColor()
.scale(colorScale)
.shape('rect');
// Loading in the dataset and assigning values based on the initial assignment performed at the top of the code. We are also changing the scale based on the value of the data and the dimensions defined above.
d3.csv('Movie.csv', data => {
xScale
.domain(d3.extent(data, xValue))
.range([0, innerWidth])
.nice();
yScale
.domain(d3.extent(data, yValue))
.range([innerHeight, 0])
.nice();
rScale
.domain(d3.extent(data, rValue))
.range([7, 38])
.nice();
g.selectAll('circle').data(data)
.enter().append('circle')
.attr('cx', d => xScale(xValue(d)))
.attr('cy', d => yScale(yValue(d)))
.attr('fill', d => colorScale(colorValue(d)))
.attr('Country', d=>d.Genre)
.attr('fill-opacity', 0.6)
.attr('r', d => rScale(rValue(d)))
// This works on the hover function and tells the code what to show when the mouseover action is implemented.
.on("mouseover", function(d) {
temp.transition()
.duration(200)
.style("opacity", 1);
temp.html("ROI : "+d.ROI + "<br/>" + "Movie :" + d.Movie)
.style("left", (d3.event.pageX - 60) + "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://cdnjs.cloudflare.com/ajax/libs/d3-legend/2.24.0/d3-legend.min.js