How to put fixed number of things on a page

vguarna
edited February 11, 2022 in Analytics #1
<p>I have a report that outputs clusters (maybe "forms" would be a better term) of 8 lines or so of data - with a 1/2 space between forms. My goal is to have all of the forms have the same spacing relative to the top of the page so that multiple pages can be stacked on top of another and singulated easily with a paper cutter. Right now, the report just plots continuously -- not only failing to align with the top of page but also breaking forms over page breaks. The forms are created with a table. That part was very easy -- all works fine.</p>
<p> </p>
<p>My thought was to use BIRT groups to control the output. I use the "initialize" event to init two variables:</p>
<p> </p>
<p>groupNumber = 1;</p>
<p>tableNumber = 0;</p>
<p> </p>
<p>The tableNumber var is intended to count forms per page (trying 4 in my case) and the groupNumber is the var that would change, signaling BIRT's group logic to start a new group (which I use just for the page break).</p>
<p> </p>
<p>Then, I arbitrarily picked a detail row in the table and added the onCreate event script:</p>
<p> </p>
<p>tableNumber++;</p>
<p>if (tableNumber > 3) {</p>
<p>    tableNumber = 0;</p>
<p>    groupNumber++</p>
<p>}</p>
<p> </p>
<p>Finally, I use "groupNumber" as the Group By expression in the report design.</p>
<p> </p>
<p>The result is that no grouping occurs. (just one group for all of the forms.) Among other things, I think it's clear that I don't understand variable scoping. If I put "groupNumber" in a dynamic text field, it appears to increment as I would expect (1 1 1 1 2 2 2 2 3 3 3 3, etc.) and I can plot it in a table cell (I don't need that, but it was interesting for debugging). But, those changes are not seen by the Group By. Oddly enough, the Group By is seeing something because if I change the spelling of the variable from groupNumber to, say, groupNumberXXX, I get an exception when the report runs. So, Group By apparently sees a variable definition but is not seeing the value changes.</p>
<p> </p>
<p>I tried playing with reportContext.setGlobalVariable("groupNumber", <some number>) but that didn't seem to have an effect. I also tried grouping by a database record key field -- that caused the grouping to work, except that it would insert a page break after every form. (I just ran that experiment to convince myself that I had the group set up properly).</p>
<p> </p>
<p>So, I am out of ideas. Could anyone answer a couple of questions:</p>
<p> </p>
<ol><li>Is this even a sensible way to solve the problem? It seems like I shouldn't have to resort to JS to do this sort of thing. I would expect my inexperience is causing me to look at this the wrong way.</li>
<li>Can someone suggest a good sort of documentation on this aspect of BIRT -- in particular, the details of the JS environment and scoping and such. I've seen some of the documentation on this site, but it didn't appear to be at a level that could take someone like me (novice) and help me understand more of the interactions inside the engine. (Even if this is a silly way to solve this problem, I would like to understand the product better for other problems I will want to solve some other day.)</li>
</ol><p>Thanks,</p>
<p>Vince</p>

Comments

  • <p>Are the 8 lines or so of data in a single data set row? Or do they come in individual rows?</p>
    <p> </p>
    <p>If in one row, you could simply size the detail row to be a particular height to force each section to be the same height.</p>
    <p> </p>
    <p>If in separate rows, you could create a group and add dummy group footer rows to hide/show based on the number of rows in that particular group. This would force each group to be the same.</p>
    <p> </p>
    <p>Let me know.</p>
    Warning No formatter is installed for the format ipb
  • <p>Thanks for the quick response.</p>
    <p> </p>
    <p>The lines are in separate rows. I may have misunderstood your response, but it sounds as though you are trying to help make sure that each 8-line thing is the same size vertically. That's actually not a problem. Each thing is exactly the same height. I haven't measured it exactly, but let's say it's two inches. The thing I'm trying to deal with is after four of these have rendered (eight inches' worth) and I have another inch left on the page, I want to insert a page break so that I don't get an item across the page break. This way, all items would start at exactly the top of the page (and they'll be lined up from one page to the next.</p>
    <p> </p>
    <p>I did create the group with the "new page except for first" option set. I guess that's sort of a dummy group, but it sounds different from what you are suggesting. The "Group By" expression is just the JS variable that changes after every 4 items. The JS var is visible to table cells (they render in those eight lines if I put one in a cell) but apparently not to the Group By scope. That's why I was asking about that.</p>
    <p> </p>
    <p>So, based on your suggestion, I will try stretching out the 8-line sets a bit so that they exactly fit on the page. If the first and last rows are fairly high, maybe it won't be too hard to avoid the page break.</p>
    <p> </p>
    <p>But isn't there a way to put in a page break after n lines? Or a way to make JS variables visible to the Group By expression evaluator? Or a way to force a page break from inside a JS event handler?</p>
    <p> </p>
    <p>Thx, Vince</p>
  • <p>Gotcha. I'm assuming you have grouping set up already, so something you could do is to create a counter variable and increment it in your group header's onCreate method, then, in the group footer, you'd just write a script in the  onCreate method that would set the page break after to always if you've reached the condition count%4 == 0;</p>
    <p> </p>
    <p>The syntax to force the break after the footer row would be something like:</p>
    <p> </p>
    <p>this.getStyle().pageBreakAfter = "always"</p>
    <p> </p>
    <p>Hope this helps. I can create an example if you'd like. Let me know your BIRT version if you'd like one. :)</p>
    Warning No formatter is installed for the format ipb
  • <p>Oh yeah, that's what I'm talking about.</p>
    <p> </p>
    <p>It works. I put each 2 inch thing in its own group (I grouped by a database field that always changes so that each item gets its own group). Additionally, in the Group By editor, I left all of the page break options to "Auto" so that each group just renders down the page. Then, using my JS counter (groupItemCount) that triggers on the footer row element onCreate event (as you mentioned), I used the method you mentioned to override the end of group page break behavior after 4 items render. They plot 4 to a page, now. Many thanks!</p>
    <p> </p>
    <p>One surprise: once I start rendering the 5th item, I thought I was going to have to set the page break behavior back to Auto again so that I don't get a break after item 5 (and 6 and 7...). Obviously that getStyle() method is only a temporary override.</p>
    <p> </p>
    <p>BTW, not important now, but I'm running a very recent version of the Eclipse BIRT bundle. Looks like 4.4.1.</p>
    <p> </p>
    <p>Could you please point me at the best place to learn about all of these methods? Either online or books would be fine. I just haven't found any good reference sources yet and I want to learn a lot more about the package.</p>
    <p> </p>
    <p>Thanks again.</p>
    <p>Vince</p>
  • <p>You can always find the documentation links at a link like:</p>
    <p> </p>
    <p><a data-ipb='nomediaparse' href='http://help.eclipse.org/indigo/index.jsp'>http://help.eclipse.org/indigo/index.jsp</a></p&gt;
    Warning No formatter is installed for the format ipb