====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 = "" + this.data[indx][0] + "
";
for(var q=0;q
";
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);
}
}