Repaint part of a screen (Timeline component)

I am building a web app with roughly the following layout on the page:

A gridLayout, each cell of which contains a Panel. In that Panel I put a few buttons, text fields and a Timeline object containing a set of data points which show up as a graph. I am storing the data set as a member variable of the object that contains the Timeline object, since the Timeline doesn’t allow access to its data sets. So far, so good. I can repaint the entire page without a problem. But what I would like to be able to do is update the data for one graph, and repaint only that Panel in the one cell of the gridLayout. And I can’t seem to get that to work. I can update the data, and re-assign the data source to the graph (Timeline). I tried doing a repaint request on the Panel, and I tried adding the ICEPush object and calling myPusher.push() after doing the data update, but neither seems to work.

So how do I force a single panel to update itself on the screen based on a client action (in this case, a button push in the panel).

Thanks,

nbc

Hi Neal,

The Timeline should listen to graph data source changes (itemset and property changes) automatically after you’ve added them to the Timeline so it should update the graphs accordingly when you modify the underlying container on the fly.

So here is a thought, instead of replacing the data source containers when you refresh, re-use the containers and just empty them with removeAllItems and re-populate them with the new points. You will need to keep references to the data source containers outside of the Timeline object for this.

Same applies for when you want to update just one graph, just empty that graphs container with removeAllItems and re-populate, the Timeline should take care of refreshing the graph automatically when the container changes.

Thanks John - I’ll give that a try and let you know what happens

nbc

John - I’m feeling rather dumb here, but I can’t get it to work… I create my Timeline with code like this:

jgl = (JartGraphLine) it.next();
bic = createGraphSource(jg, jgl); // This creates a BeanItemContainer with a list of data points
jgl.setBic(bic); // Saves the container
tl.addGraphDataSource(bic, “RDate”, “RVal”); // ‘tl’ is my Timeline object
tl.setGraphOutlineColor(bic, new Color(jgl.getColor()));

The data source is a BeanItemContainer (bic) and it is saved in the JartGraphLine object.

What I’m trying to do is negate all the data values (invert the graph) - so I did this:

public void negateDataValues(JartGraphLine jgl){
Object oid = null;
RawRRDData rawRRD = null;
RawRRDData nRawRRD = null;
long rTime = 0L;
double rValue = 0.0;
BeanItemContainer bic = jgl.getBic();
BeanItemContainer negBic = new BeanItemContainer(RawRRDData.class);

Logger.info("Negate data values here...");

for(oid = bic.firstItemId(); oid != null; oid = bic.nextItemId(oid)){
        rawRRD = bic.getItem(oid).getBean();
	rValue = rawRRD.getRValue() * (-1.0);
	rTime = rawRRD.getRTime();
	nRawRRD = new RawRRDData(null, rTime, rValue);
	negBic.addBean(nRawRRD);
}
bic.removeAllItems();
for(oid = negBic.firstItemId(); oid != null; oid = negBic.nextItemId(oid)){
	rawRRD = negBic.getItem(oid).getBean();
	bic.addBean(rawRRD);
}
	
Logger.info("Negated " + bic.size() + " items");

}

The routine gets called correctly and inverts the data, but the screen does not repaint.

Side note - I tried inverting the data directly with code like:
for(oid = bic.firstItemId(); oid != null; oid = bic.nextItemId(oid)){
rawRRD = bic.getItem(oid).getBean();
rawRRD.setRValue(rawRRD.getRValue() * (-1));
}

and that seems to cause a segment fault on the second element in the container. Other people have told me this should work, so I suspect I’m corrupting the data somehow - but I just don’t see it…

So is there something else I need to do to force the timeline to repaint itself? Because if I recreate the screen and tell it to invert the data, that works fine. But I have to rebuild the entire screen to do that…

thanks,

nbc

Looks like you found another bug (
#7934
). There is a typo in Timeline where the ItemSetChange listener never gets attached to the data source container. I’m fixing this now so it should be fixed tomorrow in a custom build of the Timeline. (https://vaadin.com/custom-builds)

As for the side note, since you are only changing the internal state of the bean and not using the container API, the container will never know that you changed the bean and so the container will never trigger a changed event to Timeline and no refresh will occur.

Instead, you will need to re-add your beans to the container when you refresh, here is an example of what I mean:

 private void invertValues(BeanItemContainer<TimelineBean> container) {
        List<TimelineBean> beans = new ArrayList<BeanItemContainerWithTimelineTest.TimelineBean>();
        for(int i=0; i<container.size(); i++){

            // Get bean
            BeanItem<TimelineBean> item = container.getItem(container.getIdByIndex(i));
            TimelineBean bean = item.getBean();

            // Invert value
            bean.setRValue(bean.getRValue() * (-1));

            // Store reference
            beans.add(bean);
        }

        // Refresh container (triggers change event for the timeline to repaint
        container.removeAllItems();
        container.addAll(beans);
    }

I’ve updated the Timeline BeanItemContainer demo application to include the invert function, you can use it as an reference if you wish. The source code can be found
here

Thanks - I’ll look for the updated Timeline tomorrow. In the meantime, I’ll fix my inversion code along the lines you suggested. Thanks very much!

nbc

John - I just looked at the custom build site - I see a timeline from a few days ago named: vaadin-timeline-cval-2.0-1.2.3.custom.jar

The version I have been using is named: vaadin-timeline-agpl-3.0-1.2.2.jar

I know the licenses are different, but is the code supposed to be the same? It looks like the cval version is the most recent - is that the one I should be using? Obviously, the bug you are fixing now will change the version number again, but do I need to be concerned about which licensed version of the code I am running? We have a Vaadin Pro Account.

Thanks,

nbc

The code is exactly the same in both the AGPL and CVAL versions, only the license differs.

Custom builds are released more often, basically any time that a issue is fixed and verified by our build system, while AGPL versions are only released when a milestone for that addon is completed. Custom builds are only released under the CVAL license.

If you have a Pro Account then all addons made by us (Vaadin Ltd) are included, so in your case I don’t see any licensing problem with using the CVAL license.

There is a good forum thread
here
about the licenses and if there is any doubt at all about how the licensing works I’d recommend contacting the sales team (https://vaadin.com/contact or directly by mail). They are always happy to help and usually knows the most about these matters.

Much obliged - I’ll look for the new custom build and let you know if that solves my problem. Thanks for the help

nbc

I just loaded the most recent custom build and inverting the graph now works as I expected it should. Thanks John!

nbc