Docs

Documentation versions (currently viewingVaadin 8)

Vaadin 8 reached End of Life on February 21, 2022. Discover how to make your Vaadin 8 app futureproof →

Getting Started with Vaadin Charts

Introduction

This tutorial walks you through the steps needed to create a new Vaadin application and show some elegant charts in it. We use Maven to set up the project and handle the dependencies.

In this tutorial, you will learn how to:

  1. Add Vaadin Charts to a project

  2. Create a simple line chart

  3. Create a combined chart with dual Y-axes

  4. Configure settings to change the look of a chart

The final result of this tutorial can be explored in GitHub at github.com/vaadin/charts-tutorial/tree/master/server. Let us get to it.

Project Setup

To start off, we need to create a new project where we can add the charts. For more details on this topic, please refer to "Installing Vaadin Charts" and Vaadin Add-ons.

Here we use Maven to set up a project, using the command-line. You can then be import the project into your IDE. You can use the IDE to generate a new maven project using the vaadin-archetype-application archetype, but in the following example we do it on command-line.

$ mvn archetype:generate -DarchetypeGroupId=com.vaadin \
 -DarchetypeArtifactId=vaadin-archetype-application \
 -DarchetypeVersion=8.0.0
Note
Replace the version with the latest available.

Archetype generation asks you a few parameters to set up the project. You need to give at least groupId and artifactId. You could answer as follows:

Define value for property 'groupId': : com.vaadin
Define value for property 'artifactId': : charts-tutorial
Define value for property 'version': 1.0-SNAPSHOT: : Enter
Define value for property 'package': com.vaadin: : Enter
[INFO] Using property: theme = mytheme
Confirm properties configuration:
groupId: com.vaadin
artifactId: charts-tutorial
version: 1.0-SNAPSHOT
package: com.vaadin
theme: mytheme
Y: : Enter

You now should have a project generated for you. It was created in a directory with the same name as the artifactId parameter that you specified, such as, charts-tutorial.

You can run the new project by issuing the following command:

$ cd charts-tutorial
$ mvn vaadin:compile jetty:run

The command will compile all sources and start a local web server. Wait until it says “Started Jetty Server” and navigate to http://localhost:8080 with your browser. Note that you do not usually need to call vaadin:compile. It is only the needed in the following cases: the first time you compile a new project created with the application archetype, when you have changed the widget set somehow, or if you add an add-on to your project, as we will see later.

In the browser, you should see a button titled Click Me. When you click it, the text Thank you for clicking appears below the button. Great! We can now move on to replace this button with a pretty chart! Stop the web server by pressing Ctrl+C in the window where you started it.

Let us then add the Vaadin Charts dependency to the project. Open the pom.xml file and find the <dependencies> tag. Add the following dependency declaration just before the end tag (</dependencies>):

...
   <dependency>
      <groupId>com.vaadin</groupId>
      <artifactId>vaadin-charts</artifactId>
      <version>4.0.5</version>
   </dependency>
</dependencies>
...

You need to have a license for Vaadin Charts in order to be able to compile the widget set. You can get a free trial key from Vaadin Directory. Click the large orange Free trial key button on the right. Then copy and paste the key into a file named .vaadin.charts.developer.license in your home directory.

Once the key is in place, you can issue the following command to compile the widget set:

$ mvn clean vaadin:update-widgetset vaadin:compile

You have now created a new project and enabled Vaadin Charts in it. You can now move on to create your charts.

Creating Your First Chart

On to actual programming! Let us replace the button with an empty chart. Open the com.vaadin.MyVaadinUI class and change the init() method to the following:

protected void init(VaadinRequest request) {
   final VerticalLayout layout = new VerticalLayout();
   layout.setMargin(true);
   setContent(layout);

   Chart chart = new Chart();
   layout.addComponent(chart);
}

Now run it by issuing 'mvn jetty:run' on the command line and load http://localhost:8080 in a browser. You should see an empty white box with the title Chart title and a small Vaadin Charts in the bottom right corner.

Let us make the title say something else. Add the following lines at the end of the init() method:

Configuration conf = chart.getConfiguration();
conf.setTitle("Hello Charts!");

Stop the old jetty process by pressing Ctrl+C and restart it by issuing 'mvn jetty:run' once more. Reload the page in the browser. The title of the chart should now read Hello Charts!. As you see, changing the properties of a chart is done through an instance of the Configuration class. When creating a chart, it automatically creates an instance of the Configuration class. You can get a reference to it by calling getConfiguration().

For more details, see "Basic Use of Charts".

Adding Some Data

Let us add some real data! Like any good TV chef, we have prepared a Java class that provides some example data for us to create charts from. Download the file from the tutorial repository in GitHub and save it in the same package as the MyVaadinUI class. Good, now we have some data to use.

