DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Related

  • Creating a Polar Chart to Measure Electromagnetic Field Strength
  • Building a Reusable Framework to Standardize API Ingestion in an On-Prem Lakehouse
  • The Update Problem REST Doesn't Solve
  • Stop Guessing, Start Seeing: A Five -Layer Framework for Monitoring Distributed Systems

Trending

  • AWS Managed Database Observability: Monitoring DynamoDB, ElastiCache, and Redshift Beyond CloudWatch
  • The Update Problem REST Doesn't Solve
  • Why SAP S/4HANA Landscape Design Impacts Cloud TCO More Than Compute Costs
  • Chat with Your Oracle Database: SQLcl MCP + GitHub Copilot
  1. DZone
  2. Coding
  3. Frameworks
  4. Introducing Sierra Charts

Introducing Sierra Charts

See how Sierra's new Charts feature can be used to easily add charting support to your client or server-side Java applications.

By 
Greg Brown user avatar
Greg Brown
·
Feb. 13, 26 · Analysis
Likes (0)
Comment
Save
Tweet
Share
1.3K Views

Join the DZone community and get the full member experience.

Join For Free

Sierra is an open-source framework for simplifying the development of Java Swing applications. It is based on the open-source Kilo framework, which has been discussed in previous articles:

  • Writing (Slightly) Cleaner Code With Collections and Optionals
  • Efficiently Transforming JDBC Query Results to JSON
  • Using Schema Annotations to Create and Execute SQL Queries

For example, Sierra's UILoader class can be used to easily construct a hierarchy of user interface elements:

XML
 
<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE column-panel SYSTEM "sierra.dtd">

<column-panel padding="8" opaque="true" background="white">
    <image-pane image="world.png" scaleMode="fill-width"/>
    <text-pane text="Hello, World!" horizontalAlignment="center"/>
</column-panel>

Greeting test

Although the same result could be achieved programmatically, as shown below, the markup version is less verbose and more readable:

Java
 
var columnPanel = new ColumnPanel();

columnPanel.setBorder(new EmptyBorder(8, 8, 8, 8));

columnPanel.setOpaque(true);
columnPanel.setBackground(Color.WHITE);

var imagePane = new ImagePane();

try (var inputStream = getClass().getResourceAsStream("world.png")) {
    imagePane.setImage(ImageIO.read(inputStream));
} catch (IOException exception) {
    throw new RuntimeException(exception);
}

imagePane.setScaleMode(ImagePane.ScaleMode.FILL_WIDTH);

columnPanel.add(imagePane);

var textPane = new TextPane("Hello, World!");

textPane.setHorizontalAlignment(HorizontalAlignment.CENTER);

columnPanel.add(textPane);


Sierra also includes some common user interface elements not provided by Swing, such as date/time pickers:

Date picker

Time picker

Sierra Charts

As of version 3.6, Sierra now additionally provides support for the following common chart types:

  • Pie/Doughnut
  • Bar/Stacked bar
  • Time series
  • Scatter
  • Candlestick

Each is discussed in more detail below.

Data Sets

Instances of the DataSet class represent the data to be presented by a chart:

Java
 
public class DataSet<K extends Comparable<? super K>, V> { ... }


DataSet defines the following properties:

  • "label" – a description of the data set, as a String
  • "color" – the color associated with the data set, as a Color
  • "stroke" – the stroke associated with the data set, as an instance of BasicStroke
  • "dataPoints" – the data set's data points, as an instance of SortedMap

Map keys generally represent the chart's domain, with their associated values representing the range.

For example, this code creates a simple data set for use by a time series chart. The sortedMapOf() and entry() methods are provided by Kilo's Collections class:

Java
 
var dataSet = new DataSet<Double, Double>("Positive Values", Color.RED);

dataSet.setDataPoints(sortedMapOf(
    entry(0.0, 0.0),
    entry(1.0, 10.0),
    entry(2.0, 20.0),
    entry(3.0, 30.0),
    entry(4.0, 40.0)
));


The resulting output is shown below:

Output

ChartPane

The ChartPane component displays a chart. Chart panes can be created either programmatically or declaratively. For example:

XML
 
<column-panel tabTitle="Pie Chart" opaque="true" background="TextArea.background" spacing="16" padding="16">
    <label font="h1.font" text="Sales by Region" horizontalAlignment="center"/>
  
    <chart-pane name="pieChartPane" weight="1"/>
  
    <row-panel>
        <spacer weight="1"/>
        <row-panel name="pieChartLegendPanel" spacing="16"/>
        <spacer weight="1"/>
    </row-panel>
</column-panel>


The following code creates a pie chart and populates the associated legend panel using the labels from the chart's data set and instances of the PieChart.LegendIcon type:

Java
 
pieChartPane.setChart(createPieChart());

