Line Chart - My first Zen Report - I see no line

Graph, ZEN, Other

Hello,

I started a post when I tried to display a line graph on a dashboard:

https://community.intersystems.com/post/dashboard-line-graph

This did not work very well. I switched gears and now I have a Zen Page that includes a Zen Report in iFrame. However my line chart does not display a line.

This is my Report class:

/// AETMON.Report
Class AETMON.Report Extends %ZEN.Report.reportPage
{

/// Class name of application this report belongs to.
Parameter APPLICATION;

/// Specifies the default display mode used for this report if
/// the URL parameter, <var>$MODE</var>, is not present.
Parameter DEFAULTMODE As STRING [ Constraint = ",html,tohtml,toxslfo,pdf,xml,xslfo,excel,toexcel,ps,pdfprint,xlsx,tiff,displayxlsx,fo2pdf,foandpdf", Flags = ENUM ] = "html";

/// This is the optional XML namespace used for the report.
Parameter REPORTXMLNAMESPACE;

Property Availability As %ZEN.Datatype.list(DELIMITER = ",");

Property AvaiDateTime As %ZEN.Datatype.list(DELIMITER = ",");

Property CreatedDate As %ZEN.Datatype.string(ZENURL = "CreatedDate");

/// This XML defines the logical contents of this report.
XData ReportDefinition [ XMLNamespace = "http://www.intersystems.com/zen/report/definition]
{
<report xmlns="http://www.intersystems.com/zen/report/definition"
 name="Report" 
 sql="SELECT ID, CreatedDate, CreatedTime, availabilityStatus FROM AETMON.AvailabilityLog WHERE CREATEDDATE=ORDER BY CreatedDate, CreatedTime">
<parameter expression='..CreatedDate'/>
<group name="CreatedDate" breakOnField="CreatedDate">
<attribute name="Date" field="CreatedDate" />
<group name="record">
<attribute name="id" field="ID" />
<attribute name="Time" field="CreatedTime" />
<attribute name="Status" field="availabilityStatus" />
</group>
<aggregate name="Count" type="SUM" field="availabilityStatus" />
</group>
</report>
}

/// This XML defines the display for this report.
/// This is used to generate the XSLT stylesheets for both HTML and XSL-FO.
XData ReportDisplay [ XMLNamespace = "http://www.intersystems.com/zen/report/display]
{
<report xmlns="http://www.intersystems.com/zen/report/display"
 name="Report" title="AET Availability Report">
<!-- Optional Init element inserts custom XSLT instructions at the top level of the generated XSLT stylesheet. -->
<init ></init>
<!-- Optional Document element specifies page layout and style characteristics. -->
<document width="8.5in" height="11in" marginLeft="1.25in" marginRight="1.25in" marginTop="1.0in" marginBottom="1.0in" ></document>
<!-- Optional Pageheader element. -->
<pageheader ></pageheader>
<!-- Optional Pagefooter element. Does not apply in HTML output. -->
<pagefooter ></pagefooter>
<!-- Required Body element. -->
<body>
<class="banner1">AET Availability Report</p>
<clineChart
ongetData="getchartdata"
title="Availability"
height="400px" width="400px"
currYAxis="0"
labelsVisible="true"
lineStyle="red"
markersVisible="true"
plotStyle="stroke-width: 1px;"
seriesCount="1"
seriesNames="Name1,Name2"
seriesSize="2"
seriesYAxes="0"
ongetLabelX="getAxisTime"
ongetLabelY="getAxisY"
>
<yAxis minValue="0" maxValue="1" />
</clineChart>
<group name="CreatedDate" line="1px">
<table orient="row" width="6in">
<item field="@Date" width="2in">
<caption value="Date:" width="2in"/>
</item>
<group name="record" line="1px">
<table orient="row" width="6in">
<item field="@Time" width="2in">
<caption value="Time:" width="2in"/>
</item>
<item field="@Status" >
<caption value="Status:"/>
</item>
</table>
</group>
</table>
</group>
</body>
</report>
}

Method getAxisTime(
val,
yseries)
{
Do ##class(AETMON.Utility).DebugAETMON("AETMON.Report getAxisTime(val = "_val_")")
Set tTime = $Piece(..AvaiDateTime,",",(val+1))
Quit $ZTime(tTime)
}

Method getAxisY(
var1,
var2,
var3)
{
Do ##class(AETMON.Utility).DebugAETMON("AETMON.Report getAxisY()")
Do ##class(AETMON.Utility).DebugAETMON("getAxisY var1 = "_var1)
Do ##class(AETMON.Utility).DebugAETMON("getAxisY var2 = "_var2)
Do ##class(AETMON.Utility).DebugAETMON("getAxisY var3 = "_var3)
If (var1 = 1) Quit "1"
If (var1 = 0) Quit "0"
Quit " "
}

Method getchartdata(
ByRef var,
chart)
{
Do ##class(AETMON.Utility).DebugAETMON("AETMON.Report getchartdata")
Try {
Set sc = $System.Status.OK()
Set tTestDate = "08/06/2019"
Set pFrom = $ZDateH(tTestDate)
Set pTo = $ZDateH(tTestDate)
// Get a resultset containing Availability data
Set sc = ##class(AETMON.AvailabilityLog).GetAvailability(pFrom,pTo,.rs)
Quit:$System.Status.IsError(sc)
Set tCount = 0
While (rs.%Next()) {
Do ##class(AETMON.Utility).DebugAETMON("AETMON.Report getchartdata tCount = "_tCount)
Set var(tCount,0) = rs.%Get("availabilityStatus")
Set var(tCount,1) = rs.%Get("CreatedTime")
If $Increment(tCount)
}
}
Catch(ex) {
Set sc = ex.AsStatus()
}
Set tCreatedTimes = var(0,1) _ "," _ var(1,1)
Do ##class(AETMON.Utility).DebugAETMON("AETMON.Report getchartdata ..AvaiDateTime = "_tCreatedTimes)
Set ..AvaiDateTime = tCreatedTimes
Quit sc
}

}
 

Can anybody tell me what I am missing or what I do wrong?

Thanks,

Oliver

 

 

  • 0
  • 0
  • 59
  • 3
  • 1

Answers

Hi Oliver.

It's hard to say what's wrong with your report, as example that you provided is not standalone -- it requires table AETMON.AvailabilityLog.

At least I think, you should change

Set var(tCount,0) = rs.%Get("availabilityStatus")
Set var(tCount,1) = rs.%Get("CreatedTime")

to

Set var(0, tCount) = rs.%Get("availabilityStatus")
Set var(1, tCount) = rs.%Get("CreatedTime")

You have seriesCount="1". That is amount of lines to show on chart.
Then you have seriesNames="Name1,Name2". These are names of lines. So either here you should have one name, or seriesCount should be 2.

You have seriesSize="2". This is amount of points to draw from each serie. If you indeed need only 2 points, then that's OK. However, if you remove this attribute then all points are plotted.

Generally, please see class reference for %ZEN.Report.Display.COSChart.cchart. It explains many attributes.

Below please find small sample that works. Ignore ReportDefinition. It's just there to make report run.

I hope it'll give you some hints.

Class community.ClineReport Extends %ZEN.Report.reportPage
{

Parameter DEFAULTMODE As STRING = "html";

/// This XML defines the logical contents of this report.
XData ReportDefinition [ XMLNamespace = "http://www.intersystems.com/zen/report/definition" ]
{
<report xmlns="http://www.intersystems.com/zen/report/definition"
   name="test" sql="select 1 q">
   <group name="q" breakOnField="q"/>
  </report>
}

/// This XML defines the display for this report.
/// This is used to generate the XSLT stylesheets for both HTML and XSL-FO.
XData ReportDisplay [ XMLNamespace = "http://www.intersystems.com/zen/report/display" ]
{
<report xmlns="http://www.intersystems.com/zen/report/display"
    name="test">
    <document width="8.5in"
            height="11in"
            marginLeft="1.25in"
            marginRight="1.25in"
            marginTop="1.0in"
            marginBottom="1.0in" />
    <body>
        <clineChart
                ongetData="getChartData"
                title="Availability"
                height="400px"
                width="400px"
                currYAxis="0"
                labelsVisible="true"
                lineStyle="red"
                markersVisible="true"
                plotStyle="stroke-width: 1px;"
                seriesCount="2"
                seriesNames="Name1,Name2"
                seriesYAxes="0"
                ongetLabelX="getAxisTime"
                >
            <yAxis minValue="0"
                    maxValue="100" />
        </clineChart>
    </body>
</report>
}

Method getChartData(
    ByRef data,
    chartObject)
{
    for i=1:1:10 {
        set data(0,i-1)=i * 2
        set data(1,i-1)=i * 3
    }
}

Method getAxisTime(
    val,
    yseries)
{
 quit $zdt($H-100 + val)
}

}

Alexander,

Thank you for your response. I understand that get data method only needs to return the Y-Axis values. In my case they will be 0 if the system I monitor is down or 1 if the status is good. I envision I may calculate a Uptime % per time selected by user later. Actually very soon. I need to demo this today.

The values for x-Axis, Date/Time stamp when system status was checked, are supplied by a separate method.

Do you think it is good to try and store values for x and y-Axes in the same data array?

I will post another update soon after I get a chance to try it out.

Oliver

I understand that get data method only needs to return the Y-Axis values

Yes!

Do you think it is good to try and store values for x and y-Axes in the same data array?

No, keeping values in getChartData and labels for X axis in getAxisTime is fine.

Alexander,

I still get no line even though everything else seems correct from what I can tell on my end. I do a lot of debugging / logging and I observe getAxisY and getAxisTime are called way more often than what seems necessary...