-
Notifications
You must be signed in to change notification settings - Fork 16
/
imdb-legend-click.js
110 lines (96 loc) · 2.96 KB
/
imdb-legend-click.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
function visualize(data) {
data = data.filter(d => d.IMDB_Rating > 0 & d.Rotten_Tomatoes_Rating > 0);
let scales = make_scales(data)
initialize(data, scales);
}
function initialize(data, scales) {
d3.select("#circles")
.selectAll("circle")
.data(data, d => d.Title).enter()
.append("circle")
.attrs({
opacity: 1,
r: 2,
cx: d => scales.x(d.IMDB_Rating),
cy: d => scales.y(d.Rotten_Tomatoes_Rating),
fill: d => scales.fill(d.Genre_Group)
})
annotations(scales)
legend(scales.fill)
}
function legend(scale) {
let legend = d3.legendColor()
.title("Genre")
.scale(scale);
d3.select("#legend")
.attr("transform", `translate(${0.7 * width}, ${margins.top})`)
.call(legend);
d3.select("#legend .legendCells")
.selectAll(".cell")
.on("click", (ev, d) => toggle_selection(ev, d))
}
function toggle_selection(ev, d) {
let ix = selected.indexOf(d)
if (ix == -1) {
selected.push(d);
} else {
selected.splice(ix, 1)
}
update_view()
}
function update_view() {
d3.select("#circles")
.selectAll("circle")
.transition()
.duration(500)
.attrs({
opacity: d => selected.indexOf(d.Genre_Group) == -1 ? 0.4 : 1,
r: d => selected.indexOf(d.Genre_Group) == -1 ? 1 : 2
})
d3.select(".legendCells")
.selectAll("rect")
.attr("opacity", (d) => selected.indexOf(d) == -1 ? 0.4 : 1)
d3.select(".legendCells")
.selectAll("text")
.attr("opacity", (d) => selected.indexOf(d) == -1 ? 0.4 : 1)
}
function annotations(scales) {
let x_axis = d3.select("#axes").append("g")
y_axis = d3.select("#axes").append("g"),
x_title = d3.select("#axes").append("text"),
y_title = d3.select("#axes").append("text");
x_axis.attr("transform", `translate(0, ${height - margins.bottom})`)
.call(d3.axisBottom(scales.x).ticks(4))
y_axis.attr("transform", `translate(${margins.left}, 0)`)
.call(d3.axisLeft(scales.y).ticks(4))
x_title.text("IMDB")
.attrs({
class: "label_title",
transform: `translate(${0.5 * width}, ${height - 0.25 * margins.bottom})`,
})
y_title.text("Rotten Tomatoes")
.attrs({
class: "label_title",
transform: `translate(${0.25 * margins.left}, ${0.5 * height})rotate(-90)`
});
}
function make_scales(data) {
return {
x: d3.scaleLinear()
.domain(d3.extent(data.map(d => d.IMDB_Rating)))
.range([margins.left, 0.7 * width - margins.right]),
y: d3.scaleLinear()
.domain(d3.extent(data.map(d => d.Rotten_Tomatoes_Rating)))
.range([height - margins.bottom, margins.top]),
fill: d3.scaleOrdinal()
.domain([... new Set(data.map(d => d.Genre_Group))])
.range(d3.schemeSet3)
}
}
let width = 700,
height = 500,
selected = ["Drama", "Other", "Musical", "Comedy", "Action", "Romantic Comedy",
"Adventure", "Thriller/Suspense", "Horror"],
margins = {left: 60, right: 60, top: 60, bottom: 60};
d3.csv("movies.csv", d3.autoType)
.then(visualize);