Discussions
Categories
Groups
Community Home
Categories
INTERNAL ENABLEMENT
POPULAR
PUBLIC CLOUD
PRIVATE CLOUD
Quick Links
MY LINKS
HELPFUL TIPS
Back to website
Home
Intelligence (Analytics)
Recursive subreports
javainfode
Hi, Does BIRT support recursive subreports.?
I need to design a report using a datasource with a tree structure similar to a filesystem folder structure.
Find more posts tagged with
Comments
mwilliams
Hi javainfode,
Can you explain more about your data and what you're wanting as your output? Thanks.
javainfode
Hi Michael,
Thanks for the reply.
Am reporting on a UML Model which can contain Packages like folders. So the UML Model structure will look like the tree structure of a file system - like Windows Explorer.
Packages, like folder, can contain other packages to any level of nesting.
I have a subreport that reports on the contents of a Package.
How can I use this subreport as I traverse the tree structure of the Model?
pkouzmenko
Hi javainfode!<br />
<br />
You can solve your problem without recursison and subreports. You can get rid of recursion:<br />
<br />
1) Create a dataset <em class='bbc'>AllPackages</em>:<br />
<strong class='bbc'>Row Mapping</strong>: <span style='font-family: Courier New'>instanceOf(/Model//*, "uml:Package")</span><br />
<strong class='bbc'>Column Mapping</strong>:<br />
<ul class='bbc'><li><em class='bbc'>name</em> as <span style='font-family: Courier New'>
@name<
;/span></li><li><em class='bbc'>qualifiedName</em> as <span style='font-family: Courier New'>
@qualifiedName<
;/span></li></ul>
<strong class='bbc'>Computed Columns</strong>: <em class='bbc'>level</em> (integer) as <span style='font-family: Courier New'>row["qualifiedName"].split("::").length</span>;<br />
<br />
2) Put into report a list (or table) with binding to <em class='bbc'>AllPackages</em> and sorting by <em class='bbc'>qualityName</em><br />
<br />
3) Put into Detail secton of this list a dynamic text (to display a package name) and write '<span style='font-family: Courier New'>'Package ' + row["name"]</span>' as an expression.<br />
<br />
4) Use column <em class='bbc'>level</em> to control a style (with 'Highlights' tab)
mwilliams
Hi pkouzmenko,
This could be a good devShare post if you have the time to make one. You'd be entered in the devShare contributor of the month contest as well.
nanneia
I know this is old, but it could be worth a try
So, I was posting couple of weeks ago about how to make recursion with birt. My problem is actually very similar to this. The only difference is, I don't want my packages to be sorted by qualified names, but by aliases. The problem is, if I sort it by aliases, the tree structure (subpackages level) is violated.
Let me show what I want. My current situation (sorted by qualifiedName; in brackets is the alias) is something like this:
A (20)
Aa (10)
Aa1 (50)
Ab (20)
B (10)
Ba (70)
Ba1 (30)
Ba2 (20)
etc.
What I want to accomplish, is next:
B (10)
Ba (70)
Ba2 (20)
Ba1 (30)
A (20)
Aa (10)
Aa1 (50)
Ab (20)
etc.
The names and aliases are columns in my dataset.
I guess I need to use some scripting, but I don't get it
Any help?
Tnx!
Hans_vd
Hi nanneia,
How about this:
- Create a second dataset that contains only the level 1 occurences with their aliases (call the field level_1_alias)
- join it together with your existing dataset
- now you can order by level_1_alias, level, alias
Not sure if all I suggest is possible in your specific situation, but I think it will always be a matter of getting that level_1_alias in every record.
Hope this helps
Hans
nanneia
I guess my explanation was bad, or my demonstration. I have already tried what you desribed and it doesn't fit my idea of recursive going through the tree.
I want to sort these packages WITHOUT any joining. If I start to join, I will have to do it on as many levels as there exists in the tree. Doing that for a big model with a deeply leveled structure is not effective at all. What I want to achieve, is to have a package hierarchy using only one dataset called Packages and to sort Packages by aliases.
I have an idea, but I'm not quite familiar with scripting as I am pretty sure I need to do some work around with scripts.
My idea is to count the level of a package (which I already did), and create a new computed column called Position that contains <level + alias>. The script, on the other hand, has to find the position of the packages parent and at the end, the final position would look something like: <parentLevel + parentAlias + level + alias> where parentPosition (parentLevel + parentAlias) would be recursively determined (or first determined for packages with a higher level).
Anybody? I desperately need some fresh ideas.
Hans_vd
<blockquote class='ipsBlockquote' ><p>If I start to join, I will have to do it on as many levels as there exists in the tree</p></blockquote>
<br />
I may be completely wrong about this, but actually I don't think so :-)<br />
You don't want to sort by alias, you want to sort by alias within a "level"<br />
Now what I meant here, is that every record will have an extra column level_1_alias. So the join will be on the level 1 part of the record.<br />
<br />
Let's say, for the records that have level 1 = "B"<br />
<br />
-> in the new data set you'll have the records:<br />
<pre class='_prettyXprint _lang-auto _linenums:0'>
qualifiedName level_1_alias
============= =============
A 20
B 10
</pre>
<br />
If you join this dataset with the existing one, and the join codition is on level 1 part of the qualifiedName, you'll have these records (I also added the level column that you must have somehow):<br />
<br />
<pre class='_prettyXprint _lang-auto _linenums:0'>
qualifiedName Alias level_1_alias level
============= ===== ============= =====
A 20 20 1
Aa 10 20 2
Aa1 50 20 3
Ab 20 20 2
B 10 10 1
Ba 70 10 2
Ba1 30 10 3
Ba2 20 10 3
</pre>
<br />
If you order by level_1_alias, level, alias, then the records will be in the order you want them.
paulk
Sorting by level will cause the data to be sorted incorrectly (Ab will come before Aa1). Using joins will require n-1 joins for n level deep.<br />
You can build a script for creating the sql required using a loop. (my code won't be entirely correct, just demonstrating the idea)<br />
<br />
<pre class='_prettyXprint _lang-auto _linenums:0'>
sql = "select * from table as maintbl";
for (i=1;i<n;i++)
{
sql += " inner join (select qualifiedName, alias as lv" + i + "alias from table where level = " + i + ") as tmp" + i + " on maintbl.qualifiedName like (tmp" + i + ".qualifiedName+'%') "
}
sql += " order by "
for (i=1;i<n;i++)
{
if(i!=1) {sql += ", "}
sql += "lv" + i + "alias"
}
sql += ", alias"
</pre>
<br />
Try to avoid using LIKE in your join as this is bad for performance.<br />
<br />
<br />
You can also use database functions to create a column for organization within a group. For SQL Server, put the following in the SELECT statement of the dataset: row_number() over (partition by level order by alias) as sortorder<br />
This will give the following result:<br />
<br />
<pre class='_prettyXprint _lang-auto _linenums:0'>
Name Alias Level sortorder
----
A 20 1 2
Aa 10 2 1
Aa1 50 3 3
Ab 20 2 2
B 10 1 1
Ba 70 2 3
Ba1 30 3 2
Ba2 20 3 1
</pre>
<br />
The sortorder is a unique number for each Name/Alias combination by level starting with the lowest Alias value. Limit this dataset through dataset parameters in the tables by the hierarchy (ie parent = A, to return just rows Aa and Ab with the correct sorting order).<br />
This method will require a subtable in the layout for each level.
nanneia
Hans, exactly the problems paulk mentioned I have to struggle with if I do it as you described.
On the other hande, paulk, I am using a XML source (UML model), so this way as you mentioned is no solution either
Thanks guys for your help, I really appreciate it!
Hans_vd
Ok, then I just don't understand your initial situation.<br />
<br />
Don't you have all the levels in one dataset, just as pkouzmenko describes in his post? If the answer is yes, then you do NOT have to join on different levels and my solution will work perfectly well.<br />
<br />
<pre class='_prettyXprint _lang-auto _linenums:0'>Sorting by level will cause the data to be sorted incorrectly</pre>
That's right. Nobody ever said that there should be a sorting on level.<br />
<br />
<br />
Regards<br />
Hans
nanneia
<blockquote class='ipsBlockquote' data-author="'Hans_vd'" data-cid="79664" data-time="1309955900" data-date="06 July 2011 - 05:38 AM"><p>
Ok, then I just don't understand your initial situation.<br />
<br />
Don't you have all the levels in one dataset, just as pkouzmenko describes in his post? If the answer is yes, then you do NOT have to join on different levels and my solution will work perfectly well.<br />
<br />
<pre class='_prettyXprint _lang-auto _linenums:0'>Sorting by level will cause the data to be sorted incorrectly</pre>
That's right. Nobody ever said that there should be a sorting on level.<br />
<br />
<br />
Regards<br />
Hans<br /></p></blockquote>
<br />
<br />
Ok, I think my explanation was not a good one, sorry about that.<br />
I have to sort by aliases WITHIN a level. So, every level has to be sorted according to the alias, keeping the parent/child relationship. <br />
Joining by level 1 would work if I want only package on level 1 to be sorted. But I want every level to be sorted. Since I am using a XML source file, I have no clue how to make it by the data source, as I could do with a SQL source. That's why I am claiming that I need some scripting, just don't know when to trig it, I have some idea on how to implement it.<br />
<br />
I hope it's a bit clearer now, sorry if I suck at explaining, I am using BIRT only for a couple of weeks, and my problem is pretty unique
<br />
<br />
Thanks for your effort guys!
Hans_vd
Nanneia, Paulk,
Nothing wrong with your explanations. It was my understanding of the problem that was failing.
I don't see any solution however.
Sorry for not being able to see what you were trying to make clear. I should have seen this from your first post.
Regards
Hans