Next, we will turn our chart to a line chart. This is done by altering the configuration. Just add it to the end of the init() method as follows:

conf.getChart().setType(ChartType.LINE);

The ChartData class contains data for the average shoe size per age for girls and boys. Let us add the shoe size data for girls. Data can be added to a chart by creating a Series object. We use DataSeries and create individual DataSeriesItems for each (shoe size, age) value pair.

Continue the init() method as follows:

ChartsData data = new ChartsData();
DataSeries girls = new DataSeries("Girls");
for(ShoeSizeInfo shoeSizeInfo : data.getGirlsData()) {
   // Shoe size on the X-axis, age on the Y-axis
   girls.add(new DataSeriesItem(
         shoeSizeInfo.getSize(),
         shoeSizeInfo.getAgeMonths()/12.0f));
}
conf.addSeries(girls);

Now restart the server again (Ctrl+C, mvn jetty:run), refresh your browser, and see that we now have a nice line chart!

However, there is still something missing. We have no units or labels for the X or Y axes. This needs to be fixed. Add the following:

conf.getxAxis().setTitle("Shoe size (EU)");
conf.getyAxis().setTitle("Age (Years)");

Restart the server and refresh your browser. Now the axes are labeled and we are well on our way!

For more details on data series, see "Chart Data".

Adding Another Data Set to the Same Chart

Now, let us add the same data for boys to the same chart. This is as easy as adding a second series to the chart configuration. We duplicate the code above and add the boy’s data series:

DataSeries boys = new DataSeries("Boys");
for(ShoeSizeInfo shoeSizeInfo : data.getBoysData()) {
   // Shoe size on the X-axis, age on the Y-axis
   boys.add(new DataSeriesItem(
        shoeSizeInfo.getSize(),
        shoeSizeInfo.getAgeMonths()/12.0f));
}
conf.addSeries(boys);

Restart the server and refresh your browser. We now have two data sets, shown with two different colors and shapes. The identifiers for both are shown in the legend below the chart. Try clicking on any of the legend items – it toggles the visibility of the series!

Finally, change the title of the chart to something that describes it, for example, "Shoe size per age for boys and girls".

Configuring the Colors

Our chart looks OK, but it would be more intuitive to read if the data for girls is rendered using a color normally associated with girls, would it not? Let us make the the girl data pink and the boy data light blue.

The colors of the lines can be changed in two ways:

  1. By modifying the theme, which specifies the colors for different series. The first series will get the first color specified in the theme, the second will get the second color, and so on.

  2. By specifying plot options for a specific series and setting the color in the plot options.

In the following we specify the color by configuring plot options for the series. Add the following to the end of the init method:

PlotOptionsLine girlsOpts = new PlotOptionsLine();
girlsOpts.setColor(SolidColor.HOTPINK);
girls.setPlotOptions(girlsOpts);

PlotOptionsLine boysOpts = new PlotOptionsLine();
boysOpts.setColor(SolidColor.BLUE);
boys.setPlotOptions(boysOpts);

Great! Restart the server and reload your browser to see the finished chart.

Creating a Combination Chart

We can now go ahead doing something more complex. The ChartData class also has historical weather data for Turku, Finland, during most of the year 2013. Let us plot the temperature as a line chart and add columns for humidity to the same chart to create a combination chart.

For more details on combination charts, see "Mixed-Type Charts".

Preparations

To clean up our code a bit, let us extract the creation of the shoe size chart to a method called getShoeSizeChart(ChartsData). This way, we can add the new weather chart without getting really messy code. Go ahead and extract the method, after which the init() method should look something as follows:

protected void init(VaadinRequest request) {
   final VerticalLayout layout = new VerticalLayout();
   layout.setMargin(true);
   setContent(layout);

   ChartsData data = new ChartsData();
   layout.addComponent(getShoeSizeChart(data));
}

Now create another new method, let us call it getWeatherChart(ChartsData) and call it in the same way as the getShoeSizeChart() method in the init() method:

layout.addComponent(getWeatherChart(data));

As the temperature data is supposed to be shown as a line chart, we can start in much the same way as the shoe size chart, with just a few differences. This time, we use a different kind of data series object, a DataProviderSeries, and configure the X-axis to be a date/time axis. The result looks as follows:

private Chart getWeatherChart(ChartsData data) {
  Chart chart = new Chart();
  Configuration conf = chart.getConfiguration();
  conf.setTitle("Turku, Finland 2013");

  conf.getChart().setType(ChartType.LINE);
  ListDataProvider<WeatherInfo> dataProvider = new ListDataProvider<>(data.getWeatherData());
  DataProviderSeries<WeatherInfo> temp = new DataProviderSeries<>(dataProvider);

  temp.setName("Temperature");
  temp.setX(WeatherInfo::getInstant);
  temp.setY(WeatherInfo::getMaxTemp);
  conf.addSeries(temp);

  conf.getxAxis().setTitle("Date");
  conf.getxAxis().setType(AxisType.DATETIME);
  conf.getyAxis().setTitle("Temperature (°C)");
  return chart;
}

