Geertjan is a DZone Zone Leader and has posted 457 posts at DZone. You can read more from them at their website. View Full User Profile

Real-Time Charts on the Java Desktop

11.20.2010
| 43907 views |
  • submit to reddit

Devoxx, and all similar conferences, is a place where you make new discoveries, continually. One of these, in my case, at last week's Devoxx, started from a discussion with Jaroslav Bachorik from the VisualVM team. He had presented VisualVM's extensibility in a session at Devoxx. I had heard that, when creating extensions for VisualVM, one can also create new charts using VisualVM's own charting API. Jaroslav confirmed this and we created a small demo together to prove it, i.e., there's a charting API in VisualVM. Since VisualVM is based on the NetBeans Platform, I went further and included the VisualVM charts in a generic NetBeans Platform application.

Then I wondered what the differences are between JFreeChart and VisualVM charts, so asked the VisualVM chart architect, Jiri Sedlacek. He sent me a very interesting answer:

JFreeCharts are great for creating any kind of static graphs (typically for reports). They provide support for all types of existing chart types. The benefit of using JFreeChart is fully customizable appearance and export to various formats. The only problem of this library is that it's not primarily designed for displaying live data. You can hack it to display data in real time, but the performance is poor.

That's why I've created the VisualVM charts. The primary (and so far only) goal is to provide charts optimized for displaying live data with minimal performance and memory overhead. You can easily display a fullscreen graph and it will still scroll smoothly while running and adding new values (when running on physical hardware, virtualized environment may give slightly worse results). There's a real rendering engine behind the charts which ensures that only the changed areas of the chart are repainted (no full-repaints because of a 1px change). Scrolling the chart means moving the already rendered image and only painting the newly displayed area. Last but not least, the charts are optimized for displaying over a remote X session - rendering is automatically switched to low-quality ensuring good response times and interactivity.

The Tracer engine introduced in VisualVM 1.3 further improves performance of the charts. I've intensively profiled and optimized the charts to minimize the cpu cycles/memory allocations for each repaint. As of now, I believe that the VisualVM charts are the fastest real time Java charts with the lowest cpu/memory footprint.

 
Best of all is that everything described above is in the JDK. That's because VisualVM is in the JDK. Here's a small NetBeans Platform application (though you could also use the VisualVM chart API without using the NetBeans Platform, just include these JARs on your classpath: org-netbeans-lib-profiler-charts.jar, com-sun-tools-visualvm-charts.jar, com-sun-tools-visualvm-uisupport.jar and org-netbeans-lib-profiler-ui.jar) that makes use of the VisualVM chart API outlined above:

 

The chart that you see above is updated in real time and you can change to full screen and you can scroll through it and, at the same time, there is no lag and it is very performant. Below is all the code (from the unit test package in the VisualVM sources) that you see in the JPanel above:

public class Demo extends JPanel {

    private static final long SLEEP_TIME = 500;
    private static final int VALUES_LIMIT = 150;
    private static final int ITEMS_COUNT = 8;
    private SimpleXYChartSupport support;

    public Demo() {
        createModels();
        setLayout(new BorderLayout());
        add(support.getChart(), BorderLayout.CENTER);
    }

    private void createModels() {
        SimpleXYChartDescriptor descriptor =
                SimpleXYChartDescriptor.decimal(0, 1000, 1000, 1d, true, VALUES_LIMIT);

        for (int i = 0; i < ITEMS_COUNT; i++) {
            descriptor.addLineFillItems("Item " + i);
        }

        descriptor.setDetailsItems(new String[]{"Detail 1", "Detail 2", "Detail 3"});
        descriptor.setChartTitle("<html><font size='+1'><b>Demo Chart</b></font></html>");
        descriptor.setXAxisDescription("<html>X Axis <i>[time]</i></html>");
        descriptor.setYAxisDescription("<html>Y Axis <i>[units]</i></html>");

        support = ChartFactory.createSimpleXYChart(descriptor);

        new Generator(support).start();
    }

