如何在 ScalaFX 中更改 LineChart XAxis lower/upper 边界?
How to change LineChart XAxis lower/upper bounds in ScalaFX?
我有一个 ScalaFX LineChart
,它的 XAxis
是时间。数据是动态的,在 AnimationTimer
内更新。随着时间的推移,绘图向右移动,但绘图始终从 0 开始,因此可见域增加,压缩数据点。
这里是 Stage
:
new Stage {
title = plotTitle
scene = new Scene(600, 600) {
val series = new XYChart.Series[Number, Number]()
series.setName(s"Simple")
val xAxis = NumberAxis("Time (s)")
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)
xAxis.lowerBound.value = math.max(index - 100, 0) // this has no effect
xAxis.upperBound.value = math.max(index, 100) // this has no effect
index += 1
}
timer.start()
}
}
如何在 AnimationTimer
更新中更新 XAxis
的 lower/upper 边界?我尝试在动画更新期间设置 XAxis.lower/upperBound
值,但没有效果。我尝试过其他方法无济于事。我见过 JavaFX 解决方案,但我无法将其转换为 ScalaFX,因为没有一对一的类型映射。
您可以通过几种方式指定明确的下限,但都需要(据我所知)手动设置上限和刻度单位,并禁用自动调整范围:
- 通过在 X 轴 的
NumberAxis
构造函数中将下限和上限以及刻度单位指定为固定值。以这种方式创建的轴自动不会自动调整范围。
- 通过将 X 轴
NumberAxis
的 lowerBound
、upperBound
和 tickUnit
属性设置为固定值。这也需要设置X轴的autoRanging = false
.
- 通过将
DoubleProperty
实例绑定到 X 轴 的 lowerBound
、upperBound
和 tickUnit
属性 NumberAxis
。这允许通过更改关联的 属性 的值来动态调整边界和刻度单位。这也需要设置autoRanging = false
.
这是第一个选项的示例:
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()
}
}
在这个例子中,我结合了第二个和第三个选项,使用固定刻度单位的下限和上限属性。
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()
}
}
让我知道这是否适合您。
我有一个 ScalaFX LineChart
,它的 XAxis
是时间。数据是动态的,在 AnimationTimer
内更新。随着时间的推移,绘图向右移动,但绘图始终从 0 开始,因此可见域增加,压缩数据点。
这里是 Stage
:
new Stage {
title = plotTitle
scene = new Scene(600, 600) {
val series = new XYChart.Series[Number, Number]()
series.setName(s"Simple")
val xAxis = NumberAxis("Time (s)")
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)
xAxis.lowerBound.value = math.max(index - 100, 0) // this has no effect
xAxis.upperBound.value = math.max(index, 100) // this has no effect
index += 1
}
timer.start()
}
}
如何在 AnimationTimer
更新中更新 XAxis
的 lower/upper 边界?我尝试在动画更新期间设置 XAxis.lower/upperBound
值,但没有效果。我尝试过其他方法无济于事。我见过 JavaFX 解决方案,但我无法将其转换为 ScalaFX,因为没有一对一的类型映射。
您可以通过几种方式指定明确的下限,但都需要(据我所知)手动设置上限和刻度单位,并禁用自动调整范围:
- 通过在 X 轴 的
NumberAxis
构造函数中将下限和上限以及刻度单位指定为固定值。以这种方式创建的轴自动不会自动调整范围。 - 通过将 X 轴
NumberAxis
的lowerBound
、upperBound
和tickUnit
属性设置为固定值。这也需要设置X轴的autoRanging = false
. - 通过将
DoubleProperty
实例绑定到 X 轴 的lowerBound
、upperBound
和tickUnit
属性NumberAxis
。这允许通过更改关联的 属性 的值来动态调整边界和刻度单位。这也需要设置autoRanging = false
.
这是第一个选项的示例:
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()
}
}
在这个例子中,我结合了第二个和第三个选项,使用固定刻度单位的下限和上限属性。
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()
}
}
让我知道这是否适合您。