-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathBarChartModule.js
154 lines (132 loc) · 5.07 KB
/
BarChartModule.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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
'use strict';
// Note: This grouped bar chart is based off the example found here:
// https://bl.ocks.org/mbostock/3887051
var BarChartModule = function(fields, canvas_width, canvas_height, sorting, sortingKey) {
// Create the overall chart div
var chart_div_tag = "<div class='bar chart' width='" + canvas_width + "'></div>";
var chart_div = $(chart_div_tag)[0];
$("#elements").append(chart_div);
// Create the tag:
var svg_tag = "<svg width='" + canvas_width + "' height='" + canvas_height + "' ";
svg_tag += "style=' '></svg>";
// Append it to #elements
var svg_element = $(svg_tag)[0];
chart_div.append(svg_element);
//create the legend
var legend_tag = "<div class='legend'></div>";
var legend_element = $(legend_tag)[0];
chart_div.append(legend_element);
var legend = d3.select(legend_element)
.attr("style","display:block;width:"
+ canvas_width + "px;text-align:center")
legend.selectAll("span")
.data(fields)
.enter()
.append("span")
.html(function(d){
return "<span style='color:" + d["Color"] +";'> ⬤</span>" + " " +
d["Label"].replace(" ", " ")
})
.attr("style", "padding-left:10px;padding-right:10px;")
// setup the d3 svg selection
var svg = d3.select(svg_element)
var margin = {top: 20, right: 20, bottom: 30, left: 40}
var width = +svg.attr("width") - margin.left - margin.right
var height = +svg.attr("height") - margin.top - margin.bottom
var g = svg.append("g").attr("transform", "translate(" + margin.left + "," + margin.top + ")");
// Setup the bar chart
var x0 = d3.scaleBand()
.rangeRound([0, width])
.paddingInner(0.1);
var x1 = d3.scaleBand()
.padding(0.05);
var y = d3.scaleLinear()
.rangeRound([height, 0]);
var colorScale = d3.scaleOrdinal(fields.map(field => field["Color"]));
var keys = fields.map(f => f['Label'])
var chart = g.append("g")
var axisBottom = g.append("g")
var axisLeft = g.append("g")
axisBottom
.attr("class", "axis")
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(x0));
axisLeft
.attr("class", "axis")
.call(d3.axisLeft(y).ticks(null, "s"))
//Render step
this.render = function(data){
//Axes
var minY = d3.min(data, function(d){
return d3.min(keys, function(key){
return d[key];
})
})
if(minY > 0){
minY = 0;
}
var maxY = d3.max(data, function(d){
return d3.max(keys, function(key){
return d[key];
})
})
x0.domain(data.map(function(d, i) { return i }));
x1.domain(keys).rangeRound([0, x0.bandwidth()]);
y.domain([minY,maxY]).nice();
if(data.length > 1){
axisBottom
.attr("transform", "translate(0," + y(0) + ")")
.call(d3.axisBottom(x0))
}
axisLeft.call(d3.axisLeft(y).ticks(null, "s"))
//Sorting
if(sorting != "none"){
if(sorting == "ascending"){
data.sort((a, b) => b[sortingKey] - a[sortingKey]);
} else if (sorting == "descending") {
data.sort((a, b) => a[sortingKey] - b[sortingKey]);
}
}
//Draw Chart
var rects = chart
.selectAll("g")
.data(data)
.enter().append("g")
.attr("transform", function(d, i) { return "translate(" + x0(i) + ",0)"; })
.selectAll("rect")
rects
.data(function(d) {
return keys.map(function(key) {
return {key: key, value: d[key]};
});
})
.enter()
.append("rect")
.attr("x", function(d) { return x1(d.key); })
.attr("width", x1.bandwidth())
.attr("fill", function(d) { return colorScale(d.key); })
.attr("y", function(d) { return Math.min(y(d.value),y(0)); })
.attr("height", function(d) { return Math.abs(y(d.value) - y(0)); })
.append("title")
.text(function (d) { return d.value; })
//Update chart
chart
.selectAll("g")
.data(data)
.selectAll("rect")
.data(function(d) {
return keys.map(function(key) {
return {key: key, value: d[key]};
});
})
.attr("y", function(d) { return Math.min(y(d.value),y(0)); })
.attr("height", function(d) { return Math.abs(y(d.value) - y(0)); })
.select("title")
.text(function (d) { return d.value; })
}
this.reset = function(){
chart.selectAll("g")
.data([])
.exit().remove();
}
}