Published
Edited
May 26, 2020
Insert cell
Insert cell
Insert cell
movies
Insert cell
//mark down editor: https://simplemde.com
md`# Answer: Attribute types
- title: categorical
- release date: quantitative
- runtime: quantitative
- budget: quantitative
- revenue: quantitative
- original_language: categorical
- rating: quantitative
- num_votes: quantitative
`




Insert cell
Insert cell
table(movies, { title: "Movies from IMDb" })
Insert cell
Insert cell

scatterplotCanvas = {
const context = DOM.context2d(width, height);

let domainX = d3.extent(movies, d => d[attributeX]);
let domainY = d3.extent(movies, d => d[attributeY]);
//To be used for bubbleplot, it gives the range of the rating from data set
let domainRating = d3.extent(movies, d => d['rating']);
//For debug purpose
console.log('Test' + domainRating);
function mapX(value, bubbleSize) {
//set the origin point of Axis X at left botton
const originX = margin.left + bubbleSize;
//set the number of pixel from data position to origin, also taking the bubbleplot may go off the canvas into consideration.
const distanceX = ( width - margin.left - margin.right - 2*bubbleSize ) *
(value - domainX[0]) / (domainX[1] - domainX[0])
//set the data from origin in Axis Y
value = originX + distanceX;
return value;
}
function mapY(value,bubbleSize) {
// TODO
//set the origin point of Axis Y at left bottom
const originY = height - margin.bottom - bubbleSize;
//set the number of pixel from data position to origin
const distanceY = ( height - margin.top - margin.bottom - 2*bubbleSize) *
(value - domainY[0]) / (domainY[1] - domainY[0])
//set the data from origin in Axis Y
value = originY - distanceY;
return value;
}

function draw() {
context.clearRect(0, 0, width, height);
context.fillStyle = backgroundColor;
context.fillRect(
margin.left,
margin.top,
width - margin.left - margin.right,
height - margin.top - margin.bottom
);
context.fillStyle = "#263238";
// console.log(movies);
movies.forEach(item => {
//
if(item['original_language'] == 'en'){
//Sets the style for shapes' outlines to
context.strokeStyle = 'white';
context.fillStyle = 'rgba(70, 130, 180, 0.8)'
} else {
// Use colorblind friendly color
context.fillStyle = '#b8860b'
context.strokeStyle = 'white';
}
context.beginPath();
//To get a properly weighted scale, one must scale each disk's radius to the square root of the corresponding data value.
//Instead, make sure that the bubbles’ areas correspond with the third variable’s values. In the same scenario as above, a point with twice the value of another point should have sqrt(2) = 1.41 times the diameter or radius so that its area is twice the smaller point’s. https://chartio.com/learn/charts/bubble-chart-complete-guide/
let bubbleSize = radius * (Math.sqrt( item['rating']/domainRating[0]));
context.arc(
//Change paramenters of the function for bubbleplot task.
mapX(item[attributeX],bubbleSize),
mapY(item[attributeY],bubbleSize),
bubbleSize ,
0,
2 * Math.PI
);
//Disable the fullfill color in scatterplot
context.fill();
//Sets the style for shapes' outlines to mitigate overdraw.
context.stroke();
});
}

draw();
return context.canvas;
}
Insert cell
Insert cell
x = d3
.scaleLinear()
.domain(d3.extent(movies, d => d[attributeX]))
.nice()
.range([margin.left, width - margin.right])
Insert cell
y = d3
.scaleLinear()
.domain(d3.extent(movies, d => d[attributeY]))
.nice()
.range([height - margin.bottom, margin.top])
Insert cell
Insert cell
x(500)
Insert cell
Insert cell
scatterplotSVG = {
const svg = d3.create("svg").attr("viewBox", [0, 0, width, height]);

svg
.append("g")
.attr("transform", `translate(0,${height - margin.bottom})`)
.call(d3.axisBottom(x).ticks(width / 160))
.call(g =>
g
.append("text")
.attr("x", width)
.attr("y", margin.bottom - 4)
.attr("fill", "currentColor")
.attr("text-anchor", "end")
.text(attributeX)
);
svg
.append("g")
.attr("transform", `translate(${margin.left},0)`)
.call(d3.axisLeft(y))
.call(g =>
g
.append("text")
.attr("x", -margin.left)
.attr("y", 10)
.attr("fill", "currentColor")
.attr("text-anchor", "start")
.text(attributeY)
);
svg
.append("rect")
.attr("x", margin.left)
.attr("y", margin.top)
.attr("width", width - margin.left - margin.right)
.attr("height", height - margin.top - margin.bottom)
.attr("fill", backgroundColor);

// TODO: draw the circles for the data items
//Use forEach method to iterate all the items in movies. https://www.w3schools.com/jsref/jsref_foreach.asp
//Arrow function reference: https://www.w3schools.com/js/js_arrow_function.asp
//To be used for bubbleplot, it gives the range of the rating from data set
let domainRating = d3.extent(movies, d => d['rating']);
movies.forEach(item => {
let bubbleSize = radius * (Math.sqrt( item['rating']/domainRating[0]));
//Reference: https://developer.mozilla.org/en-US/docs/Web/SVG/Element/circle
https://www.tutorialspoint.com/d3js/d3js_introduction_to_svg.htm
//Inject the SVG element using the append() method
//The <circle> SVG element is an SVG basic shape, used to draw circles based on a center point and a radius.
//Add the attributes and styles using the attr() and the style() methods.
if(item.original_language == 'en'){
svg
.append('circle')
.attr('cx', x(item[attributeX]))
.attr('cy', y(item[attributeY]))
.attr('r', bubbleSize)
//.style('fill', 'rgba(50,50,50,0.2)')
//.style('fill', 'none')
.style('fill', 'rgba(70, 130, 180, 0.8)')
.style('stroke', 'white');
} else {
svg
.append('circle')
.attr('cx', x(item[attributeX]))
.attr("cy", y(item[attributeY]))
.attr("r", bubbleSize)
.style("fill", 'rgba(183, 134, 11, 0.8)')
.style('stroke', 'white');
}
});

return svg.node();
}
Insert cell
Insert cell
height = 600
Insert cell
margin = ({ top: 25, right: 20, bottom: 35, left: 80 })
Insert cell
radius = 10
Insert cell
activeArea = ({width: width - margin.left - margin.right - 2*radius,
height:height - margin.top - margin.bottom - 2*radius});
Insert cell
Insert cell
Insert cell
Insert cell
attributes = ["runtime", "budget", "revenue", "rating", "num_votes"]
Insert cell
movies = d3.csvParse(await FileAttachment("movies@3.csv").text(), d3.autoType)
Insert cell
import { table } from "@tmcw/tables/2"
Insert cell
function code(s) {
return html`<code style="white-space: nowrap;">${s}</code>`;
}
Insert cell
backgroundColor = "#ECEFF1"
Insert cell
import { select } from "@jashkenas/inputs"
Insert cell
d3 = require("d3@5")
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more