for (var dataSet : pieChartPane.getChart().getDataSets()) {
    pieChartLegendPanel.add(new JLabel(dataSet.getLabel(),
        new PieChart.LegendIcon(dataSet),
        SwingConstants.LEADING));
}


Pie Charts

The PieChart class represents a pie chart:

Java
 
public class PieChart<K extends Comparable<? super K>, V extends Number> extends Chart<K, V> { ... }


The chart displays one slice per data set:

Pie chart per slice

The size of each slice is determined by dividing the sum of its associated data point values by the total of all data point values across all data sets.

Pie charts can also be presented as a doughnut:

Doughnut chart

Bar Charts

The BarChart class displays a bar chart:

Java
 
public class BarChart<K extends Comparable<? super K>, V extends Number>
        extends CategoryChart<K, V> {
    ...
}

Bar chart



Java
 
var northDataSet = new DataSet<Month, Double>("North", UILoader.getColor("light-coral"));

northDataSet.setDataPoints(sortedMapOf(
    entry(Month.JANUARY, 30.0),
    entry(Month.FEBRUARY, 5.0),
    entry(Month.MARCH, 20.0)
));

var southDataSet = new DataSet<Month, Double>("South", UILoader.getColor("orange"));

southDataSet.setDataPoints(sortedMapOf(
    entry(Month.JANUARY, 40.0),
    entry(Month.FEBRUARY, 10.0),
    entry(Month.MARCH, 75.0)
));

...


Category labels are produced by the chart's domain label transform:

Java
 
barChart.setDomainLabelTransform(
        month -> month.getDisplayName(TextStyle.FULL, Locale.getDefault())
);


Range labels are produced by the range label transform:

Java
 
var rangeLabelFormat = NumberFormat.getNumberInstance();

rangeLabelFormat.setMinimumFractionDigits(1);
rangeLabelFormat.setMaximumFractionDigits(1);

barChart.setRangeLabelTransform(rangeLabelFormat::format);


Bars may optionally be stacked:

Stacked bar chart

Time Series Charts

The TimeSeriesChart class displays a collection of values over a period of time:

Java
 
public class TimeSeriesChart<K extends Comparable<? super K>, V extends Number>
        extends XYChart<K, V> {
    ...
}


For example, this chart shows a series of Double values (plotted on the y-axis) collected at Integer intervals (plotted on the x-axis):

Time series chart

It also demonstrates the use of domain markers, which can be used to highlight specific data points.

Individual value markers may optionally be shown:

Time series chart with individual value markers

Scatter Charts

The ScatterChart class displays the relationship between two variables:

Java
 
public class ScatterChart<K extends Comparable<? super K>, V extends Number>
        extends XYChart<K, V> {
    ...
}

Scatter chart

Linear trend lines may optionally be shown to help draw a correlation between the values:

Scatter chart with linear trend lines

Candlestick Charts

The CandlestickChart class displays a collection of OHLC (open, high, low, close) values:

Java
 
public class CandlestickChart<K extends Comparable<? super K>>
        extends CategoryChart<K, OHLC> {
    ...
}


Candlestick charts are typically used to present historical pricing information. The box (or "body") represents the opening and closing values. A hollow body indicates a positive trend (a value where the closing price is higher than the opening price). A solid body represents a negative trend (a value where the closing price is lower than the opening price). The "wick" lines above and below the body represent the high and low values, respectively:

Candlestick charts

The OHLC type is defined as follows:

Java
 
public record OHLC(
    double open,
    double high,
    double low,
    double close
) { ... }


Headless Usage

Charts can also be used in a headless environment. For example, the following code uses Apache Batik to create an SVG representation of a chart:

Java
 
var document = domImplementation.createDocument("http://www.w3.org/2000/svg", "svg", null);

var svgGraphics = new SVGGraphics2D(document);

chart.draw(svgGraphics, WIDTH, HEIGHT);

var writer = new StringWriter();

svgGraphics.stream(writer, false);


Complete Example

The following is a complete example of an application built using Sierra. It uses the Tiingo End-of-Day API to retrieve historical stock pricing information:

Example of an application built using Sierra

The source code for this example can be found here. For more information, see the project README.

Chart Data set Framework

Opinions expressed by DZone contributors are their own.

Related

  • Creating a Polar Chart to Measure Electromagnetic Field Strength
  • Building a Reusable Framework to Standardize API Ingestion in an On-Prem Lakehouse
  • The Update Problem REST Doesn't Solve
  • Stop Guessing, Start Seeing: A Five -Layer Framework for Monitoring Distributed Systems

Partner Resources

×

Comments

The likes didn't load as expected. Please refresh the page and try again.

  • RSS
  • X
  • Facebook

ABOUT US

  • About DZone
  • Support and feedback
  • Community research

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 215
  • Nashville, TN 37211
  • [email protected]

Let's be friends:

  • RSS
  • X
  • Facebook