Skip to content

Instantly share code, notes, and snippets.

@jewelsea
Created September 7, 2012 19:25
Show Gist options
  • Star 8 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save jewelsea/3668862 to your computer and use it in GitHub Desktop.
Save jewelsea/3668862 to your computer and use it in GitHub Desktop.
Uses JavaFX to draw layers of XYCharts.
import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.scene.Scene;
import javafx.scene.chart.BarChart;
import javafx.scene.chart.CategoryAxis;
import javafx.scene.chart.LineChart;
import javafx.scene.chart.NumberAxis;
import javafx.scene.chart.XYChart;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
/**
* Demonstrates how to draw layers of XYCharts.
* https://forums.oracle.com/forums/thread.jspa?threadID=2435995 "Using StackPane to layer more different type charts"
*/
public class LayeredXyChartsSample extends Application {
public static void main(String[] args) { launch(args); }
@Override public void start(Stage stage) {
stage.setScene(
new Scene(
layerCharts(
createBarChart(),
createLineChart()
)
)
);
stage.show();
}
private NumberAxis createYaxis() {
final NumberAxis axis = new NumberAxis(0, 21, 1);
axis.setPrefWidth(35);
axis.setMinorTickCount(10);
axis.setTickLabelFormatter(new NumberAxis.DefaultFormatter(axis) {
@Override public String toString(Number object) {
return String.format("%7.2f", object.floatValue());
}
});
return axis;
}
private BarChart<String, Number> createBarChart() {
final BarChart<String, Number> chart = new BarChart<>(new CategoryAxis(), createYaxis());
setDefaultChartProperties(chart);
chart.getData().addAll(
new XYChart.Series(
FXCollections.observableArrayList(
new XYChart.Data("Jan", 2),
new XYChart.Data("Feb", 10),
new XYChart.Data("Mar", 8),
new XYChart.Data("Apr", 4),
new XYChart.Data("May", 7),
new XYChart.Data("Jun", 5),
new XYChart.Data("Jul", 4),
new XYChart.Data("Aug", 8),
new XYChart.Data("Sep", 16.5),
new XYChart.Data("Oct", 13.9),
new XYChart.Data("Nov", 17),
new XYChart.Data("Dec", 10)
)
)
);
return chart;
}
private LineChart<String, Number> createLineChart() {
final LineChart<String, Number> chart = new LineChart<>(new CategoryAxis(), createYaxis());
setDefaultChartProperties(chart);
chart.setCreateSymbols(false);
chart.getData().addAll(
new XYChart.Series(
FXCollections.observableArrayList(
new XYChart.Data("Jan", 1),
new XYChart.Data("Feb", 2),
new XYChart.Data("Mar", 1.5),
new XYChart.Data("Apr", 3),
new XYChart.Data("May", 2.5),
new XYChart.Data("Jun", 5),
new XYChart.Data("Jul", 4),
new XYChart.Data("Aug", 8),
new XYChart.Data("Sep", 6.5),
new XYChart.Data("Oct", 13),
new XYChart.Data("Nov", 10),
new XYChart.Data("Dec", 20)
)
)
);
return chart;
}
private void setDefaultChartProperties(final XYChart<String, Number> chart) {
chart.setLegendVisible(false);
chart.setAnimated(false);
}
private StackPane layerCharts(final XYChart<String, Number> ... charts) {
for (int i = 1; i < charts.length; i++) {
configureOverlayChart(charts[i]);
}
StackPane stackpane = new StackPane();
stackpane.getChildren().addAll(charts);
return stackpane;
}
private void configureOverlayChart(final XYChart<String, Number> chart) {
chart.setAlternativeRowFillVisible(false);
chart.setAlternativeColumnFillVisible(false);
chart.setHorizontalGridLinesVisible(false);
chart.setVerticalGridLinesVisible(false);
chart.getXAxis().setVisible(false);
chart.getYAxis().setVisible(false);
chart.getStylesheets().addAll(getClass().getResource("overlay-chart.css").toExternalForm());
}
}
/** file: overlay-chart.css (place in same directory as LayeredXyChartsSample */
.chart-plot-background {
-fx-background-color: transparent;
}
.default-color0.chart-series-line {
-fx-stroke: forestgreen;
}
@jewelsea
Copy link
Author

jewelsea commented Sep 7, 2012

Official platform feature request: http://javafx-jira.kenai.com/browse/RT-12710 "chart API -- multiple chart types on the same axis"

@jewelsea
Copy link
Author

jewelsea commented Sep 7, 2012

https://forums.oracle.com/forums/thread.jspa?threadID=243599 "Using StackPane to layer more different type charts"

@KilianB
Copy link

KilianB commented Sep 6, 2018

A not yet finished work around: https://github.com/KilianB/JavaFXMultiChart

@dmos62
Copy link

dmos62 commented Dec 15, 2019

Something like this can be used to avoid using CSS files. In above example it's used because these CSS properties don't have getters/setters, but you can access the children nodes and do .setStyle on them.

    [...]
        var children = mapCssClassesToNodes(chart.getPlotChildren());

        var cssClassOfChartBackground = "chart-plot-background";
        var chartBackground = children.get(cssClassOfChartBackground);

        var cssRuleToMakeBackgroundTransparent = "-fx-background-color: transparent";
        chartBackground.setStyle(cssRuleToMakeBackgroundTransparent);
    }

    private Map<String,Node> mapCssClassesToNodes(List<Node> nodes) {
        var map = new HashMap<String,Node>();
        for (Node child : children) {
            var cssClasses = child.getStyleClass();
            for (String cssClass : cssClasses) {
                map.put(cssClass, child);
            }
        }
        return map;
    }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment