Live Barchart of All Properties
A Barchart report is used to show either current values or total values.
Where possible, it's usually a good idea to ensure that the asset axis (the x-axis in this report) has some kind of logical order, which is where the barchart across a relationship can be very useful.
An example can be found in the Drive Current Live Values Infographic.
Example
Description
You should replace the following…
Element | Replace With |
---|---|
[PROPERTY] | The name of the property you want to report on |
[PROPERTYID] | The ARDI ID number of the property you want to report on |
[MINVALUE] | The minimum value you want to display |
[MAXVALUE] | The maximum value you want to display |
[PLACES] | The maximum decimal places to show |
[UNITS] | The measurement units |
class ActiveReport extends SVGReport { initialise() { super.initialise(); this.first = true; }; create() { this.liveReport("'[PROPERTY]' ALLPOINTS"); } update() { this.draw(report.livedata); } draw(data) { //Establish the size of the report. var margin = {top: 60, right: 40, bottom: 40, left: 150}; var height = this.sizing[1]; var width = this.sizing[0]; //Setup variables var min = [MINVALUE]; var max = [MAXVALUE]; var svg = this.svgbase; //Prepare the data to display var finaldata = []; for(var q=0;q<data.length;q++) { finaldata.push({name: this.columns[q].name,value: parseFloat(data[q])}); } if (this.first == true) { //The first time we run, set up the display. $('#reportsvg').html(""); //Create a group inside the margins. var group = svg.append("g") .attr("transform","translate(" + margin.left + " " + margin.top + ")"); svg = group; width = width - (margin.left + margin.right); height = height - (margin.top + margin.bottom); //Create the X axis var x = d3.scaleLinear() .domain([[MINVALUE], [MAXVALUE]]) .range([ 0, width]); //Draw the X axis svg.append("g") .attr("transform", "translate(0," + height + ")") .call(d3.axisBottom(x)) .selectAll("text") .attr("transform", "translate(-10,0)rotate(-45)") .style("text-anchor", "end"); // Create the Y axis var y = d3.scaleBand() .range([ 0, height ]) .domain(finaldata.map(d => d.name.replace("[PROPERTY]",""))) .padding(.1); //Draw the Y axis svg.append("g") .call(d3.axisLeft(y)) //Save the things we've created so they can be re-used later. this.svg = group; this.first = false; this.x = x; this.y = y; } this.multiplier = Math.pow(10,[PLACES]); var context = this; //Draw the bars this.svg.selectAll(".bar") .data(finaldata) .join( enter => enter.append("rect") .attr("class","bar element") .attr("x", function(d) { return context.x(Math.min(0,d.value)); }) .attr("width",0) .attr("y", function(d) { if (isNaN(d.value)) return context.y(d.name.replace("[PROPERTY]","")) + (context.y.bandwidth()/4); return context.y(d.name.replace("[PROPERTY]","")); }) .attr("height", function(d) { if (isNaN(d.value)) return context.y.bandwidth()/2; return context.y.bandwidth(); }) .attr("fill", function(d) { if (isNaN(d.value)) return 'purple'; var clr = MapColour[PROPERTYID](d.value); if (d.value == minvalue) return d3.color(clr).darker(0.5).formatHex(); if (d.value == maxvalue) return d3.color(clr).brighter(0.5).formatHex(); return clr; }) .attr("name",function(d) { return d.name.replace("[PROPERTY]",""); }) .attr("value",function(d) { return Math.round(d.value * context.multiplier) / context.multiplier; }) .attr("units","[UNITS]") .call(this.tip) .transition() .duration(1000) .attr("width", function(d) { if (isNaN(d.value)) return width; return context.x(Math.abs(d.value)) - context.x(0); }), update => update .transition() .duration(500) .attr("y", function(d) { if (isNaN(d.value)) return context.y(d.name.replace("[PROPERTY]","")) + (context.y.bandwidth()/4); return context.y(d.name.replace("[PROPERTY]","")); }) .attr("height", function(d) { if (isNaN(d.value)) return context.y.bandwidth()/2; return context.y.bandwidth(); }) .attr("width",function(d) { if (isNaN(d.value)) return width; return context.x(Math.abs(d.value)) - context.x(0); }) .attr("x", function(d) { return context.x(Math.min(0,d.value)); }) .attr("fill", function(d) { if (isNaN(d.value)) return 'purple'; var clr = MapColour[PROPERTYID](d.value); if (d.value == minvalue) return d3.color(clr).darker(0.5).formatHex(); if (d.value == maxvalue) { return d3.color(clr).brighter(0.5).formatHex(); } return clr; }) ) //Draw the values, but only when there are a reasonable number of bars. if (this.columns.length < 50) { this.svg.selectAll(".values") .data(finaldata) .join( enter => enter.append("text") .attr("class","values") .attr("x", 0 ) .attr("y", function(d) { return context.y(d.name.replace("[PROPERTY]","")) + 10; }) .attr("fill", "white") .attr("opacity",0) .attr("text-anchor",function(d) { var cx = x(d.value); if (cx < 100) return "start"; return "end"; }) .attr("alignment-baseline","hanging") .transition() .duration(1000) .attr("x", function(d) { var cx = context.x(d.value); if (cx < 100) return cx + 10; return cx - 10; }) .attr("opacity",1) .text(function(d) { if (isNaN(d.value)) return ""; return (Math.round(d.value * context.multiplier) / context.multiplier) + "[UNITS]"; }), update => update .attr("text-anchor",function(d) { var cx = context.x(d.value)-10; if (cx < 100) return "start"; return "end"; }) .transition() .duration(500) .attr("opacity",1) .attr("x", function(d) { var cx = context.x(d.value); if (cx < 100) return cx + 10; return cx - 10; }) .text(function(d) { if (isNaN(d.value)) return ""; return (Math.round(d.value * context.multiplier) / context.multiplier) + "[UNITS]"; }) ) } } }