I want to create a scatter chart by fxml file.I put the code below in my fxml file but when it done the render,it did not like I expected.Do somebody know what's going on?
<BorderPane xmlns="http://javafx.com/javafx/8.0.121"
xmlns:fx="http://javafx.com/fxml/1" fx:controller="sample.ChartController">
<left>
<ScatterChart fx:id="memoryDistribution" prefWidth="360" title="Memory Distribution">
<xAxis>
<NumberAxis fx:id="xAxis" label="Memory Address/k" lowerBound="0" upperBound="7" tickUnit="1.00"/>
</xAxis>
<yAxis>
<NumberAxis fx:id="yAxis" label="Memory Address/k" lowerBound="1" upperBound="257" tickUnit="8.00"/>
</yAxis>
</ScatterChart>
</left>
what above code do like this:
wrong expectation
But what I expect is like this:
expectation
the second image code:
public class Main extends Application {
#Override
public void start(Stage primaryStage) throws Exception{
primaryStage.setTitle("Scatter Chart Sample");
final NumberAxis xAxis = new NumberAxis(0, 8, 1);
final NumberAxis yAxis = new NumberAxis(1, 257, 8);
final ScatterChart<Number,Number> sc = new
ScatterChart<>(xAxis,yAxis);
xAxis.setLabel("Memory Address/k");
yAxis.setLabel("Memory Address/k");
sc.setTitle("Memory Distribution");
XYChart.Series series1 = new XYChart.Series();
series1.setName("job-1");
series1.getData().add(new XYChart.Data(0.5, 5));
series1.getData().add(new XYChart.Data(1.5, 5));
series1.getData().add(new XYChart.Data(2.5, 5));
series1.getData().add(new XYChart.Data(3.5, 5));
series1.getData().add(new XYChart.Data(4.5, 5));
series1.getData().add(new XYChart.Data(5.5, 5));
series1.getData().add(new XYChart.Data(6.5, 5));
series1.getData().add(new XYChart.Data(7.5, 5));
series1.getData().add(new XYChart.Data(0.5, 13));
series1.getData().add(new XYChart.Data(1.5, 13));
series1.getData().add(new XYChart.Data(2.5, 13));
series1.getData().add(new XYChart.Data(3.5, 13));
series1.getData().add(new XYChart.Data(4.5, 13));
series1.getData().add(new XYChart.Data(5.5, 13));
XYChart.Series series2 = new XYChart.Series();
series2.setName("job-2");
series2.getData().add(new XYChart.Data(0.5, 29));
series2.getData().add(new XYChart.Data(1.5, 29));
series2.getData().add(new XYChart.Data(2.5, 29));
series2.getData().add(new XYChart.Data(3.5, 29));
series2.getData().add(new XYChart.Data(4.5, 29));
series2.getData().add(new XYChart.Data(5.5, 29));
sc.getData().addAll(series1, series2);
Scene chartScene = new Scene(sc,360,736);//best lookup
primaryStage.setScene(chartScene);
primaryStage.setMaximized(true);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
I already done my demand:the grid on,and the cell size is 256.
I put an any kind of Pane in the fxml,when the init start it should be render and put a blank pane in there.
<center>
<ScrollPane fx:id="chartPane" prefWidth="380" prefHeight="760">
</ScrollPane>
</center>
Then I write the code to init a scatter chart and put it to the above pane.
In the class sample.ChartController as the fxml configured,put the init code in this class,name a method initialize.
private void initialize(){
final NumberAxis xAxis = new NumberAxis(0,8,1);
final NumberAxis yAxis = new NumberAxis(0,256,8);
xAxis.setLabel("Memory Address/k");
yAxis.setLabel("Memory Address/k");
this.memoryDistributionChart = new ScatterChart(xAxis,yAxis);
memoryDistributionChart.setTitle("Memory Distribution");
memoryDistributionChart.setPrefHeight(736);
memoryDistributionChart.setPrefWidth(360);
chartPane.setContent(memoryDistributionChart);
}
memoryDistributionChart is a ScatterChart,a member property.
chartPane is another member property.
finally,the result like this
Because when the main stage render,the controller initialize method should be invoked first.
Related
I have two XY charts and I want them to be placed one on the top and the other at the bottom of a JavaFX application.
Both graph widths should fill their "container" and the bottom graph should be x times smaller than the top graph.
For the sake of reproducibility, here is an example built from Oracle's tutorial:
import javafx.application.Application;
import javafx.geometry.Side;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.chart.CategoryAxis;
import javafx.scene.chart.LineChart;
import javafx.scene.chart.NumberAxis;
import javafx.scene.chart.XYChart;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class Test extends Application {
#Override
public void start(Stage stage) {
stage.setTitle("Line Chart Sample");
final CategoryAxis xAxis1 = new CategoryAxis();
final NumberAxis yAxis1 = new NumberAxis();
xAxis1.setLabel("Month");
final LineChart<String, Number> lineChart1 =
new LineChart<>(xAxis1, yAxis1);
final CategoryAxis xAxis2 = new CategoryAxis();
xAxis2.setLabel("Month");
final NumberAxis yAxis2 = new NumberAxis();
final LineChart<String, Number> lineChart2 =
new LineChart<>(xAxis2, yAxis2);
lineChart1.setLegendVisible(false);
lineChart2.setLegendVisible(false);
XYChart.Series series1 = new XYChart.Series();
series1.setName("Portfolio 1");
series1.getData().add(new XYChart.Data("Jan", 23));
series1.getData().add(new XYChart.Data("Feb", 14));
series1.getData().add(new XYChart.Data("Mar", 15));
series1.getData().add(new XYChart.Data("Apr", 24));
series1.getData().add(new XYChart.Data("May", 34));
series1.getData().add(new XYChart.Data("Jun", 36));
series1.getData().add(new XYChart.Data("Jul", 22));
series1.getData().add(new XYChart.Data("Aug", 45));
series1.getData().add(new XYChart.Data("Sep", 43));
series1.getData().add(new XYChart.Data("Oct", 17));
series1.getData().add(new XYChart.Data("Nov", 29));
series1.getData().add(new XYChart.Data("Dec", 25));
XYChart.Series series2 = new XYChart.Series();
series2.setName("Portfolio 2");
series2.getData().add(new XYChart.Data("Jan", 33));
series2.getData().add(new XYChart.Data("Feb", 34));
series2.getData().add(new XYChart.Data("Mar", 25));
series2.getData().add(new XYChart.Data("Apr", 44));
series2.getData().add(new XYChart.Data("May", 39));
series2.getData().add(new XYChart.Data("Jun", 16));
series2.getData().add(new XYChart.Data("Jul", 55));
series2.getData().add(new XYChart.Data("Aug", 54));
series2.getData().add(new XYChart.Data("Sep", 48));
series2.getData().add(new XYChart.Data("Oct", 27));
series2.getData().add(new XYChart.Data("Nov", 37));
series2.getData().add(new XYChart.Data("Dec", 29));
lineChart1.getData().addAll(series1);
lineChart2.getData().addAll(series2);
Scene scene = new Scene(createVBoxLayout(lineChart1, lineChart2), 800, 600);
stage.setScene(scene);
stage.show();
}
private Parent createVBoxLayout(XYChart chart1, XYChart chart2) {
VBox vBox = new VBox(chart1, chart2);
chart1.prefHeight(200);
chart1.minHeight(200);
chart1.maxHeight(200);
chart2.prefHeight(400);
chart2.minHeight(400);
chart2.maxHeight(400);
return vBox;
}
private Parent createGridLayout(XYChart chart1, XYChart chart2) {
GridPane gridPane = new GridPane();
gridPane.add(chart1, 0, 0, 1, 1);
gridPane.add(chart2, 0, 1, 1, 2);
return gridPane;
}
public static void main(String[] args) {
launch(args);
}
}
The graph on the bottom should be twice as big as the one on the top.
I have tried two approaches:
Method createVBoxLayout creates a VBox and uses the prefered/min/max sizes to modify the chart size.
Here is the result:
Clearly, the bottom graph is not twice as big as the graph at the top. Moreover, the size ratio would not be kept when the window is resized.
The method createGridLayout creates a GridPane, here is the result:
Now, it's the top graph that is twice as big as the bottom one, which is the opposite of what is coded in the method! Moreover, the graphs do not fill the width of the window. Finally, when resizing the window, the charts overlap and don't keep their relative sizes (should be 1/3 - 2/3).
The methods prefHeight(...), minHeight(...), etc do not set the preferred height, etc. They return the computed values for those, with the argument being the width for the chart (i.e. chart1.prefHeight(200) means "tell me the preferred height if the width is 200"). See the documentation.
You need
chart1.setPrefHeight(200);
chart1.setMinHeight(200);
chart1.setMaxHeight(200);
etc.
For the grid pane version, use RowConstraints and ColumnConstraints to control the layout of the grid. The rows are simply resized to contain the nodes they contain, so making a chart span two rows will probably just give one of the rows zero height. (Again, see the documentation.)
private Parent createGridLayout(XYChart chart1, XYChart chart2) {
GridPane gridPane = new GridPane();
gridPane.add(chart1, 0, 0, 1, 1);
gridPane.add(chart2, 0, 1, 1, 2);
RowConstraints top = new RowConstraints(200);
RowConstraints bottom = new RowConstraints(400);
gridPane.getRowConstraints().addAll(top, bottom);
ColumnConstraints cc = new ColumnConstraints();
cc.setHgrow(Priority.ALWAYS);
gridPane.getColumnConstraints().add(cc);
return gridPane;
}
or
private Parent createGridLayout(XYChart chart1, XYChart chart2) {
GridPane gridPane = new GridPane();
gridPane.add(chart1, 0, 0);
gridPane.add(chart2, 0, 1);
RowConstraints top = new RowConstraints();
top.setPercentHeight(100.0 / 3.0);
RowConstraints bottom = new RowConstraints();
bottom.setPercentHeight(200.0 / 3.0);
gridPane.getRowConstraints().addAll(top, bottom);
ColumnConstraints cc = new ColumnConstraints();
cc.setHgrow(Priority.ALWAYS);
gridPane.getColumnConstraints().add(cc);
return gridPane;
}
I have a problem I can not figure out. Please let me put the code first for better explanation:
public class TestXYChart extends Application {
NumberAxis xAxis = new NumberAxis(); // 1
NumberAxis yAxis = new NumberAxis(); // 2
XYChart.Series series1 = new XYChart.Series();
#Override
public void start(Stage primaryStage) {
StackPane root = new StackPane();
Scene scene = new Scene(root, 300, 250);
LineChart lineChart = new LineChart<Number, Number>(xAxis, yAxis);
root.setOnScroll(scrollHandler);
root.getChildren().addAll(lineChart);
series1.getData().add(new XYChart.Data(1, 20));
series1.getData().add(new XYChart.Data(2, 40));
series1.getData().add(new XYChart.Data(3, 100));
series1.getData().add(new XYChart.Data(4, 50));
series1.getData().add(new XYChart.Data(5, 170));
series1.getData().add(new XYChart.Data(6, 190));
series1.getData().add(new XYChart.Data(7, 30));
series1.getData().add(new XYChart.Data(8, 39));
series1.getData().add(new XYChart.Data(9, 44));
series1.getData().add(new XYChart.Data(10, 78));
series1.getData().add(new XYChart.Data(11, 93));
series1.getData().add(new XYChart.Data(12, 75));
// this.loadIntoDataBaseFromFile();
lineChart.getData().addAll(series1);
lineChart.setAnimated(true);
lineChart.setAlternativeColumnFillVisible(false);
lineChart.setAlternativeRowFillVisible(false);
primaryStage.setTitle("Hello World!");
primaryStage.setScene(scene);
primaryStage.show();
}
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
EventHandler scrollHandler = new EventHandler<ScrollEvent>(){
#Override
public void handle(ScrollEvent event) {
System.out.println("Handling Scroll Event");
xAxis.setLowerBound(xAxis.getLowerBound() + 1);
xAxis.setUpperBound(xAxis.getUpperBound() - 1);
}
};
}
I use the code above to test whether I can operate the LineChart, especially when I scroll mouse, the LineChart will zoom in/out.
I found the fact that exactly as above code, it doesn't work. But if we just change the first two line codes, change from:
NumberAxis xAxis = new NumberAxis(); // 1
NumberAxis yAxis = new NumberAxis(); // 2
to:
NumberAxis xAxis = new NumberAxis(0,12,0.5); // 1
NumberAxis yAxis = new NumberAxis(0,300,10); // 2
Everything works well. So, why it happens like this?Thank you.
And, if I seperate the new NumberAxis(...) instance from the declaration NumberAxis xAxis/yAxis, it doesn't work too.
The difference between using an empty constructor or with arguments is clear if you have a look at NumberAxis JavaDoc:
public NumberAxis()
Create a auto-ranging NumberAxis
and
public NumberAxis(double lowerBound, double upperBound, double tickUnit)
Create a non-auto-ranging NumberAxis with the given upper bound, lower bound and tick unit
Basically, the first one has autoRanging set to true, what means it will try to show the data, no matter how you modify the bounds of the axis.
On the contrary, the second one has autoRanging set to false, so any change in the axis bounds will be reflected on the chart.
Note that you can set this in the first case to change the default behaviour:
xAxis.setAutoRanging(false);
I tested this css code to change chart color but I get NPE when I run the code:
public class MainApp extends Application {
#Override public void start(Stage stage) {
stage.setTitle("Line Chart Sample");
//defining the axes
final NumberAxis xAxis = new NumberAxis();
final NumberAxis yAxis = new NumberAxis();
xAxis.setLabel("Number of Month");
//creating the chart
final LineChart<Number,Number> lineChart = new LineChart<>(xAxis,yAxis);
// Look up first series fill
Node node = lineChart.lookup(".default-color0.chart-series-area-fill");
// Set the first series fill to translucent pale green
node.setStyle("-fx-fill: linear-gradient(#f2f2f2, #d4d4d4);"
+ " -fx-background-insets: 0 0 -1 0, 0, 1, 2;"
+ " -fx-background-radius: 3px, 3px, 2px, 1px;");
Node nodew = lineChart.lookup(".chart-series-area-line");
// Set the first series fill to translucent pale green
nodew.setStyle("-fx-stroke: #989898; -fx-stroke-width: 1px; ");
lineChart.setTitle("Stock Monitoring, 2010");
//defining a series
XYChart.Series series = new XYChart.Series();
series.setName("My portfolio");
//populating the series with data
series.getData().add(new XYChart.Data(1, 23));
series.getData().add(new XYChart.Data(2, 14));
series.getData().add(new XYChart.Data(3, 15));
series.getData().add(new XYChart.Data(4, 24));
series.getData().add(new XYChart.Data(5, 34));
series.getData().add(new XYChart.Data(6, 36));
series.getData().add(new XYChart.Data(7, 22));
series.getData().add(new XYChart.Data(8, 45));
series.getData().add(new XYChart.Data(9, 43));
series.getData().add(new XYChart.Data(10, 17));
series.getData().add(new XYChart.Data(11, 29));
series.getData().add(new XYChart.Data(12, 25));
Scene scene = new Scene(lineChart,800,600);
lineChart.getData().add(series);
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
This line is the problem:
node.setStyle("-fx-fill: linear-gradient(#f2f2f2, #d4d4d4);".........);
Can you tell me how I can fix this? This css code was used in AreaChart. Now I want to use it in LineChart.
P.S
I also tried this css from the example:
http://docs.oracle.com/javafx/2/charts/css-styles.htm
Node node = lineChart.lookup(".default-color0.chart-series-line");
// Set the first series fill to translucent pale green
node.setStyle("-fx-stroke: #e9967a;");
But again I get NPE.
Make sure you refer to the css documentation for the type of node you are using to see which style classes it supports.
Lookups are generally not available until css styling has been applied to the node. This means, at the very least, that it must have been rendered to the screen, but it seems that on occasion it takes another frame or two. So, if you want to use a lookup, you must call it after you have called stage.show();, sometimes you need to take further steps to call it later.
A much better approach is to use an external style sheet. See the tutorial: there's also a specific page for styling charts.
Update (additional idea):
In Java 8 (and maybe in JavaFX 2.2: I don't have a copy of caspian.css convenient), all the data-related colors are defined in terms of the lookup colors CHART_COLOR_1 through CHART_COLOR_8. This gives a nice one-liner to set the colors, at least:
lineChart.setStyle("CHART_COLOR_1: #e9967a;");
You have to lookup the nodes after the stage has been shown.
public class MainApp extends Application
{
#Override public void start(Stage stage)
{
stage.setTitle("Line Chart Sample");
//defining the axes
final NumberAxis xAxis = new NumberAxis();
final NumberAxis yAxis = new NumberAxis();
xAxis.setLabel("Number of Month");
//creating the chart
final LineChart<Number,Number> lineChart = new LineChart<>(xAxis,yAxis);
lineChart.setTitle("Stock Monitoring, 2010");
//defining a series
XYChart.Series series = new XYChart.Series();
series.setName("My portfolio");
//populating the series with data
series.getData().add(new XYChart.Data(1, 23));
series.getData().add(new XYChart.Data(2, 14));
series.getData().add(new XYChart.Data(3, 15));
series.getData().add(new XYChart.Data(4, 24));
series.getData().add(new XYChart.Data(5, 34));
series.getData().add(new XYChart.Data(6, 36));
series.getData().add(new XYChart.Data(7, 22));
series.getData().add(new XYChart.Data(8, 45));
series.getData().add(new XYChart.Data(9, 43));
series.getData().add(new XYChart.Data(10, 17));
series.getData().add(new XYChart.Data(11, 29));
series.getData().add(new XYChart.Data(12, 25));
Scene scene = new Scene(lineChart,800,600);
lineChart.getData().add(series);
stage.setScene(scene);
stage.show();
// Look up first series fill
Node node = lineChart.lookup(".default-color0.chart-series-area-fill");
// Set the first series fill to translucent pale green
node.setStyle("-fx-fill: linear-gradient(#f2f2f2, #d4d4d4);"
+ " -fx-background-insets: 0 0 -1 0, 0, 1, 2;"
+ " -fx-background-radius: 3px, 3px, 2px, 1px;");
Node nodew = lineChart.lookup(".chart-series-area-line");
// Set the first series fill to translucent pale green
nodew.setStyle("-fx-stroke: #989898; -fx-stroke-width: 1px; ");
}
public static void main(String[] args)
{
launch(args);
}
}
This question already has an answer here:
How to change color of a single bar java fx
(1 answer)
Closed 9 years ago.
I want to create temperature chart where I can monitor in real time temperature.
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.chart.NumberAxis;
import javafx.scene.chart.StackedAreaChart;
import javafx.scene.chart.XYChart;
import javafx.stage.Stage;
public class MainApp extends Application
{
final NumberAxis xAxis = new NumberAxis(1, 31, 1);
final NumberAxis yAxis = new NumberAxis();
final StackedAreaChart<Number, Number> sac
= new StackedAreaChart<Number, Number>(xAxis, yAxis);
#Override
public void start(Stage stage)
{
setUserAgentStylesheet(STYLESHEET_CASPIAN);
stage.setTitle("Area Chart Sample");
sac.setTitle("Temperature Monitoring (in Degrees C)");
XYChart.Series<Number, Number> seriesApril
= new XYChart.Series<Number, Number>();
seriesApril.setName("April");
seriesApril.getData().add(new XYChart.Data(1, 4));
seriesApril.getData().add(new XYChart.Data(3, 10));
seriesApril.getData().add(new XYChart.Data(6, 15));
seriesApril.getData().add(new XYChart.Data(9, 8));
seriesApril.getData().add(new XYChart.Data(12, 5));
seriesApril.getData().add(new XYChart.Data(15, 18));
seriesApril.getData().add(new XYChart.Data(18, 15));
seriesApril.getData().add(new XYChart.Data(21, 13));
seriesApril.getData().add(new XYChart.Data(24, 19));
seriesApril.getData().add(new XYChart.Data(27, 21));
seriesApril.getData().add(new XYChart.Data(30, 21));
XYChart.Series<Number, Number> seriesMay
= new XYChart.Series<Number, Number>();
seriesMay.setName("May");
seriesMay.getData().add(new XYChart.Data(1, 20));
seriesMay.getData().add(new XYChart.Data(3, 15));
seriesMay.getData().add(new XYChart.Data(6, 13));
seriesMay.getData().add(new XYChart.Data(9, 12));
seriesMay.getData().add(new XYChart.Data(12, 14));
seriesMay.getData().add(new XYChart.Data(15, 18));
seriesMay.getData().add(new XYChart.Data(18, 25));
seriesMay.getData().add(new XYChart.Data(21, 25));
seriesMay.getData().add(new XYChart.Data(24, 23));
seriesMay.getData().add(new XYChart.Data(27, 26));
seriesMay.getData().add(new XYChart.Data(31, 26));
Scene scene = new Scene(sac, 800, 600);
sac.getData().addAll(seriesApril);
stage.setScene(scene);
stage.show();
}
public static void main(String[] args)
{
launch(args);
}
}
I want to change the color of of the chart for height temperature. For example I want to see temperature between 10 and 20 in green and temperature between 40 and 50 in red. Can you hep me to implement this?
This is only possible with CSS.
Add the following lines to your CSS and give your chart the id temperatureChart.
#temperatureChart .series0.chart-series-area-fill {
-fx-fill: linear-gradient(to top, #0984df, #00d8ff 20%, #fff000 60%, #ff0000) ;
}
The right percent values you must figure out yourself.
Hope this helps,
Kalasch
EDIT(in code method):
To do this in Code, you can do the following(it is suggested that you check if the lookup is null):
sac.lookup("#temperatureChart .series0.chart-series-area-fill")
.setStyle("-fx-fill: linear-gradient(to top, #0984df, #00d8ff 20%, #fff000 60%, #ff0000);");
It is not recomended to do so, but if there is no other way...
I found many examples how to zoom in charts but I'm looking for basic example in which the user can scroll with the mouse wheel.
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.chart.BarChart;
import javafx.scene.chart.CategoryAxis;
import javafx.scene.chart.NumberAxis;
import javafx.scene.chart.XYChart;
import javafx.stage.Stage;
public class BarChartSample extends Application {
final static String austria = "Austria";
final static String brazil = "Brazil";
final static String france = "France";
final static String italy = "Italy";
final static String usa = "USA";
#Override public void start(Stage stage) {
stage.setTitle("Bar Chart Sample");
final CategoryAxis xAxis = new CategoryAxis();
final NumberAxis yAxis = new NumberAxis();
final BarChart<String,Number> bc =
new BarChart<String,Number>(xAxis,yAxis);
bc.setTitle("Country Summary");
xAxis.setLabel("Country");
yAxis.setLabel("Value");
XYChart.Series series1 = new XYChart.Series();
series1.setName("2003");
series1.getData().add(new XYChart.Data(austria, 25601.34));
series1.getData().add(new XYChart.Data(brazil, 20148.82));
series1.getData().add(new XYChart.Data(france, 10000));
series1.getData().add(new XYChart.Data(italy, 35407.15));
series1.getData().add(new XYChart.Data(usa, 12000));
XYChart.Series series2 = new XYChart.Series();
series2.setName("2004");
series2.getData().add(new XYChart.Data(austria, 57401.85));
series2.getData().add(new XYChart.Data(brazil, 41941.19));
series2.getData().add(new XYChart.Data(france, 45263.37));
series2.getData().add(new XYChart.Data(italy, 117320.16));
series2.getData().add(new XYChart.Data(usa, 14845.27));
XYChart.Series series3 = new XYChart.Series();
series3.setName("2005");
series3.getData().add(new XYChart.Data(austria, 45000.65));
series3.getData().add(new XYChart.Data(brazil, 44835.76));
series3.getData().add(new XYChart.Data(france, 18722.18));
series3.getData().add(new XYChart.Data(italy, 17557.31));
series3.getData().add(new XYChart.Data(usa, 92633.68));
Scene scene = new Scene(bc,800,600);
bc.getData().addAll(series1, series2, series3);
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
Any help is welcome.
P.S I tested to insert the code into ScrollPane but I don't see any effect of using it.
ScrollPane s1 = new ScrollPane();
//s1.setPrefSize(620, 620);
s1.setHbarPolicy(ScrollPane.ScrollBarPolicy.AS_NEEDED); // Horizontal scroll bar
s1.setVbarPolicy(ScrollPane.ScrollBarPolicy.AS_NEEDED); // Vertical scroll bar
s1.setContent(bc);
Take a look at this answer.
I've got it working with this code:
final double SCALE_DELTA = 1.1;
bc.setOnScroll(new EventHandler<ScrollEvent>() {
public void handle(ScrollEvent event) {
event.consume();
if (event.getDeltaY() == 0) {
return;
}
double scaleFactor = (event.getDeltaY() > 0) ? SCALE_DELTA : 1 / SCALE_DELTA;
bc.setScaleX(bc.getScaleX() * scaleFactor);
bc.setScaleY(bc.getScaleY() * scaleFactor);
}
});
bc.setOnMousePressed(new EventHandler<MouseEvent>() {
public void handle(MouseEvent event) {
if (event.getClickCount() == 2) {
bc.setScaleX(1.0);
bc.setScaleY(1.0);
}
}
});
You should check out Jason Winnebeck's JFXUtils. He has developed a really nice library for chart zooming as well as panning (dragging the zoomed chart area like Google Maps).
You can also easily reset the chart. I wired it up to double click like you suggested.
You can specify the format of the axis labels on his custom StableTicksAxis (I display dates and times on my x axis).
Zooming works from a click-and-drag on the chart area or on the axis for zooming in to the entire span of either the x or y axis.
Mouse wheel zooming is baked right in.
He has a convenience method for super simple default setup, which wraps the chart in the components required to implement zooming.