Issue
I've create a small app which uses a live animated line chart to display the number of files in a certain folder every 2 seconds. All works well but the chart/yAxis keeps displaying double values after every update. The folder can contain between 0 and 30.000 files ...
href="https://i.stack.imgur.com/gvWTf.png" rel="nofollow noreferrer">
@FXML
public LineChart<String, Integer> myChart;
@FXML
public CategoryAxis xAxis;
@FXML
public NumberAxis yAxis;
...
yAxis.setMinorTickVisible(false);
yAxis.setTickMarkVisible(false);
yAxis.setTickUnit(1);
How do I make sure the y-Axis only contains/uses integer values ... ? The x,5 values/rows should never be used.
Solution
The tick unit is automatically set if autoranging is enabled (which it is by default). See the documentation.
So one way is to turn off autoranging, and set the range manually. This may need you to update the range when the data change, but the following demonstrates the idea:
public class ChartTest extends Application {
@Override
public void start(Stage stage) throws IOException {
CategoryAxis xAxis = new CategoryAxis();
NumberAxis yAxis = new NumberAxis();
yAxis.setTickUnit(1);
yAxis.setMinorTickVisible(false);
yAxis.setTickMarkVisible(false);
yAxis.setAutoRanging(false);
Random rng = new Random();
XYChart.Series<String, Integer> data = new XYChart.Series<>();
int max = Integer.MIN_VALUE;
for (String x : "ABCDEFGHIJKLMNOPQRSTUVWXYZ".split("")) {
int y = rng.nextInt(10);
if (y > max) max = y ;
data.getData().add(new XYChart.Data<>(x, y));
}
yAxis.setUpperBound(max + 1);
data.setName("Data");
LineChart<String, Integer> chart = new LineChart(xAxis, yAxis);
chart.getData().add(data);
Scene scene = new Scene(new BorderPane(chart), 600, 800);
stage.setTitle("Chart Test");
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch();
}
}
If you want to retain autoranging, you can use a tick label formatter that returns an empty string for non-integer values:
public class ChartTest extends Application {
@Override
public void start(Stage stage) throws IOException {
CategoryAxis xAxis = new CategoryAxis();
NumberAxis yAxis = new NumberAxis();
yAxis.setMinorTickVisible(false);
yAxis.setTickMarkVisible(false);
yAxis.setTickLabelFormatter(new StringConverter<Number>() {
@Override
public String toString(Number number) {
double d = number.doubleValue();
if (d == Math.rint(d)) {
return Integer.toString(number.intValue());
}
return "" ;
}
// Not used
@Override
public Number fromString(String s) {
return null;
}
});
Random rng = new Random();
XYChart.Series<String, Integer> data = new XYChart.Series<>();
for (String x : "ABCDEFGHIJKLMNOPQRSTUVWXYZ".split("")) {
int y = rng.nextInt(10);
data.getData().add(new XYChart.Data<>(x, y));
}
data.setName("Data");
LineChart<String, Integer> chart = new LineChart(xAxis, yAxis);
chart.getData().add(data);
Scene scene = new Scene(new BorderPane(chart), 600, 800);
stage.setTitle("Chart Test");
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch();
}
}
Answered By - James_D
Answer Checked By - Gilberto Lyons (JavaFixing Admin)