JasperReports customize series labels based on a value other than the Category value - jasper-reports

I have a JasperReport with a line chart that I need to display labels on, but I want them to display conditionally for each data point. I've created the customizer class to actually display the value, but I want to use a different field than the value field to decide if it should display or not.
Basically in my DataSet I have 3 fields:
Date: (Category Axis)
Value: (Value Axis)
PrintValue: Boolean field
I want to print the Value in the label only when PrintValue=true

One solution would be to override one of the methods implemented by JRDefaultScriptlet in a scriptlet class, then set the value of "PrintValue" in any manner you desire. Then in your chart dataset you should be able to reference $V{PRINTVALUE} as an operand.
I'm going to assume your using iReport for your report design.
Open your report in iReport and click the report name (Top most node in the report Inspector)
Set the Scriplet class to your package name and class, e.g., org.company.scriptlets.MyChartClass
Declare your report variable in iReport. In this case "PRINTVALUE" would be the variable name.
Create a java class that overrides a scriplet method, like beforeDetailEval, e.g.,:
#Override
public void beforeDetailEval() throws JRScriptletException {
super.beforeDetailEval();
...
this.setVariableValue("PRINTVALUE", true);
}
Since you want to display the category label conditionally for each tick mark, you'll probably need to use a Map of key/val pairs. key would be category label, value would be true/false for "PRINTVALUE". Note I did NOT illustrate this in the sample code above but its entirely possible. Just declare your report variable as a Map, e.g., HashMap<String, Boolean> hm.
You'll need to add your new scriplet class to the Classpath in iReport.
Hope this helps or at least gets you started.

Related

How do you add data bars to a chart via Java?

On startup, I'm trying to add a varying quantity of values to a barchart. I have an agent type Component. It has a few variables associated with it, one being hopperLevel. I create multiple Component agents based on an Excel sheet that assigns values to these variables. The number of Component agents created depends on the number of rows filled out on the Excel sheet. As the simulation runs, hopperLevel changes and I'd like to chart components(0).hopperLevel, components(1).hopperLevel, components(2).hopperLevel, etc. for all components.
I've tried the addDataItem method in the On startup field like this:
for ( Component comp : components )
{
chartHopperLevels.addDataItem(comp.hopperLevel, comp.componentName, blue);
}
but get the error:
"The method addDataItem(DataItem, String, Color) in the type BarChart is not applicable for the arguments (int, String, Color)"
I understand that an int isn't a DataItem, but I'm not sure what a DataItem is.
How do I use this method? Or is there a better way?
You cannot directly refer to an value in the addDataItem() function. This is because Java cannot monitor a value and do something if it changes.
Instead, AnyLogic has defined the DataItem which contains more or less only an update function which gets triggered and then pulls a new version of your value. The trigger can be automatically (setting Update data automatically in your chart) or manually (DataItem.update()). This update function is custom build for every value that you want to monitor.
You can build such a custom DataItem/update function (here: for variable myVariable) in the Additional class code in main:
public class MyDataItem extends DataItem{
#Override
public void update(){
super.setValue(myVariable);
}
}
You can the initialise your custom version of the DataItem like this:
DataItem di = new MyDataItem();
And finally you can add it (like you already did) to your barchart:
chart.addDataItem(di, "my value", red);
you need to read and understand the API on creating a DataItem first, see the AnyLogic help.
You can create a DataItem as below:
DataItem myItem = new DataItem();
myItem.setValue(12);
chart.addDataItem(myItem, "cool", Color.blue);
So you create a separate DataItem object first and then set its value to something you like. Then, you can add that to your bar chart (which is called "chart" in my example code above).
cheers

Adding a form filter

I'm currently working on a form in Microsoft Dynamics AX.
The form consists of a grid with about 10 fields from 4 different tables.
As the form is now it returns too many values so I need to include some sort of filter, it doesn't need to be dynamic, just a static filter saying only show the lines with value X in column Y.
Has anyone here got some experience with this sort of thing? Where do I start?
I must say I'm not experienced with Microsof AX at all, I've been working with it for about a month now.
I've tried to follow this guide: How to: Add Filter Controls to a Simple List Form [AX 2012]
But I got stuck at the second part (To add a control to the custom filter group) Step 2: I dont know which type of control to chose, and ik i pick lets say a ComboBox i cant get Step 3 to work because I dont see the 'Override Methods' they mention.
Well, I usually do it this way:
In ClassDeclaration, create as many QueryBuildRanges variables as fields to filter. Let's name them Criteria1, Criteria2, etc (name them properly, please, not as here)
QueryBuildRange criteria1, criteria2;
In each Datasource you need to filter, override method Init, an add code similar to this:
super();
criteria1 = this.query().datasource(tablenum(tableofdatasource)).addQueryRange(fieldNum(fieldtofilter))
//criteria1.status(RangeStatus::locked); //optional - this way you can hide filter field to user, have it readonly for users, etc
Create a control of type StringEdit or ListBox in form to be used as filter. Change their AutoDeclaration property to Yes. Override modified() method. In it, I use to put something similar to:
super();
element.changeFilters();
In form, add method changeFilters();
range rangeFromStringControl = StringEditControlName.text(); //Put in rangeFromStringControl the string to be used as filter, as a user would write it
range rangeFromListBoxControl;
criteria1.value(rangeFromStringControl);
switch (listBoxControl.Selection())
{
case NoYesAll::All:
rangeFromListBoxControl = ''; //Empty filter string - No filter at all
break;
case NoYesAll::No:
rangeFromListBoxControl = QueryValue(NoYes::No); //Or whatever string filter value you want
break;
//Etc
}
//We have all filter strs done; let's filter for each main DataSource required with new filters
DataSource1.executeQuery();
//If there is other datasources joined to this one, it's usually no necessary to call their executeQuery;
//If there are others with filters and not joined to it, call their executeQuery()
If you need this filter to be applied when form is open, set appropiate initial values to controls, and then in form's run() method:
run();
element.changeFilters();

