Data labels in Vaadin Charts 3 Java

In this short tutorial, I'll share a couple of tips related to data labels. The code snippets available in this tutorial, can be used as is in Vaadin Charts 4 as long as you have a Vaadin Framework 8 project. In Charts 4, the API calls using java.util.Date have been deprecated in favor of java.time.Instant. Full code samples of this tutorial using Vaadin Framework 7 and Charts 3.2 are available here.

Starting point: a simple line chart

As a starting point, we need some kind of a chart. I used a simple line chart plotting the average temperatures in Turku, Finland in July every year since 1961. The data is available in the Finnish Meteorological Institute's website. From the basic axis configuration, the most important one for me was to configure the x-axis to be a type of DateTime because of the format of the data I had available from the FMI site. I also customised the data series color. The basics of styling charts are covered well in a separate blog article available here.

Chart showing average temperatures in Turku, Finland every July since 1961

Chart chart = new Chart();

Configuration conf = chart.getConfiguration();
conf.setTitle("Average temperatures in Turku, Finland");
conf.setSubTitle("1961 - 2016");

XAxis xAxis = conf.getxAxis();
xAxis.setType(AxisType.DATETIME);
xAxis.setTitle("Year");

YAxis yAxis = conf.getyAxis();
yAxis.setTitle("Temperature (℃)");
yAxis.setMax(30);
yAxis.setMin(0);

/* get data csv values and map those to a list of DataSeriesItem */
List<DataSeriesItem> items = getDataSeriesItems(Month.JULY);
DataSeries series = new DataSeries(items);
series.setName("July");
conf.addSeries(series);

chart.drawChart();
 

The resulting chart looks good for a starting point: the axes are labeled properly and the units are present. The point tooltip could use some tweaking to get the measurement unit visible.

Configuring data point tooltip

The tooltip is easy to configure through a SeriesTooltip object. You can override the default tooltip formats by using setHeaderFormat for the tooltip header format and setPointFormat for the point format. For now, we're only interested in adding the ℃ unit to the tooltip after the point value. To achieve this we can use setValueSuffix.


PlotOptionsLine options = new PlotOptionsLine();
options.getTooltip().setValueSuffix(" ℃");
series.setPlotOptions(options);

Data point tooltip with unit

Adding data labels

Now let's add some informational value using data labels. We could enable labels for each point easily, but in this case it would add very little value. Instead, let's add labels for the top 10 coldest and hottest years.

There are probably a lot of better ways to find the coldest and hottest points from the data, but here's my way:

// For coldest
items.stream().sorted(Comparator.comparingDouble(item ->
  item.getY().doubleValue())).limit(10).forEach(/* add data label */);
// For hottest
items.stream().sorted(Collections.reverseOrder(Comparator.comparingDouble(item ->
  item.getY().doubleValue()))).limit(10).forEach(/* add data label */);

For the top coldest points I want to have a blue callout style label below the point and for the hottest ones a red callout above the point.

private static void addCallout(DataSeriesItem item, SolidColor bgColor, Number labelY) {
    DataLabels callout = new DataLabels(true);
    callout.setVerticalAlign(VerticalAlign.MIDDLE);
    callout.setShape(Shape.CALLOUT);
    callout.setY(labelY);
    callout.setBackgroundColor(bgColor);
    callout.setColor(SolidColor.WHITE);
    callout.setBorderWidth(1);
    callout.setBorderRadius(4);
    callout.setPadding(3);
    callout.setFormat("{y}<br/>℃");
    item.setDataLabels(callout);
}

private static void addCalloutAbove(DataSeriesItem item) {
    addCallout(item, new SolidColor("#ff3a49"), -25);
}

private static void addCalloutBelow(DataSeriesItem item) {
    addCallout(item, new SolidColor("#00b4f0"), 25);
}

Callout shaped data label with unit

The result looks good, but there is still one gotcha: when two labels overlap, one of them is hidden. You can allow overlapping by setting it for every label of a series in the PlotOptionsLine.

DataSeries series = new DataSeries(items);
PlotOptionsLine options = new PlotOptionsLine();
DataLabels labels = new DataLabels();
labels.setAllowOverlap(true);
options.setDataLabels(labels);
options.getTooltip().setValueSuffix(" ℃");
series.setPlotOptions(options);
series.setName(name);

The labels don't disappear when overlapped, but the result is a bit crowded.

Callout shaped data label overlapping

Changing the font size to a smaller one fixes the situation.

callout.getStyle().setFontSize("9px");

Here's the end result.

Chart displaying top 10 hottest and coldest Julys since 1961 using a callout shaped data label

This was a brief introduction to data labels in Vaadin Charts. I gathered the information from Vaadin Docs, Charts 3.2.0 API documentation, and the Charts demo collection. Try these tips and other ways to configure your charts yourself.

See more tutorials