Interactive Line Chart
A Line Chart report is used to show one value compared to another, usually when the x-axis is time.
In most cases, bar charts are the preferred option if your x axis is something other than time.
An example can be found in the Wind Farm Wind Speed Display.
This is a more complex version of the Simple Line Chart, which does not have interactivity.
This overrides the updateTooltip function and calls tip on the interactive elements so that they will create tooltips when the mouse hovers over them.
It uses the getMouseAxisPos function (which is specific to SVG reports) to convert the mouse position into both the X and Y values of the chart that the mouse is hovering over.
Example
Description
You should replace the following…
Element | Replace With |
---|---|
[ASSET] | The name of the asset to display |
[PROPERTY] | The name of the property you want to report on |
[PLACES] | The maximum decimal places to show |
[UNITS] | The measurement units |
class ActiveReport extends SVGReport { initialise() { super.initialise(); this.property = '[PROPERTY]'; }; create() { this.singleQueryReport("'[ASSET]' ASSET '" + this.property + "' PROPERTY VALUES {\"grain\": -2000,%%} GETHISTORY"); } updateTooltip(ev) { var pos = this.getMouseAxisPos(this.x,this.y,ev.clientX,ev.clientY); var bi = d3.bisector(d => d[0]); var indx = bi.right(this.data,pos[0], 1); this.svgbase.select('.axismarker') .attr("x1",this.x(pos[0])) .attr("x2",this.x(pos[0])) .style("display",""); if (indx >= this.data.length) indx = this.data.length-1; var tt = "<table style=\"font-size: small;\"><tr><td colspan=\"2\" style=\"color: black;\">" + this.data[indx][0] + "<br/><br/></td></tr>"; for(var q=0;q<this.columns.length;q++) { tt += "<tr><td><div style=\"background-color: " + this.getSequenceColour(q) + "; border: 1px solid black; width: 20px; height: 20px;\"></div></td><td><label style=\"color: black;\">" + this.columns[q].name.replace(" " + this.property,"") + ": " + this.data[indx][q+1].toFixed([PLACES]) + " [UNITS]"; } tt += "</table>"; return tt; } draw(data) { //Get the SVG and sizing $('svg').html(""); var height = this.sizing[1]; var width = this.sizing[0]; //Calculate the min and max across all channels var xextent = d3.extent(data,d => d[0]); var yextent = d3.extent(data,d => d[1]); for(var q=0;q<this.columns.length;q++) { var ex = d3.extent(data,d => d[q+1]); if (ex[0] < yextent[0]) yextent[0] = ex[0]; if (ex[1] > yextent[1]) yextent[1] = ex[1]; } //Add a small buffer to the Y axis to add some padding var yspan = (yextent[1] - yextent[0]) * 0.08; if (yextent[0] != 0) { yextent[0] -= yspan; } if (yextent[1] != 0) { yextent[1] += yspan; } //Calculate the margin for the report var margin = {top: this.margin.top, left: 40,right: 20,bottom: 50}; var svgbase = this.svgbase; var svg = svgbase; //Create the X and Y axes var x = d3.scaleTime().domain(xextent).rangeRound([margin.left, width - margin.right]); var y = d3.scaleLinear().domain(yextent).rangeRound([height - margin.bottom,margin.top]); //Create an appropriate tick format var xTickFormat = x.tickFormat(null, "%H:%M, %-d %b %Y"); var yTickFormat = y.tickFormat(100,null); //Save the axes so the tooltip can access them this.x = x; this.y = y; //Draw a set of axes this.drawAxisSet(x,y,"Time","[PROPERTY] ([UNITS])",margin.left,margin.right,width,height,"main"); //Draw each of the lines for(var vx=1;vx<data[0].length;vx++) { svg.append("path") .datum(data) .attr("fill", "none") .attr("stroke", this.getSequenceColour(vx-1)) .attr("stroke-width", 2) .attr("stroke-linejoin", "round") .attr("stroke-linecap", "round") .attr("d", d3.line() .curve(d3.curveStep) .x(d => x(d[0])) .y(d => y(d[vx])) .defined(d => { if (isNaN(d[1])) return false; return true; } )) .style("pointer-events","none") .call(this.tip); } svg.select('#main') .call(this.tip); } }