Dynamic Y-axis scale
Hello BIRT Experts,<br />
<br />
I am trying to adjust the y-axis of a report based on a report parameter. If the report parameter is greater than the default y-axis maximum, the y-axis maximum should be set to the parameter. Otherwise, the y-axis scale should keep its default formatting.<br />
<br />
I've made some progress with the following script (note that the y and x axes are inverted in this report):<br />
<br />
<pre class='_prettyXprint _lang-auto _linenums:0'>function beforeGeneration( chart, icsc )
{
// Force the y-axis scale to increase if load mark is greater than its default
yAxis1 = chart.primaryBaseAxes[0];
yScale1 = yAxis1.getScale();
if(icsc.externalContext.scriptable.getParameterValue("LoadMark") > yScale1.getMax())
{
yScale1.setMax(NumberDataElementImpl.create(icsc.externalContext.scriptable.getParameterValue("LoadMark")));
yAxis1.setScale(yScale1);
}
}</pre>
<br />
The problem I'm having is that yScale1.getMax() is returning nothing (I'm assuming it gets set later on in the chart rendering) and the y-scale ends up always being set to the report parameter. Which event function sets the y-axis min and max, and what would be the best way to work out this problem?<br />
<br />
Thanks for your help<br />
<br />
David
<br />
I am trying to adjust the y-axis of a report based on a report parameter. If the report parameter is greater than the default y-axis maximum, the y-axis maximum should be set to the parameter. Otherwise, the y-axis scale should keep its default formatting.<br />
<br />
I've made some progress with the following script (note that the y and x axes are inverted in this report):<br />
<br />
<pre class='_prettyXprint _lang-auto _linenums:0'>function beforeGeneration( chart, icsc )
{
// Force the y-axis scale to increase if load mark is greater than its default
yAxis1 = chart.primaryBaseAxes[0];
yScale1 = yAxis1.getScale();
if(icsc.externalContext.scriptable.getParameterValue("LoadMark") > yScale1.getMax())
{
yScale1.setMax(NumberDataElementImpl.create(icsc.externalContext.scriptable.getParameterValue("LoadMark")));
yAxis1.setScale(yScale1);
}
}</pre>
<br />
The problem I'm having is that yScale1.getMax() is returning nothing (I'm assuming it gets set later on in the chart rendering) and the y-scale ends up always being set to the report parameter. Which event function sets the y-axis min and max, and what would be the best way to work out this problem?<br />
<br />
Thanks for your help<br />
<br />
David
0
Comments
-
Forgot to post the working code. A report parameter, 'LoadMark', is used to draw a marker line in the chart. The script determines the maximum value of all datasets and forces the y-axis to be the value of LoadMark if LoadMark is greater than the dataset maximum. <br />
<br />
<pre class='_prettyXprint _lang-auto _linenums:0'>importPackage(Packages.org.eclipse.birt.chart.model.data.impl);
maxValue = 0;
/**
* Called before generation of chart model to GeneratedChartState.
*
* @param chart
* Chart
* @param icsc
* IChartScriptContext
*/
function beforeGeneration( chart, icsc )
{
// Force the y-axis scale to increase if the load mark is greater than its default
yAxis1 = chart.primaryBaseAxes[0];
yScale1 = yAxis1.getScale();
if (icsc.externalContext.scriptable.getParameterValue("LoadMark") > maxValue)
{
yScale1.setMax(NumberDataElementImpl.create(icsc.externalContext.scriptable.getParameterValue("LoadMark")));
yAxis1.setScale(yScale1);
}
}
/**
* Called before drawing each marker line in an Axis.
*
* @param axis
* Axis
* @param markerLine
* MarkerLine
* @param icsc
* IChartScriptContext
*/
function beforeDrawMarkerLine( axis, markerLine, icsc )
{
// Draw the LoadMark line if specified.
var loadMark = icsc.externalContext.scriptable.getParameterValue("LoadMark");
if (Number(loadMark) == 0)
markerLine.getLineAttributes().setVisible(false);
else
markerLine.setValue(NumberDataElementImpl.create(loadMark));
}
/**
* Called after populating the series dataset.
*
* @param series
* Series
* @param dataSet
* DataSet
* @param icsc
* IChartScriptContext
*/
function afterDataSetFilled( series, dataSet, icsc )
{
importPackage(Packages.java.io);
importPackage(Packages.org.eclipse.birt.chart.model.type.impl);
importPackage(Packages.org.eclipse.birt.chart.util);
importPackage(Packages.java.util);
ps = PluginSettings.instance();
dsp = ps.getDataSetProcessor(series.getClass());
if (dsp.getMaximum(dataSet) > maxValue)
{
maxValue = dsp.getMaximum(dataSet);
}
}
</pre>0 -
Yeah, I completely wasn't thinking right when I answered you above. I've posted examples getting the min and max this same way before. Sorry about that! Glad you got it done the right way despite me having a brain lapse! Feel free to post this as an example in the devShare, if you'd like!Warning No formatter is installed for the format ipb0
-
Actually, I just realized there's a mistake in afterDataSetFilled() - it will run through both the x and y axis for each dataset, so when the x-axis has larger numbers than the y axis, it won't work properly.
Is there a way to run getMaximum() on a single axis/component of a dataSet?0 -
Yeah. Wrap your getMax code in an if statement that checks the series:
if (series.eClass().getName().equals("Series 1")){
dsp = ps.getDataSetProcessor(series.getClass());
if (dsp.getMaximum(dataSet) > maxValue)
{
maxValue = dsp.getMaximum(dataSet);
}
}Warning No formatter is installed for the format ipb0 -
And one final thing - my chart is a flipped axis chart which seems to be causing some other issues (see attachment). In that chart, I've set the marker line to be at a value of 200 (and am using my workaround code to adjust the axis maximum accordingly). But when I check the maxValue variable in that code, it comes back as 745 and not 142 which makes me think it is looping through what appears to be the x-axis (but in reality is the y-axis in the chart, since the chart is flipped).
Is there a way to only check the one axis' value? Thanks for all the help on this one0 -
Did my last post not help you? In the above code, "Series" would be the x-axis and "Series 1" would be the first y-axis series. When you flip the axis, maybe that is switched. Let me know. If not, if you can recreate the issue with the sample database and post it in here, I'll do some testing.Warning No formatter is installed for the format ipb0
-
Sorry, I thought that was referring to the series name - didn't realize it was the eClass() property. I played around with it and checking if it equaled 'Series' was what I needed - this ignored what appeared to be the x-axis in my report and only ran through the y-axis values for all datasets.0
-
Hi,
I am trying to get the dynamic scale and the marker line based on the data set. X-axis seems to be working based on the series values but Y-axis does not. In the attached report, first chart has the code applied to X-axis scale and the second chart has the OnRender script applied to both X-axis and Y-axis.
Any idea why the dynamic scale logic is not working for the Y-axis?
Thanks
UYWarning No formatter is installed for the format ipb0 -
When I run your report, it appears to me that the second chart's axis values are set based on the min and max values of the data in both the x and y. Am I not understanding the issue?
Edit: Is it the scale you're wanting to be fixed?Warning No formatter is installed for the format ipb0 -
Hi Michael,<br />
<br />
The Y-axis scale should look into the min and max values of the "Series 1" and get the Y scale. That does not seem to happen with the code below. <br />
<br />
<pre class='_prettyXprint _lang-auto _linenums:0'>if (series.getSeriesIdentifier() == "Series 1"){
//(series.eClass().getName().equals("Series 1")){
dsp = ps.getDataSetProcessor( series.getClass() );
//dataset max
ymax = dsp.getMaximum( dataSet );
ymin = dsp.getMinimum( dataSet );
}</pre>
<br />
Not sure why the code is not reading the mimimum and maximum values of "Series 1".<br />
<br />
Thanks<br />
UYWarning No formatter is installed for the format ipb0 -
<p>Hello,</p>
<p> </p>
<p>I am trying to dynamically change the multiplier and suffix on the y-axis at run time.</p>
<p> </p>
<p>For example in a bar chart if the min value of the chart is in excess of £1m, to have the scale shown as £1m, £2m,.... but if the min and max values are between £1k and £1m to have the scale shown as £1k, £2k, .....</p>
<p> </p>
<p>How might I be able to code that in the beforeGeneration() function ?</p>
<p> </p>
<p>Many thanks</p>
0 -
<p>What version of BIRT are you using? Is this commercial BIRT, or open source BIRT?</p>
Warning No formatter is installed for the format ipb0 -
<p>You can also do this in the <em>beforeRendering</em> event:</p>
<pre class="_prettyXprint">
beforeRendering: function(options, chart)
{
if (chart.getYAxisMax() < 1000000)
options.yAxis[0].labels.formatter = function() {
return (this.value / 10000) + ' K';
};
else if (chart.getYAxisMax() > 1000000)
options.yAxis[0].labels.formatter = function() {
return (this.value / 1000000) + ' M';
};
},
</pre>
<p>Attached is a sample.</p>
<p> </p>
<p>In the future, please specify what version of BIRT you are using so that we can assist you more efficiently.</p>
Warning No formatter is installed for the format ipb0 -
<p>Clement Wong, </p>
<p> </p>
<p> </p>
<p>Qucik question: </p>
<p>what happens when you have secondary Y-axis. getYAxis just updates on primary -Yaxis. Any help would be appreciated. </p>
<p> </p>
<p>Thanks</p>
<p>Suresh</p>
0 -
<p><span style="font-family:'courier new', courier, monospace;">chart.getYAxisMax()</span> only works for the first Y axis.</p>
<p> </p>
<p>However, if you want to check on the max of the secondary axis, you can get its value via:</p>
<pre class="_prettyXprint">
chart.getCore().yAxis[1].max
</pre>Warning No formatter is installed for the format ipb0
Categories
- All Categories
- 108 Developer Announcements
- 53 Articles
- 106 General Questions
- 144 IM Services
- 43 OpenText Hackathon
- 32 Developer Tools
- 20.6K Analytics
- 4.1K AppWorks
- 8.9K Extended ECM
- 899 Cloud Fax and Notifications
- 77 Digital Asset Management
- 9.3K Documentum
- 29 eDOCS
- 120 Exstream
- 39.8K TeamSite
- 1.7K Web Experience Management