-
Notifications
You must be signed in to change notification settings - Fork 0
/
histogram.html
132 lines (103 loc) · 4.1 KB
/
histogram.html
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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
<!DOCTYPE html>
<meta charset="utf-8">
<!-- Load d3.js -->
<script src="https://d3js.org/d3.v4.js"></script>
<!-- Create a div where the graph will take place -->
<div id="my_dataviz"></div>
<p>
<label>Change number of bins</label>
<input type="number" min="1" max="100" step="10" value="20" id="nBin">
</p>
<script>
// set the dimensions and margins of the graph
var margin = {top: 10, right: 30, bottom: 30, left: 40},
width = 480 - margin.left - margin.right,
height = 400 - margin.top - margin.bottom;
// append the svg object to the body of the page
var svg = d3.select("#my_dataviz")
.append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform",
"translate(" + margin.left + "," + margin.top + ")");
// get the data
d3.csv("https://raw.githubusercontent.com/IsaacMwendwa/dataViz/main/a1-cars.csv", function(data) {
// Defining graph title and axis labels
const xAxisLabel = "Number of Cylinders";
const yAxisLabel = "Frequency";
const title = `Histogram showing ${yAxisLabel} of ${xAxisLabel} of Car Engines`;
//Create Title
svg.append("text")
.attr("x", width / 2 )
.attr("y", 0)
.style("text-anchor", "middle")
.text(title);
//Create X axis label
svg.append("text")
.attr("x", width / 2 )
.attr("y", height + margin.bottom)
.style("text-anchor", "middle")
.text(xAxisLabel);
//Create Y axis label
svg.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 0-margin.left)
.attr("x",0 - (height / 2))
.attr("dy", "1em")
.style("text-anchor", "middle")
.text(yAxisLabel);
// X axis: scale and draw:
var x = d3.scaleLinear()
.domain([0, 10]) // can use this instead of 1000 to have the max of data: d3.max(data, function(d) { return +d.price })
.range([0, width]);
svg.append("g")
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(x));
// Y axis: initialization
var y = d3.scaleLinear()
.range([height, 0]);
var yAxis = svg.append("g")
// A function that builds the graph for a specific value of bin
function update(nBin) {
// set the parameters for the histogram
var histogram = d3.histogram()
.value(function(d) { return d.Cylinders; }) // I need to give the vector of value
.domain(x.domain()) // then the domain of the graphic
.thresholds(x.ticks(nBin)); // then the numbers of bins
// And apply this function to data to get the bins
var bins = histogram(data);
// Y axis: update now that we know the domain
y.domain([0, d3.max(bins, function(d) { return d.length; })]); // d3.hist has to be called before the Y axis obviously
yAxis
.transition()
.duration(1000)
.call(d3.axisLeft(y));
// Join the rect with the bins data
var u = svg.selectAll("rect")
.data(bins)
// Manage the existing bars and eventually the new ones:
u
.enter()
.append("rect") // Add a new rect for each new elements
.merge(u) // get the already existing elements as well
.transition() // and apply changes to all of them
.duration(1000)
.attr("x", 1)
.attr("transform", function(d) { return "translate(" + x(d.x0) + "," + y(d.length) + ")"; })
.attr("width", function(d) { return x(d.x1) - x(d.x0) -1 ; })
.attr("height", function(d) { return height - y(d.length); })
.style("fill", "#69b3a2")
// If less bar in the new histogram, I delete the ones not in use anymore
u
.exit()
.remove()
}
// Initialize with 20 bins
update(20)
// Listen to the button -> update if user change it
d3.select("#nBin").on("input", function() {
update(+this.value);
});
});
</script>