X

Geertjan's Blog

  • November 19, 2010

Chart Library for NetBeans Platform Applications?

Geertjan Wielenga
Product Manager
I had a pretty great time at Devoxx this year. Met lots of people (Joe Darcy from Project Coin stopping by at the Oracle booth to have a look at my demos of Project Coin features in NetBeans IDE was one of the highlights). As always, Devoxx is a great way to catch up with loads of people at the same time and exchange technical bits of information about projects you're working on.

One of the people I had a long chat with was Jaroslav Bachorik from the VisualVM team. Aside from other topics, I asked him how the charts work in VisualVM because I had heard that VisualVM includes an API for making charts, such as these in VisualVM itself:

However, if you're creating a plugin for VisualVM, wouldn't it be cool to use charts yourself? So Jaroslav and I (mainly Jaroslav) came up with the following "hello world" chart code:

SimpleXYChartDescriptor sxycd = SimpleXYChartDescriptor.decimal(0, true, 500);
sxycd.addLineItems("Test1","Test2","Test3");
SimpleXYChartSupport factory = ChartFactory.createSimpleXYChart(sxycd);
factory.addValues(System.currentTimeMillis(), new long[]{100,200,300});
factory.addValues(System.currentTimeMillis(), new long[]{100,200,300});
factory.addValues(System.currentTimeMillis(), new long[]{100,200,300});
factory.addValues(System.currentTimeMillis(), new long[]{100,200,300});
add(factory.getChart(), BorderLayout.CENTER);

The above comes from the "com.sun.tools.visualvm.charts" package, read about ChartFactory and SimpleXYChartDescriptor and SimpleXYChartSupport in the VisualVM Javadoc.

If you put the code above into a panel in a VisualVM plugin, you'll end up with this in VisualVM:

Note: Jaroslav updated my earlier VisualVM templates, which you can get here on the Plugin Portal, use them to create new panels and actions and other typical artifacts in a VisualVM plugin.

Finally, since we're able to create charts in VisualVM, shouldn't we also be able to use the chart API in any NetBeans Platform application? Sure, glad you asked. Include the VisualVM clusters ("visualvm" and "profiler" clusters from the "lib" folder in the JDK) in your NetBeans Platform application, then include the code above in a TopComponent, and here you are:

Nice. Not sure what all the features are of this chart library (read the VisualVM Javadoc for clues) and I'm pretty sure this chart library isn't competition for JFreeChart. But, still, if you like the charts in VisualVM and you want to do something similar, now you can.


Join the discussion