How to pass the parameter from one subreport to another subreport

I am newbie and I'm designing my report using iReport 4.5.
I have a main report (MainReport) and three subreports (Sub1, Sub2, Sub3)
In Sub1 I have three summary variables say presentPayable, presentPayment, balance
In Sub2 I have one summary variable say totalCost
I need to use the summary variables of Sub1, Sub2 in my Sub3.
How can I do this? Is this possible to pass the variables from one subreport to another?
Otherwise please provide me any alternate to do this.
To pass a value from a subreport to its parent, the parent must first have a variable to receive the value. In your case the main report should have 4 variables, one each for presentPayable, presentPayment, balance, and totalCost.
Next you need to add a returnValue element to the subreport element in the main report. This element maps a variable in the subreport to a variable in this report using the attributes subreportVariable and toVariable.
To do this in iReport, click on your subreport element in the main report. In the properties list, click on Return Values. A dialog should appear. Click on the Add button. Type the name of the subreport variable and select the variable in this report that you would like it to be transferred to. You should leave the calculation type as "Nothing", which will instruct jasper to simply overwrite the variable with the new value. Click Ok to add this, then repeat for the other variables/subreports.
Now when you run the report, each time the subreport has completed processing, the current value of the variable in the subreport is passed back to the specified variable in the main report.
To use that value in another subreport, you need to pass the variable from the main report to the other subreport as a parameter. This has two parts: Adding a subreportParameter to the subreport element in the parent report, and adding a parameter to the subreport itself.
In iReport, click on your subreport element in the main report. In the properties list, click on Parameters. In the dialog that appears, click the Add button. Give the parameter a name (e.g. presentPayable) and input a value expression that references the variable in your main report (e.g. $V{presentPayable}). Repeat this for each of the variables that you want to pass in.
Next, open your subreport. In the report inspector, right-click on Parameters. Select Add Parameter, then rename the new parameter to match the name you entered in the previous step.
In the subreport, you should now be able to reference these values like any other parameter (e.g. $P{presentPayable}).

create bar chart with expression as values

I usually create chart with Passing map object from Java code and in iReport using sub data set I create the chart.
Now I need to create a bar chart from calculated values of other fields of same report. For example one of the text box calculated value is
new java.lang.Double((Double.valueOf( $P{REPORT_PARAMETERS_MAP}.get("budget_labour_cost").toString()).doubleValue())
+ (Double.valueOf( $P{REPORT_PARAMETERS_MAP}.get("budget_ico_cost").toString()).doubleValue())
+ (Double.valueOf( $P{REPORT_PARAMETERS_MAP}.get("budget_subcon_cost").toString()).doubleValue())
+ (Double.valueOf( $P{REPORT_PARAMETERS_MAP}.get("budget_oth_purchase_cost").toString()).doubleValue())
)
I need to use the result of the expression in one bar of bar chart.
You can still use a dataset; simply collect the results of the text fields in a variable (type list or map), then create a new datasource from this for your dataset.
The variable might use an expression similar to
$V{variable}.add() ? $V{variable} : $V{variable}
Calculation type "Nothing".

GXT - Pissed off with ComobBox in Grid (different Display Label and Value)

I am trying to add a CobmoBox in EditorGrid
I have a class Vehicle with fields
Integer vehicleId;
String plateNo;
Integer vehicleType; //1=Car,2=Truck
I want the combo box to show vehicle's type in text form i.e if vehicleType is 1, "Car" would be displayed. And when the user select any other option - like "Truck" the corresponding integer value should be populated into the bean.
This is pretty standard stuff with plain old JSP and HTML.
However I couldn't find a simple way the do this in Ext GWT.
If you are using a GXT ComboBox, the easiest way to is create a model representing your vehicle object if you haven't already. This is basically a class that extends GXT's BaseModelData class.
Once you have your model, you create a combo box using that type:
ComboBox<VehicleModel> box = new ComboBox<VehicleModel>();
The last step is to tell the combo box which fields to use for values and for display, which is done with 2 method calls:
box.setDisplayField("field name for display");
box.setValueField("field name for value");
When you load up a store of vehicle models, GXT will take care of the rest. You will, however, need to convert the model back to the vehicle object itself to be persisted.