    private static class Generator extends Thread {

        private SimpleXYChartSupport support;

        public void run() {
            while (true) {
                try {
                    long[] values = new long[ITEMS_COUNT];
                    for (int i = 0; i < values.length; i++) {
                        values[i] = (long) (1000 * Math.random());
                    }
                    support.addValues(System.currentTimeMillis(), values);
                    support.updateDetails(new String[]{1000 * Math.random() + "",
                                1000 * Math.random() + "",
                                1000 * Math.random() + ""});
                    Thread.sleep(SLEEP_TIME);
                } catch (Exception e) {
                    e.printStackTrace(System.err);
                }
            }
        }

        private Generator(SimpleXYChartSupport support) {
            this.support = support;
        }
    }

}

 

Here is the related Javadoc. To get started using the VisualVM charts in your own application, read this blog, and then look in the "lib" folder of the JDK to find the JARs you will need.

And then have fun with real-time data in your Java desktop applications.

 

Published at DZone with permission of its author, Geertjan Wielenga.

Comments

Hantsy Bai replied on Sat, 2010/11/20 - 11:10am

Why not extract the chart api from the VisualVM and standardize it as an Charts and Reports API for NetBeans platform, thus will benifit all NetBeans platform developer.

Juan Ottonello replied on Sat, 2010/11/20 - 11:55am

Thanks for the info Geertjan, usefull as always! For sure there are a lot of people interested in having a live charts library (that's the lack of JFreeChart, as said) and having an NPM separated of the visualVM would be great fo the NB Platform!

cowwoc replied on Sat, 2010/11/20 - 1:28pm

I'm also interested in the charting library being split from VisualVM and made publically available.

Lester Burnham replied on Mon, 2010/11/22 - 1:52am

I'm not sure how it compares to the VisualVM charts, but JChart2D is worth a look if you're looking for live desktop charts.

Jeanette Winzenburg replied on Mon, 2010/11/22 - 9:48am

posted the question to the older blog entry, repeating it here:

 

would love to play with it (outside of NetBeans, being a Eclipse fangirl :-), but seems like something missing (after copying the all jars from the jdk lib/visualvm/visualvm/Modules and from lib/visualVM/profiler3/Modules). Running the example from the devoxx blog entry throws:

Exception in thread "main" java.lang.NoClassDefFoundError: org/openide/util/NbBundle
    at com.sun.tools.visualvm.charts.xy.SimpleXYChartUtils.createDetailsString(SimpleXYChartUtils.java:463)
    at com.sun.tools.visualvm.charts.xy.SimpleXYChartUtils.createDetailsArea(SimpleXYChartUtils.java:305)

Whatelse do I need?

Hmmm ... from the 4 jars you explicitly listed, I couldn't find the "com-sun-tools-visualvm-uisupport.jar" in the jdk's (1.6) lib Where exactly is it?

 

Thanks
Jeanette

Geertjan Wielenga replied on Tue, 2010/11/23 - 6:06am in response to: Jeanette Winzenburg

Like I said in the comments to the blog entry, you need org-openide-util.jar, which is in the "lib/visualvm/platform/lib" folder in the JDK.

Winston Brummer replied on Wed, 2010/11/24 - 4:03am

Is it possible that you could make the code for the project available. I could get this working with JConsole but not with VisualVM. Is there a difference in creating the jar? Thanks Winston

Claude Lalyre replied on Wed, 2010/11/24 - 10:39am

Really great article ! Surely I will use these APIs for my future coding. Thanks.

Mohit Khanna replied on Wed, 2010/11/24 - 11:22am

Perfect. This is what i was looking for!

I have been using JFreeChart for quite some time now. But as you said, its kinda heavy with the live charting, etc. Plotting 100K events.... no big deal if you do it right. But yes i did have to disable tooltips, and other fancy stuff on the chart panel.

VisualVM chart API - i gonna try next now! :-)

