wefra/lib/d3-v6-oop/gauge_chart.js

146 lines
6.6 KiB
JavaScript
Raw Normal View History

//'use strict';
GaugeChart = {
init: function(url, html_tag_attr, current_accessor, min_accessor, max_accessor, width=200, height=145, colors=["#d7191c", "#efef5d", "#1a9641"]){
//var self = this;
this.url = url;
this.html_tag_attr = html_tag_attr;
this.width = 200;
this.height = 145;
this.current_accessor = current_accessor;
this.min_accessor = min_accessor;
this.max_accessor = max_accessor;
this.arcMin = -Math.PI/2;
this.arcMax = Math.PI/2;
this.innerRadius = 60;
this.outerRadius = 90;
this.labelPad = 10;
this.dataValue = function(d) { return +d; };
this.colorOptions = colors;
this.arc = d3.arc();
this.render();
this.update();
setInterval(this.update.bind(this), 30 * 1000);
},
prepare_data: function(){
var self = this;
return d3.json(urlRoot+this.url, config_requestArguments).then(function(dataset){
self.min = self.min_accessor(dataset);
self.max = (self.max_accessor(dataset)>0)?self.max_accessor(dataset):1;
self.current = self.current_accessor(dataset);
self.ave_min_max = ( Number(self.min) + Number(self.max) ) / 2;
self.dataDomain = [self.min, self.ave_min_max, self.max];
self.svg.datum([self.current]);
});
},
render: function(){
this.svg = d3.select(this.html_tag_attr).append("svg");
},
update: function(){
var self = this;
this.prepare_data().then(function(){
self.svg.each(function(data) {
// Convert data to standard representation greedily;
// this is needed for nondeterministic accessors.
data = data.map(function(d) { return self.dataValue(d); });
var arcScale = d3.scaleLinear().domain(self.dataDomain).range([self.arcMin, 0, self.arcMax]);
var colorScale = d3.scaleLinear().domain(self.dataDomain).range(self.colorOptions);
var arc = d3.arc().innerRadius(self.innerRadius)
.outerRadius(self.outerRadius)
.startAngle(self.arcMin);
// Select the svg element, if it exists.
var svg = d3.select(this).selectAll("svg").data([data]);
// Otherwise, create the skeletal chart.
var gEnter = svg.enter().append("svg").append("g");
var arcGEnter = gEnter.append("g").attr("class", "arc");
arcGEnter.append("path").attr("class", "bg-arc");
arcGEnter.append("path").attr("class", "data-arc")
.datum({endAngle: self.arcMin, startAngle: self.arcMin, score: self.dataDomain[0]})
.attr("d", arc)
.style("fill", colorScale(self.dataDomain[0]))
.each(function(d) { this._current = d; });
arcGEnter.append("text").attr("class", "arc-label");
arcGEnter.append("text").attr("class", "arc-min-label");
arcGEnter.append("text").attr("class", "arc-max-label");
// Update the outer dimensions.
//svg = self.svg.select("svg").attr("viewBox", '0 0 ' + self.width + ' ' + self.height);
svg = self.svg.select("svg");
svg.attr("viewBox", '0 0 ' + self.width + ' ' + self.height);
svg.select("g.arc").attr("transform", "translate(" + (self.width / 2) + "," + (self.outerRadius + ((self.outerRadius * 2) - self.height) / 2) + ")");
svg.select("g.arc .bg-arc")
.datum({endAngle: self.arcMax})
//.style("fill", "#ddd")
.attr("d", arc);
// https://bl.ocks.org/mbostock/1346410
function arcTween(a) {
var i = d3.interpolate(this._current, a);
this._current = i(0);
return function(t) {
return arc(i(t));
};
}
svg.select("g.arc .data-arc")
.datum({score: data[0], startAngle: self.arcMin, endAngle: arcScale(data[0])})
.transition()
.duration(750)
.style("fill", function(d) { return colorScale(d.score); })
.style("opacity", function(d) { return d.score < self.dataDomain[0] ? 0 : 1; })
.attrTween("d", arcTween);
var label_radius = (self.innerRadius + (self.outerRadius - self.innerRadius) / 2);
var angle_min_label = self.arcMin - (Math.PI/15);
var angle_max_label = self.arcMax + (Math.PI/15);
svg.select("text.arc-min-label")
.attr('x', (label_radius * Math.sin(angle_min_label)))
.attr('y', -(label_radius * Math.cos(angle_min_label)))
.style("alignment-baseline", "central")
.style("text-anchor", "middle")
.attr('font-size', '10px')
.attr('stroke', 'white')
.text(d3.format(".2s")(self.min));
svg.select("text.arc-max-label")
.attr('x', (label_radius * Math.sin(angle_max_label)))
.attr('y', -(label_radius * Math.cos(angle_max_label)))
.style("alignment-baseline", "central")
.style("text-anchor", "middle")
.attr('font-size', '10px')
.attr('stroke', 'white')
.text(d3.format(".2s")(self.max));
svg.select("text.arc-label")
.datum({score: data[0]})
.attr("x", 0)
.attr("y", 0)
.style("alignment-baseline", "central")
.style("text-anchor", "middle")
.style("font-size", "20px")
.attr('stroke', 'white')
.text(function(d) { return d3.format(",.2f")(d.score); });
});
});
},
};
get_gauge = function(url, html_tag_attr, current_accessor, min_accessor, max_accessor, colors=["#d7191c", "#efef5d", "#1a9641"], width=300, height=145){ //FIX width et height n'ont aucune influence sur le graphic
var my_gauge = {};
Object.assign(my_gauge, GaugeChart);
my_gauge.init(url, html_tag_attr, current_accessor, min_accessor, max_accessor, width, height, colors);
return my_gauge;
};
//1. Bringing D3JS, what prices for training Giliana, find a small business case
//2. What kind of synergie can be with Microsoft Dynamics?
//3. If definitely to visit their at