Search code examples
javascripteclipsestylesbirt

Color cell according to condition


I have a table in which I have to set background color when the cell in header and cell in row appear as pair in a certain list in data source. For example: column : "AUD, USD" row : "BRL, CZK"

in the cell of column AUD and row is BRL I check if exists in the list in datasource "AUD-BRL" and if so I need to color in a green

Now, I thought to do it in this way: columns and rows will be in lists. I go over both lists and then color in those indexes the cell.

So that I will have one function for whole table and not have to call from each cell to function (There are 1200 cells overall). How can that be done?


Solution

  • The answer from Fede MG is correct.

    If I understand your question correctly, you want to add a highlighting rule to all cells in the table detail row. Unfortunately I think it is a bit cumbersome to achieve this in BIRT.

    I assume that your table has e.g. bindings like COL_VALUE_1, ..., COL_VALUE_9 for the cell values and COL_TITLE_1, ..., COL_TITLE_9 for the column headers.

    Furthermore I assume a bit of experience with using Javascript in BIRT.

    The way I do this like this:

    For each detail cell I create a onCreate event script with code like this:

    highlightDetailCell(this, row, 1);
    

    ... where 1 is the column number. E.g. this is the code for the first column, for the second column i replace the 1 with 2 and so on. One can quickly do this with copy&paste.

    Next I implement the logic in a function inside the onInitialize script of the report like this:

    function highlightDetailCell(item, row, colnum) {
        var colTitle = row["COL_TITLE_" + colnum];
        var colValue = row["COL_VALUE_" + colnum];
        var highlight = use_your_logic_to_decide(colTitle, colValue);
        if (highlight) {
            item.get_Style().backgroundColor = "yellow";
        }
    }
    

    This is the basic idea. If you want to add the script to many cells, it might be a lot of work to do this by hand. In fact it is possible to attach the call to the highlightDetailCell function with a script (of course, this is BIRT :-). You should read the documentation and just tinker with the Design Engine API (DE API for short).

    But be warned that writing and debugging such a script may be even more work than doing the donkey work of adding and editing a one-liner to 1200 cells!

    What I once did was basically this (in the onFactory event of the report item):

    // This code is a simplified version that modifies just the first cell,
    // However it should point you into the right direction.
    
    // Some preparation
    importPackage(Packages.org.eclipse.birt.report.model.api);
    var myconfig = reportContext.getReportRunnable().getReportEngine().getConfig();
    var de = DataEngine.newDataEngine( myconfig, null );
    var elementFactory = reportContext.getDesignHandle().getElementFactory();
    
    // Find the item you want to modify (in my case, a "Grid Item").
    // Note that for tables, the structure is probably a bit different.
    // E.G. tables have header, detail and footer rows, 
    // while grids just have rows.
    var containerGrid = reportContext.getDesignHandle().findElement("Layout MATRIX");
    
    // Get the first row
    var row0 = containerGrid.getRows().get(0);
    // Do something with the first cell (:
    var cell = row0.getCells().get(0).getContent();
    cell.setStringProperty("paddingTop", "1pt");
    cell.setStringProperty("paddingLeft", "1pt");
    cell.setStringProperty("paddingRight", "1pt");
    cell.setStringProperty("paddingBottom", "1pt");
    cell.setStringProperty("borderBottomColor", "#000000");
    cell.setStringProperty("borderBottomStyle", "solid");
    cell.setStringProperty("borderBottomWidth", "thin");
    cell.setStringProperty("borderTopColor", "#000000");
    cell.setStringProperty("borderTopStyle", "solid");
    cell.setStringProperty("borderTopWidth", "thin");
    cell.setStringProperty("borderLeftColor", "#000000");
    cell.setStringProperty("borderLeftStyle", "solid");
    cell.setStringProperty("borderLeftWidth", "thin");
    cell.setStringProperty("borderRightColor", "#000000");
    cell.setStringProperty("borderRightStyle", "solid");
    cell.setStringProperty("borderRightWidth", "thin");
    
    // When you're finished:
    de.shutdown( );
    

    Things are more complicated if you have to handle merged cells.

    You could even add content to the cell (I created a whole matrix dynamically this way).

    The script does not exactly what you want (add the script to each cell), but I leave this as an exercise...

    It is also helpful to save the dynamically modified report design for opening in the designer, to see the outcome:

    reportContext.getDesignHandle().saveAs("c:/temp/modified_report.rptdesign");
    

    HTH