Good article.

Javier Ortiz replied on Fri, 2010/11/26 - 3:35pm

This sure looks like a great addition API to the platform. Hope it gets done!

Liu Huasong replied on Wed, 2010/12/15 - 7:33pm

Hi Geertjan, when I run this demo without using the NetBeans Platform, the charts displayed, but it throws NPE(just one time):

Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
	at com.sun.tools.visualvm.charts.SimpleXYChartSupport$3.run(SimpleXYChartSupport.java:160)
	at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:209)
	at java.awt.EventQueue.dispatchEvent(EventQueue.java:597)
	at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269)
	at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184)
	at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:174)
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169)
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161)
	at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)

We have to include these 6 JARs on the classpath to use it without using the NetBeans Platform:
  • org-netbeans-lib-profiler-charts.jar
  • com-sun-tools-visualvm-charts.jar
  • com-sun-tools-visualvm-uisupport.jar
  • org-netbeans-lib-profiler-ui.jar
  • org-openide-util.jar
  • org-openide-util-lookup.jar

  • Without this 2 jars, the charts don't deplay, the program repeatedly throws:
    Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
    	at com.sun.tools.visualvm.charts.SimpleXYChartSupport$3.run(SimpleXYChartSupport.java:160)
    	at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:209)
    	at java.awt.EventQueue.dispatchEvent(EventQueue.java:597)
    	at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269)
    	at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184)
    	at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:174)
    	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169)
    	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161)
    	at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)
    Exception in thread "main" java.lang.NoClassDefFoundError: org/openide/util/NbBundle
    	at com.sun.tools.visualvm.charts.xy.SimpleXYChartUtils.createDetailsString(SimpleXYChartUtils.java:462)
    	at com.sun.tools.visualvm.charts.xy.SimpleXYChartUtils.createDetailsArea(SimpleXYChartUtils.java:304)
    	at com.sun.tools.visualvm.charts.SimpleXYChartSupport.getChart(SimpleXYChartSupport.java:94)
    	at client.ChartDemo.(ChartDemo.java:22)
    	at client.ChartDemo.main(ChartDemo.java:73)
    Caused by: java.lang.ClassNotFoundException: org.openide.util.NbBundle
    	at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
    	at java.security.AccessController.doPrivileged(Native Method)
    	at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
    	at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
    	at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
    	at java.lang.ClassLoader.loadClass(ClassLoader.java:248)
    	... 5 more
    

    Then I add org-openide-util.jar to the class path, the charts don't deplay too, the program repeatedly throws:
    Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
    	at com.sun.tools.visualvm.charts.SimpleXYChartSupport$3.run(SimpleXYChartSupport.java:160)
    	at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:209)
    	at java.awt.EventQueue.dispatchEvent(EventQueue.java:597)
    	at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269)
    	at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184)
    	at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:174)
    	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169)
    	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161)
    	at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)
    Exception in thread "main" java.lang.NoClassDefFoundError: org/openide/util/lookup/implspi/ActiveQueue
    	at org.openide.util.Utilities.activeReferenceQueue(Utilities.java:299)
    	at org.openide.util.TimedSoftReference.(TimedSoftReference.java:91)
    	at org.openide.util.NbBundle.getBundleFast(NbBundle.java:518)
    	at org.openide.util.NbBundle.getBundle(NbBundle.java:441)
    	at org.openide.util.NbBundle.getBundle(NbBundle.java:394)
    	at org.openide.util.NbBundle.getMessage(NbBundle.java:637)
    	at com.sun.tools.visualvm.charts.xy.SimpleXYChartUtils.createDetailsString(SimpleXYChartUtils.java:462)
    	at com.sun.tools.visualvm.charts.xy.SimpleXYChartUtils.createDetailsArea(SimpleXYChartUtils.java:304)
    	at com.sun.tools.visualvm.charts.SimpleXYChartSupport.getChart(SimpleXYChartSupport.java:94)
    	at client.ChartDemo.(ChartDemo.java:22)
    	at client.ChartDemo.main(ChartDemo.java:73)
    Caused by: java.lang.ClassNotFoundException: org.openide.util.lookup.implspi.ActiveQueue
    	at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
    	at java.security.AccessController.doPrivileged(Native Method)
    	at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
    	at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
    	at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
    	at java.lang.ClassLoader.loadClass(ClassLoader.java:248)
    	... 11 more
    

    I don't understand why the Charts API depends org-openide-util.jar and org-openide-util-lookup.jar.

    Pol Matm replied on Tue, 2010/12/28 - 11:40am

    Hi,

    I was using till now Jfreechart for real time plotting for my application, but my problem with it was that after many data points started going slower and slower because it was redrawing all the data points. SO I found this article and I am very very interested. 

     

    I am using eclipse. So I put the code u have up, and i included all the nessesary jar files.But I am getting this exception:

     Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
        at com.sun.tools.visualvm.charts.SimpleXYChartSupport$3.run(SimpleXYChartSupport.java:160)
        at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:209)
        at java.awt.EventQueue.dispatchEvent(EventQueue.java:597)
        at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269)
        at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184)
        at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:174)
        at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169)
        at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161)
        at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)

     

    Any idea what is happening??

     

    Thanks Pol

    Pol Matm replied on Tue, 2010/12/28 - 11:44am in response to: Liu Huasong

    Hi Liu,

     We have the same problem as I can see with the difference that me when i added also the two extra jars you mentioned, I am still having the exception.

     

    Any idea?

     

    Thanks,

     

    Pol

    Abhi Deo replied on Sat, 2011/07/30 - 1:21pm

    can we use the same application as the web based, as i need to do the same thing but the problem is that it has to be done as a web based application , so we dont have much control over the browsers. In my case the data will be written on a flat file, and the whole application will be deployed on the server in LINUX, so i need to show the real time data from those flat files , so please guide me accordingly so that i can use the application for the web based examples. The graph has to be updated after every three seconds , so i need to draw this graph and show the updated values on the graph All the values to be taken , will be from the flat files, which will be log files, in the format of the CSV format which has to be taken from them and showed it to the users. It will be showing a LIve Stock chart tot the various clients

    Erik Ostermueller replied on Sat, 2012/01/07 - 1:14pm

    I'm also getting the Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException error. Thanks, --Erik

    Jaffa Wify replied on Thu, 2012/03/01 - 12:20am

    Photographs are output onto blank wallpaper material. Typical installations are corporate lobbies, restaurants, athletic facilities, and home interiors. This gives a designer the ability to give a space the exact look and feel desired. Thanks a lot. Regards, desktop wallpaper

    Sfafaef Adfasg replied on Fri, 2012/06/01 - 10:18am

    Thanks for the info Geertjan, usefull as always! For sure there are a lot of people interested in having a live charts library (that's the lack of JFreeChart, as said) and having an NPM separated of the visualVM would be great fo the NB Platform! 10mb Internet

    Nile Donald replied on Fri, 2012/08/10 - 2:36am

    Yeah thats the great post i really liked it, it helped me alot as code is given, this can solve the problem anyone can get his/her problem solved, thanks for sharing.  Huawei Ascend P1

    Passion Lab replied on Sat, 2012/08/18 - 1:23pm

    The only problem of this library is that it's not primarily designed for displaying live data. You can hack it to display data in real time, but the performance is poor. vanzari apartamente

    Arno Van Rensburg replied on Tue, 2013/03/19 - 3:50am in response to: Pol Matm

    Has anyone found a solution for the NPE's yet?

    Ali Inayat replied on Thu, 2013/08/08 - 2:55am

    This code is awesome and i am going to keep touch with this website its really nice information please share new information as soon as possible  Coming Soon Mobiles

    Comment viewing options

    Select your preferred way to display the comments and click "Save settings" to activate your changes.