123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111 |
- class Barchart extends Chart {
- constructor(customId) {
- super(customId);
- //////////
- // AXES //
- //////////
- this.x = d3.scaleLinear()
- .range([this.margin.left, this.width - this.margin.right]);
- this.y = d3.scaleBand()
- .rangeRound([this.height - this.margin.bottom, this.margin.top])
- .padding(0.1);
- this.xAxis = d3.axisBottom(this.x).ticks(10);
- this.yAxis = d3.axisLeft(this.y).ticks(0);
- this.svg.append("g")
- .attr('id', "axis--x-" + this.customId)
- .attr("transform", "translate(0," + (this.height - this.margin.bottom) + ")")
- .call(this.xAxis);
- this.svg.append("g")
- .attr('id', "axis--y-" + this.customId)
- // offset to right so ticks are not covered
- .attr("transform", "translate(" + (this.margin.left) + ",0)")
- .call(this.yAxis)
- /////////////
- // SPECIAL //
- /////////////
- this.labels = ["picked", "selected", "all"];
- d3.selectAll(".checkbox-" + this.customId).on("change", () => {
- this.draw();
- });
- }
- updateAndDraw(chartData) {
- let data = []
- for (const idx in chartData[0]) {
- let arr = chartData[0][idx];
- data.push({"name":arr.name,
- [this.labels[0]]:arr.value[0],
- [this.labels[1]]:arr.value[1],
- [this.labels[2]]:arr.value[2]});
- }
- this.data = data;
- this.draw();
- }
- draw() {
- // calculate max domain x
- let maxDomainXList = [0];
- d3.selectAll(".checkbox-" + this.customId).each((d, i, nodes) => {
- let checkbox = d3.select(nodes[i]);
- if(checkbox.property("checked")) {
- let group = checkbox.property("value");
- let maxVal = d3.max(this.data, (d) => {return d[group]; });
- maxDomainXList.push(maxVal);
- }
- });
- this.x.domain([0, d3.max(maxDomainXList)]);
- this.y.domain(this.data.map((d) => {return d.name; }));
- // redraw bars
- for (const idx in this.labels) {
- // draw group in reverse order (slice makes new array so original is not modified)
- let group = this.labels.slice().reverse()[idx];
- // ex: checkbox-barchart-picked
- let unchecked = !d3.select("#checkbox-"+ this.customId + "-" + [group]).property("checked");
- let bars = this.svg.selectAll(".bar-" + [group])
- .data(this.data);
- // new data (optical illusion animation, bars are inverse)
- bars
- .enter().append("rect")
- .attr("class", "bar-" + [group])
- .attr("y", (d) => { return this.y(d.name); })
- .attr("height", (d) => { return this.y.bandwidth(); })
- .attr("x", (d) => {
- if (unchecked) { return 0; }
- return this.x(d[group]); })
- .attr("width", (d) => {
- if (unchecked) { return 0; }
- return this.width - (this.x(d[group])); });
- bars.exit().remove();
- // updated data:
- bars.transition()
- .duration(750)
- .attr("y", (d) => { return this.y(d.name); })
- .attr("height", (d) => { return this.y.bandwidth(); })
- .attr("x", (d) => {
- if (unchecked) { return 0; }
- return this.margin.left })
- .attr("width", (d) => {
- if (unchecked) { return 0; }
- return this.x(d[group]) - this.margin.left; });
- }
- // update axes
- this.svg.select("#axis--y-" + this.customId).transition().duration(750).call(this.yAxis)
- this.svg.select("#axis--x-" + this.customId).transition().duration(750).call(this.xAxis)
- }
- }
|