Comments ( 18 )
  • Jean-Marc Borer Friday, November 19, 2010

    That's a nice tip. I was recently wondering if it would be possible to integrate some monitoring features of VisualVM into our own NB RCP based monitoring tool. This would avoid to launch it separately. Now I know it can be possible through the reuse of its cluster. Cool! I'all have to experiment.


  • Geertjan Wielenga Friday, November 19, 2010

    Hi Jean-Marc. Yes, good point, and there's more good news in connection with this that you'll find useful, I'll blog about it soon. Basically, it's possible to include the NetBeans Profiler in your own application (either to monitor the application under development, from inside the application itself, or for the case where the end users of your application need the monitoring capabilities of NetBeans IDE themselves). I'll blog about this scenario soon, someone at Devoxx told me about this, it's actually a scenario that's being used in real life at a company in Germany.


  • Thiago Bonfante Friday, November 19, 2010

    Hi Geertjan. I'm sorry to bother with a non related comment, but I found in you blog a 2008 post with the subject "Feature on Demand". I'm researching best pratices on modularization as modular strategies for a huge ERP, but I can't find anything else about that "Feature on Demand". Can you please help with some material or tips or a simple guidence, because until January 31, I have to put on my boss desk, a nice formula to prove the power of Netbeans Platform.

    Thanks for your contribution on this blog, it became required reading for my day to day.

    Regards.


  • Geertjan Friday, November 19, 2010

    Here's your answer, Thiago:

    http://wiki.netbeans.org/FitnessForever#Solution

    Please contact me directly at geertjan dot wielenga at oracle dot com and I'll help you directly in setting up the nice formula for your boss!


  • Ernest Saturday, November 20, 2010

    It seems it is even possible to use this outside the NetBeans platform - by sticking Geertjan's example above into a JDialog and just including the jars: 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 . Pretty cool!


  • Kleopatra Monday, November 22, 2010

    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?

    Thanks

    Jeanette


  • Geertjan Wielenga Monday, November 22, 2010

    org-openide-util.jar, which you'll find in the "platform" folder in VisualVM.


  • Owl Monday, November 22, 2010

    Very interesting. When using it outside of NetBeans (e.g. WebApplication on JEE), is it possible to export the chart to graphics file, e.g. PNG or JPEG?


  • Jiri Sedlacek Tuesday, November 23, 2010

    Hi Owl, these charts don't support export to bitmaps. As described in the article, VisualVM charts are designed for displaying live data (in Java applications). JFreeChart will do better job for you when creating charts on server-side.


  • Pol Tuesday, December 28, 2010

    Hi there,

    Well first of all great job!!

    What I want to do is to extend the API for the VisualVM charts. I would like the to add things like the jfreechart has. Example plot points, or linepoints and not only lines, define the colour of the line, add Graphics inside the plot as Rectangle2D and etc.

    So my question is how I can start doing that?

    I am trying to find the source code but I cant.

    Thanks,

    Pol


  • Clint Wednesday, January 18, 2012

    Hey, after I included the visualvm.charts package, how come it keeps complaining it can't find the "add" function from your code. How do I fix that? Thank you


  • Kyle Tuesday, December 25, 2012

    Great information. Realtime plotting libraries seem to be a constant point of discussion for various platforms. I would love to hear if you have any updates for attractive realtime plotting in java.

    I was excited to use the fast plotting of visualvm in my netbeans platform project but after including the two clusters you identified in your post I still received an unresolved symbol error in the project for your example code. After considerable searching I attempted to import com.sun.tools.visualvm.* but to no avail. I'm a bit of a noob with netbeans, the netbeans platform, and clusters so it might be something simple. But after an hour of searching I've hit a bit of a road block and was hoping that I'm missing something obvious.


  • Geertjan Tuesday, December 25, 2012

    Kyle, not sure what I can do based on the info you've provided. What does "an unresolved symbol error" mean -- isn't that too generic for you to hope for me to be able to help you?


  • Ken Favières Sunday, June 15, 2014

    Hi Geertjan,

    I just wanted to execute your demo from http://java.dzone.com/news/real-time-charts-java-desktop.

    I've downloaded file com-sun-tools-visualvm-charts.jar and created at Netbeans's ant library manager the corresponding class path to it.

    When I try to execute the demo this runtime error occurs:

    -----begin

    Exception in thread "main" java.lang.NoClassDefFoundError: org/netbeans/lib/profiler/charts/ItemsModel

    at com.sun.tools.visualvm.charts.ChartFactory.createSimpleXYChart(ChartFactory.java:42)

    at graphs.Graphs.createModels(Graphs.java:40)

    at graphs.Graphs.<init>(Graphs.java:27)

    at graphs.Graphs.main(Graphs.java:74)

    Caused by: java.lang.ClassNotFoundException: org.netbeans.lib.profiler.charts.ItemsModel

    at java.net.URLClassLoader$1.run(URLClassLoader.java:366)

    at java.net.URLClassLoader$1.run(URLClassLoader.java:355)

    at java.security.AccessController.doPrivileged(Native Method)

    at java.net.URLClassLoader.findClass(URLClassLoader.java:354)

    at java.lang.ClassLoader.loadClass(ClassLoader.java:423)

    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)

    at java.lang.ClassLoader.loadClass(ClassLoader.java:356)

    ... 4 more

    Java Result: 1

    BUILD SUCCESSFUL (total time: 1 second)

    -----end

    It seems that the corresponding sources cannot be found or do not exist. I have checked that, unlike Ant Library Manager / Classpath, the section Ant Library Manager / Sources is empty.

    What can I do?

    I am using Netbeans 7.2.1 with Java jdk1.7.0_10.

    Thanks in advance,

    Ken


  • Geertjan Monday, June 16, 2014

    Why would you use 7.2.1? And why JDK 7 update 10? Why not just use the latest, i.e., NetBeans 8 and JDK 8?


  • Ken Favi&egrave;res Thursday, June 19, 2014

    Hi again!

    I've upgraded to netbeans 8.0 and jdk1.8.0_05, as you suggested. However, the problem stays the same, throwing the following runtime error. I've included the code as well.

    Any idea?

    Thanks in advance,

    Ken.

    ----the error message----------

    Exception in thread "main" java.lang.NoClassDefFoundError: org/netbeans/lib/profiler/charts/ItemsModel

    at com.sun.tools.visualvm.charts.ChartFactory.createSimpleXYChart(ChartFactory.java:22)

    at rawgraph.RawGraph.createModels(RawGraph.java:43)

    at rawgraph.RawGraph.<init>(RawGraph.java:30)

    at rawgraph.RawGraph.main(RawGraph.java:75)

    Caused by: java.lang.ClassNotFoundException: org.netbeans.lib.profiler.charts.ItemsModel

    at java.net.URLClassLoader$1.run(URLClassLoader.java:372)

    at java.net.URLClassLoader$1.run(URLClassLoader.java:361)

    at java.security.AccessController.doPrivileged(Native Method)

    at java.net.URLClassLoader.findClass(URLClassLoader.java:360)

    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)

    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)

    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)

    ... 4 more

    Java Result: 1

    BUILD SUCCESSFUL (total time: 2 seconds)

    ----------------------

    -----and the code------

    package rawgraph;

    import com.sun.tools.visualvm.charts.ChartFactory;

    import com.sun.tools.visualvm.charts.SimpleXYChartDescriptor;

    import com.sun.tools.visualvm.charts.SimpleXYChartSupport;

    import java.awt.BorderLayout;

    import javax.swing.JPanel;

    public class RawGraph 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 RawGraph(){

    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;

    private long t2, t1;

    public void run() {

    t1 = System.currentTimeMillis();

    while (t2-t1 < 20000) {

    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);

    //t2 = System.currentTimeMillis();

    } catch (Exception e) {

    e.printStackTrace(System.err);

    }

    t2 = System.currentTimeMillis();

    }

    }

    private Generator(SimpleXYChartSupport support) {

    this.support = support;

    }

    } //end Generator

    public static void main(String[] args) {

    // TODO code application logic here

    new RawGraph();

    }

    } // end RawGraph

    -----------------


  • guest Sunday, September 13, 2015

    althought this is an old thread, I was out looking for ways to use this stinking chart stuff, so for future reference for java noobs (like me)... if figured out the problem with this stupid exception.

    the RawGraph constructor tries calls createModels() as it's first item, and createModels() tries to start the thread running with the "new Generator(support).start();" ... HOWEVER, you can't start the thread yet because the next two items in the constructor have business to take care of

    "

    setLayout(new BorderLayout()); // define a JPanel layout

    add(support.getChart(), BorderLayout.CENTER); //add the Janel to the layout

    "

    This is where the NullPointer comes from.

    I added a "startThread()" as the last item in the constructor:

    "

    createModels();

    setLayout(new BorderLayout());

    add(support.getChart(), BorderLayout.CENTER);

    startThread();

    "

    and defined startThread just below createModels() as:

    "

    private void startThread(){

    new Generator(support).start();

    }

    "

    and... then the following changes to main:

    "

    public static void main(String[] args){

    RawGraph rawob = new RawGraph();

    rawob.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    rawob.pack();

    rawob.setVisible(true);

    }

    "

    oh.. Geez... couple more cleanup items I forgot was wrong with this "EXAMPLE"!!!

    1) lots of initial classdef errors, just had to trace class name into visualvm install directory (after downloading visualvm and unzipping, copying inside of java directory,... as there was no actual "install" routine for it) and add the appropriate jar to my neatbeans proj, with an associated import statement

    2) change RawGraph class from "extends JPanel" to "extends JFrame" so I could make the main changes and not have to build a more complicated example.


  • Geertjan Monday, September 14, 2015

    Lengthy comments at the end of a blog entry can probably be done better by means of a blog article of your own or an article some place, with a link to it here. In any case, thanks a lot for these insights and will take a look at them and write an updated blog entry for this (note that I wrote it in 2010, so it would be pretty surprising if everything still worked as it did back then).


Please enter your name.Please provide a valid email address.Please enter a comment.CAPTCHA challenge response provided was incorrect. Please try again.