====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 [[https://demo.optrix.com.au/s/ex/displaylist/info?report=windspeed|Wind Farm Wind Speed Display]]. This is a more complex version of the [[Simple Line Chart of a Property]], 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 = ""; for(var q=0;q
" + this.data[indx][0] + "

"; 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 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 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); } }