Let us look a little closer at the new series type. The DataProviderSeries is bound to a normal DataProvider from Vaadin Framework. In this case, we create a ListDataProvider that contains WeatherInfo beans. We then create a DataProviderSeries instance, set the name of the series, and define the functions used for retrieving the X and Y data. In this case, the value returned from a call to the getInstant() method in WeatherInfo will be used as the value of X for each data point. Similarly, the value returned by calling getMaxTemp() will be used as the value of Y.

Configuring the X-axis should be fairly self-explanatory. It just sets the title and type of the axis.

Restart the server and refresh your browser to see the new chart. Awesome! We are well on our way.

Adding Columns and a Second Y-axis

Let us continue by adding the humidity data to the chart. For this set of data, we want to show it using columns instead of lines, which can be done by configuring suitable plot options for the series. We will use the same provider bound to a new DataProviderSeries to provide the data:

ListDataProvider<WeatherInfo> dataProvider = new ListDataProvider<>(weatherInfo);
DataProviderSeries<WeatherInfo> humidity = new DataProviderSeries<>(dataProvider);

humidity.setName("Humidity");
humidity.setX(WeatherInfo::getInstant);
humidity.setY(WeatherInfo::getMeanHumidity);
humidity.setPlotOptions(new PlotOptionsColumn());
conf.addSeries(humidity);

You can restart and refresh to see the results. Now the chart does not look too nice, as the columns completely overlap the temperature chart.

Two things need to be done to make this chart better:

  1. Change the order of the data series to make the temperature line render on top of the columns.

  2. Add a second Y-axis for the humidity, as it is in percent, while the temperature is in Celsius.

Changing the order of the series is simple, just switch the order of the addSeries() calls. Adding a second Y-axis that scales the humidity data in a meaningful way can be done as follows:

YAxis humidityYAxis = new YAxis();
humidityYAxis.setTitle("Humidity (%)");
humidityYAxis.setMin(0);
humidityYAxis.setOpposite(true);
conf.addyAxis(humidityYAxis);
humidity.setyAxis(humidityYAxis);

Here we create a new YAxis, configure the title, set the minimum value, and move the axis to the opposite side of the chart.

The final method should look something as follows:

private Chart getWeatherChart(ChartsData data) {
  Chart chart = new Chart();
  Configuration conf = chart.getConfiguration();
  conf.setTitle("Turku, Finland 2013");

  conf.getChart().setType(ChartType.LINE);

  ListDataProvider<WeatherInfo> dataProvider = new ListDataProvider<>(data.getWeatherData());

  DataProviderSeries<WeatherInfo> temp = new DataProviderSeries<>(dataProvider);

  temp.setName("Temperature");
  temp.setX(WeatherInfo::getInstant);
  temp.setY(WeatherInfo::getMaxTemp);

  conf.getxAxis().setTitle("Date");
  conf.getxAxis().setType(AxisType.DATETIME);
  conf.getyAxis().setTitle("Temperature (°C)");

  DataProviderSeries<WeatherInfo> humidity = new DataProviderSeries<>(dataProvider);

  humidity.setName("Humidity");
  humidity.setX(WeatherInfo::getInstant);
  humidity.setY(WeatherInfo::getMeanHumidity);
  humidity.setPlotOptions(new PlotOptionsColumn());

  conf.addSeries(humidity);
  conf.addSeries(temp);

  YAxis humidityYAxis = new YAxis();
  humidityYAxis.setTitle("Humidity (%)");
  humidityYAxis.setMin(0);
  humidityYAxis.setOpposite(true);
  conf.addyAxis(humidityYAxis);
  humidity.setyAxis(humidityYAxis);

  return chart;
}

Restart, refresh, and enjoy a better looking chart!

Downsampling Data

One issue remains. Drawing the chart is a bit slow, because of the huge amount of data packed into it. To make it more efficient, we need to downsample the data in some way. For very simple downsampling, we can use the Vaadin DataProvider filtering API. Try something like the following filter to show only the values for each Sunday:

dataProvider.addFilter(point -> {
  LocalDateTime date = LocalDateTime.ofInstant(point.getInstant(), ZoneId.of("Europe/Helsinki"));
  return date.getDayOfWeek() == DayOfWeek.SUNDAY;
});

This will make the data more sparse by only taking one data point every seven days. Play around with the filter to see what you can accomplish!

Summary

Congratulations! You now know the basics of how to get charts in your Vaadin application. For further examples, please see the on-line demo at demo.vaadin.com/charts4.