You can specify an explicit lower bound in a few ways, but all require (to the best of my knowledge) manually also setting an upper bound and tick unit, and disabling auto-ranging:
- By specifying the lower & upper bounds, and tick unit, as fixed values, in the
NumberAxis
constructor for the X-axis. Axes created in this way are automatically not auto-ranging.
- By setting the
lowerBound
, upperBound
and tickUnit
properties of the X-axis NumberAxis
to fixed values. This also requires setting the X-axis's autoRanging = false
.
- By binding
DoubleProperty
instances to the lowerBound
, upperBound
and tickUnit
properties of the X-axis NumberAxis
. This allows the bounds and tick unit to be dynamically adjusted, by changing the value of the associated property. This also requires setting autoRanging = false
.
Here's an example of the first option:
new Stage {
title = plotTitle
scene = new Scene(600, 600) {
val series = new XYChart.Series[Number, Number]()
series.setName(s"Simple")
// Specify an X-axis with fixed upper & lower bounds, and tick unit
// (separation of major tick values).
//
// Note: This is automatically not an auto-ranging axis.
val xAxis = NumberAxis("Time (s)", 115.0, 225.0, 25.0)
val yAxis = NumberAxis("Amplitude")
val lineChart = new LineChart(xAxis, yAxis)
lineChart.setAnimated(false)
lineChart.getData.add(series)
lineChart.setCreateSymbols(false)
root = lineChart
var index = 0
val timer = AnimationTimer { time =>
series.getData.add(XYChart.Data[Number, Number](index, math.cos(index)))
if (series.getData.size > 100) series.getData.remove(0, series.getData.size() - 100)
index += 1
}
timer.start()
}
}
In this example, I'm combining the second and third options to use properties for the lower & upper bounds, with a fixed tick unit.
new Stage {
title = plotTitle
scene = new Scene(600, 600) {
val series = new XYChart.Series[Number, Number]()
series.setName(s"Simple")
// Note: This axis is automatically auto-ranging.
val xAxis = NumberAxis("Time (s)")
val yAxis = NumberAxis("Amplitude")
// Disable auto-ranging of the xAxis.
xAxis.autoRanging = false
// Create a double property whose value will be used as the lower bound of the
// X-axis. If the value of this property is changed, the chart will update
// accordingly, automatically. Make this 0 initially.
val xLowBound = DoubleProperty(0.0)
// Bind this property to the lowerBound of the X-axis
xAxis.lowerBound <== xLowBound
// Repeat for the upper bound. 100, initially.
val xUpBound = DoubleProperty(100.0)
xAxis.upperBound <== xUpBound
// Set the tick unit to a fixed value.
xAxis.tickUnit = 25.0
val lineChart = new LineChart(xAxis, yAxis)
lineChart.setAnimated(false)
lineChart.getData.add(series)
lineChart.setCreateSymbols(false)
root = lineChart
var index = 0
val timer = AnimationTimer { time =>
series.getData.add(XYChart.Data[Number, Number](index, math.cos(index)))
if (series.getData.size > 100) series.getData.remove(0, series.getData.size() - 100)
// Dynamically update the lower & upper bounds.
xLowBound.value = math.max(index - 100, 0)
xUpBound.value = math.max(index, 100)
index += 1
}
timer.start()
}
}
Let me know if this does the trick for you.