我试图实现类似于Windows中的网络使用图。我显示了最后30秒的数据,新值显示在右侧并向左移动。
我已经完成了所有工作,我不能让垂直网格线随数据移动。相反,主刻度线始终保持静止,而图表上的线正好移动。
即。在下面的图像中,我预计主刻度线将保持在5的tickUnit,并显示在55和60. 65处的标签将在屏幕外。
我的任何解决方案/解决方案都建立在已经存在的东西之上,而不是从头开始编写。是否可以通过子类化来定制行为?
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.collections.ListChangeListener;
import javafx.collections.ObservableList;
import javafx.scene.Scene;
import javafx.scene.chart.LineChart;
import javafx.scene.chart.NumberAxis;
import javafx.scene.chart.XYChart;
import javafx.scene.chart.XYChart.Data;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
public class StackOverflow25383566 extends Application {
@Override
public void start(Stage stage) throws Exception {
final NumberAxis xAxis = new NumberAxis();
xAxis.setAutoRanging(false);
xAxis.setForceZeroInRange(false);
xAxis.setTickUnit(5);
final NumberAxis yAxis = new NumberAxis(0, 15, 1);
yAxis.setAutoRanging(false);
final LineChart<Number, Number> chart = new LineChart<Number, Number>(
xAxis, yAxis);
chart.setAnimated(false);
chart.setCreateSymbols(false);
chart.setLegendVisible(false);
final XYChart.Series<Number, Number> series = new XYChart.Series<Number, Number>();
chart.getData().add(series);
series.getData().addListener(
new ListChangeListener<Data<Number, Number>>() {
@Override
public void onChanged(
ListChangeListener.Change<? extends Data<Number, Number>> arg0) {
ObservableList<Data<Number, Number>> data = series
.getData();
xAxis.setLowerBound(data.get(0).getXValue()
.doubleValue());
xAxis.setUpperBound(data.get(data.size() - 1)
.getXValue().doubleValue());
}
});
stage.setScene(new Scene(new BorderPane(chart), 800, 600));
stage.show();
final Runnable update = new Runnable() {
private int clock;
@Override
public void run() {
try {
ObservableList<Data<Number, Number>> data = series
.getData();
if (data.size() > 10) {
data.remove(0);
}
data.add(new XYChart.Data<Number, Number>(clock, clock % 13));
clock++;
} catch (Throwable e) {
// executors silently swallow exceptions
e.printStackTrace();
throw e;
}
}
};
Executors.newSingleThreadScheduledExecutor().scheduleAtFixedRate(
new Runnable() {
@Override
public void run() {
Platform.runLater(update);
}
}, 0, 500, TimeUnit.MILLISECONDS);
}
public static void main(String[] args) {
launch(args);
}
}
答案 0 :(得分:2)
我能够通过继承ValueAxis来解决这个问题,以便它返回始终是tickUnit倍数的tick标记。
这张照片显示的是我所追求的,即不一定以重要的嘀嗒声开始。
private class SpecialAxis extends ValueAxis<Number> {
private SimpleObjectProperty<Double> tickUnitProperty = new SimpleObjectProperty<Double>(
5d);
@Override
protected List<Number> calculateMinorTickMarks() {
List<Number> ticks = new ArrayList<Number>();
double tickUnit = tickUnitProperty.get() / getMinorTickCount();
double start = Math.floor(getLowerBound() / tickUnit) * tickUnit;
for (double value = start; value < getUpperBound(); value += tickUnit) {
ticks.add(value);
}
return ticks;
}
@Override
protected List<Number> calculateTickValues(double arg0, Object arg1) {
List<Number> ticks = new ArrayList<Number>();
double tickUnit = tickUnitProperty.get();
double start = Math.floor(getLowerBound() / tickUnit) * tickUnit;
for (double value = start; value < getUpperBound(); value += tickUnit) {
ticks.add(value);
}
return ticks;
}
@Override
protected Object getRange() {
// not sure how this is used??
return null;
}
@Override
protected String getTickMarkLabel(Number label) {
return label.toString();
}
@Override
protected void setRange(Object range, boolean arg1) {
// not sure how this is used??
}
public SimpleObjectProperty<Double> getTickUnitProperty() {
return tickUnitProperty;
}
public void setTickUnit(double tickUnit) {
tickUnitProperty.set(tickUnit);
}
}
答案 1 :(得分:0)
要获得网格移动的移动图表,您可以尝试使用LineChart<Number,Number>
。对于x轴,使用NumberAxis
,并设置正确的刻度标签格式器。由于您要删除数据,只需将x轴中的forceZeroInRange
选项设置为false,因为不会绘制较旧的时间值。必须使用autoRanging
on。
使用类似代码段:
NumberAxis xAxis = new NumberAxis();
xAxis.setAutoRanging(true);
xAxis.setForceZeroInRange(false);
xAxis.setTickLabelFormatter(new StringConverter<Number>(){
@Override
public String toString(Number t) {
return new SimpleDateFormat("HH:mm:ss").format(new Date(t.longValue()));
}
@Override
public Number fromString(String string) {
throw new UnsupportedOperationException("Not supported yet.");
}
});
NumberAxis yAxis = new NumberAxis();
LineChart<Number,Number> chart = new LineChart<>(xAxis,yAxis);
当左边的第一张主要门票消失时,你会看到垂直主要刻度从右向左移动。