It's all about the answers!

Ask a question

Why do I get a separate row in a BIRT report for each custom attribute?

Zachary K (19344239) | asked Jun 29 '12, 6:06 p.m.
edited Jul 04 '12, 3:12 p.m. by Geoffrey Clemm (30.0k23035)
I'm using RTC 3.0.1 and BIRT. I've added 4 custom attributes to a work item type. I can retrieve the custom attribute values (STRING_KEY/STRING_VAL) in the BIRT report but for each workitem ID, I get 4 results (rows); one for each custom attribute value. 
How can I display the 4 custom attributes for one row only in the BIRT report?
Thanks in advance for your help.

9 answers

permanent link
Rafik Jaouani (5.0k16) | answered Jul 06 '12, 12:52 p.m.
In the open method of the scripted data set you could create an integer indexed array that stores all the work item ids: workItemIds = []; for (var id in workItems) { workItemIds.push(id); } Then iterate over workItemIds instead of workItems.

permanent link
Zachary K (19344239) | answered Jul 02 '12, 12:08 p.m.
edited Jul 02 '12, 12:10 p.m.
I tried using a group by WI ID but I couldn't get it to work. 
Any idea on how to display a single row for each workitem with its custom attributes values?
Thanks in advance.

permanent link
James Moody (3.3k24) | answered Jul 04 '12, 2:05 p.m.
Custom attributes are not stored the way that you want to view them. You'd like for each custom attribute to get its own column in a table, but they are stored (as you see) in a generic key-value way since we don't know ahead of time what all the possible attributes could be. I think the simplest solution looks something like this:

1. Create a global javascript array which will contain one object per work item. Do this in the initialize method of the report.
2. In onFetch of your data set, you want logic that does the following:
   If this is the first time you've seen this work item (i.e. if myArray[row["WI_ID"]] == null/undefined) then initialize myArray[row["WI_ID"]] to an empty object {}.
   Otherwise look up the object at myArray[row["WI_ID"]]
   In this array, put a field corresponding to the custom attribute you found. For example, myArray[row["WI_ID"]][row["STRING_KEY"]] = row["STRING_VAL"]; or something like that.
3. Create a scripted data set that reads elements from myArray and produces a row for each one, with first-class columns for each of your (known) custom attributes.

But beware of the performance implications of this - depending on how many work items you are fetching, this could get expensive in terms of memory.


permanent link
Zachary K (19344239) | answered Jul 05 '12, 7:42 a.m.
edited Jul 05 '12, 8:24 a.m.
Thanks James for your reply. 
I would need more help for 1) as I'm not too familiar with reading data source in javascript.
-  I've created an array workItems = []; in the initialize event for the report
- I've created a data source script and a data set using that data source. On the "fetch" event of the data set,  I need to read the workItems array. Should I do something like that:
<code>if (index < workItems.length) {
  row["Col1"] = workItems[index];
  return true;
} else {
  return false;


permanent link
James Moody (3.3k24) | answered Jul 05 '12, 9:53 a.m.
Yes, that's the basic idea regarding your fetch. If you'd like an example of a report which does this, check out any of our story points-based reports that ship with RTC. For examples, "Story Points.rptdesign" which you can find in the plug-in folder in your RTC client installation. Import that into your workspace and open it with BIRT. You'll see a similar pattern which you can copy.

permanent link
Zachary K (19344239) | answered Jul 06 '12, 10:19 a.m.
edited Jul 06 '12, 10:20 a.m.
Thanks James - I almost got it to work. 
This is what I have in the onFetch of the dataset for workItems
if (typeof(workItems) == "undefined") {
if (workItems[row["WI_ID"]] == null) {
   workItems[row["WI_ID"]] = new Object();
   workItems[row["WI_ID"]]["SUMMARY"] = row["SUMMARY"];
} else {
workItems[row["WI_ID"]][row["STRING_KEY"]] = row["STRING_VAL"];

My only problem is with reading elements from  workItems to produce a row as you mentioned in 3).
How can I read the items from workItems, I can't use workItems.length to iterate tru the array as the index is the workitem id.    

Thanks for your help

permanent link
Zachary K (19344239) | answered Jul 06 '12, 1:02 p.m.
Thanks that works fine

permanent link
Paul Wellman (71119) | answered May 22 '13, 12:51 p.m.
Is there anyway we could see an example of this report?
I tried to look st the Story Points file but it is quite cumbersome.

I am looking for a nice and simple way to implement the solution mentioned here.

Thanks so much.

permanent link
Krzysztof Ka┼║mierczyk (7.4k34997) | answered May 23 '13, 5:14 a.m.
Also Rafik some time ago made a video how to do that:
This might be helpful for you as well.

Your answer

Register or to post your answer.