forked from fair-acc/chart-fx
-
Notifications
You must be signed in to change notification settings - Fork 0
/
MetaDataRendererSample.java
271 lines (231 loc) · 10.1 KB
/
MetaDataRendererSample.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
package de.gsi.chart.samples;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.collections.ListChangeListener;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.CheckBox;
import javafx.scene.control.ComboBox;
import javafx.scene.control.Label;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import de.gsi.chart.XYChart;
import de.gsi.chart.axes.spi.DefaultNumericAxis;
import de.gsi.chart.plugins.DataPointTooltip;
import de.gsi.chart.plugins.EditAxis;
import de.gsi.chart.plugins.EditDataSet;
import de.gsi.chart.plugins.Panner;
import de.gsi.chart.plugins.ParameterMeasurements;
import de.gsi.chart.plugins.TableViewer;
import de.gsi.chart.plugins.XRangeIndicator;
import de.gsi.chart.plugins.Zoomer;
import de.gsi.chart.renderer.Renderer;
import de.gsi.chart.renderer.spi.ErrorDataSetRenderer;
import de.gsi.chart.renderer.spi.MetaDataRenderer;
import de.gsi.chart.ui.geometry.Side;
import de.gsi.dataset.DataSet;
import de.gsi.dataset.DataSetMetaData;
import de.gsi.dataset.testdata.spi.GaussFunction;
import de.gsi.dataset.testdata.spi.RandomWalkFunction;
import de.gsi.dataset.utils.ProcessingProfiler;
public class MetaDataRendererSample extends Application {
private static final Logger LOGGER = LoggerFactory.getLogger(MetaDataRendererSample.class);
private static final int N_SAMPLES1 = 10000; // default: 1000000
private static final int N_SAMPLES2 = 50; // default: 1000000
private static final int UPDATE_DELAY = 1000; // [ms]
private static final int UPDATE_PERIOD = 1000; // [ms]
private Timer timer;
protected int counter1 = -1;
protected int counter2 = -1;
public TimerTask getTask(final Renderer renderer1, final Renderer renderer2) {
return new TimerTask() {
int updateCount;
@Override
public void run() {
Platform.runLater(() -> {
// setAll in order to implicitly clear previous list of
// 'old' data sets
renderer1.getDatasets()
.setAll(new MetaInfoRandomWalkFunction("random walk", MetaDataRendererSample.N_SAMPLES1));
renderer2.getDatasets().setAll(new MetaInfoGausFunction("gaussy", MetaDataRendererSample.N_SAMPLES2,
MetaDataRendererSample.N_SAMPLES1));
if (updateCount % 100 == 0) {
LOGGER.atInfo().log("update iteration #" + updateCount);
}
updateCount++;
});
}
};
}
@Override
public void start(final Stage primaryStage) {
ProcessingProfiler.setVerboseOutputState(true);
ProcessingProfiler.setLoggerOutputState(true);
ProcessingProfiler.setDebugState(false);
final BorderPane root = new BorderPane();
final Scene scene = new Scene(root, 800, 600);
final DefaultNumericAxis xAxis1 = new DefaultNumericAxis("x axis", "samples");
final DefaultNumericAxis yAxis1 = new DefaultNumericAxis("y axis", "V");
yAxis1.setAnimated(false);
// padding is useful for showing error messages on top or bottom half
// of canvas
yAxis1.setAutoRangePadding(0.1);
final DefaultNumericAxis yAxis2 = new DefaultNumericAxis("y axis2", "A");
yAxis2.setSide(Side.RIGHT);
// padding is useful for showing error messages on top or bottom half
// of canvas
yAxis2.setAutoRangePadding(0.1);
yAxis2.setAnimated(false);
final DefaultNumericAxis yAxis3 = new DefaultNumericAxis("y axis3", "");
yAxis3.setSide(Side.RIGHT);
yAxis3.setAnimated(false);
final XYChart chart = new XYChart(xAxis1, yAxis1);
chart.setAnimated(false);
final ErrorDataSetRenderer renderer1 = new ErrorDataSetRenderer();
final ErrorDataSetRenderer renderer2 = new ErrorDataSetRenderer();
renderer2.getAxes().add(yAxis2);
final MetaDataRenderer metaDataRenderer = new MetaDataRenderer(chart);
// chart.rendererList().setAll(renderer1, renderer2, renderer3,
// metaDataRenderer);
chart.getRenderers().setAll(renderer1, renderer2);
// chart.rendererList().setAll(renderer1, metaDataRenderer);
// chart.rendererList().set(0, renderer1);
chart.getRenderers().add(metaDataRenderer);
getTask(renderer1, renderer2).run();
chart.getPlugins().add(new ParameterMeasurements());
final Zoomer zoom = new Zoomer();
chart.getPlugins().add(zoom);
final XRangeIndicator xRange = new XRangeIndicator(xAxis1, 50, 60);
chart.getPlugins().add(xRange);
chart.getPlugins().add(new EditAxis());
chart.getPlugins().add(new Panner());
chart.getPlugins().add(new TableViewer());
chart.getPlugins().add(new EditDataSet());
chart.getPlugins().add(new DataPointTooltip());
chart.getPlugins().add(new EditAxis());
chart.getAllDatasets().addListener((final ListChangeListener.Change<? extends DataSet> c) -> {
while (c.next()) {
if (c.getAddedSize() > 0) {
metaDataRenderer.getDatasets().addAll(c.getAddedSubList());
}
if (c.getRemovedSize() > 0) {
metaDataRenderer.getDatasets().removeAll(c.getRemoved());
}
}
});
metaDataRenderer.getDatasets().addAll(chart.getAllDatasets());
final Button newDataSet = new Button("new DataSet");
newDataSet.setOnAction(evt -> getTask(renderer1, renderer2).run());
final Button startTimer = new Button("timer");
startTimer.setOnAction(evt -> {
if (timer == null) {
timer = new Timer("sample-update-timer", true);
timer.scheduleAtFixedRate(getTask(renderer1, renderer2), MetaDataRendererSample.UPDATE_DELAY,
MetaDataRendererSample.UPDATE_PERIOD);
} else {
timer.cancel();
timer = null;
}
});
final ComboBox<Side> dataSideSelector = new ComboBox<>();
dataSideSelector.getItems().addAll(Side.values());
dataSideSelector.valueProperty().bindBidirectional(metaDataRenderer.infoBoxSideProperty());
final CheckBox drawOnTopOfCanvas = new CheckBox("Draw on Canvas?");
drawOnTopOfCanvas.selectedProperty().bindBidirectional(metaDataRenderer.drawOnCanvasProperty());
root.setTop(new HBox(newDataSet, startTimer, new Label("Meta-Data Info side: "), dataSideSelector,
drawOnTopOfCanvas));
long startTime = ProcessingProfiler.getTimeStamp();
ProcessingProfiler.getTimeDiff(startTime, "adding data to chart");
startTime = ProcessingProfiler.getTimeStamp();
root.setCenter(chart);
ProcessingProfiler.getTimeDiff(startTime, "adding chart into StackPane");
startTime = ProcessingProfiler.getTimeStamp();
primaryStage.setTitle(this.getClass().getSimpleName());
primaryStage.setScene(scene);
primaryStage.setOnCloseRequest(evt -> Platform.exit());
primaryStage.show();
ProcessingProfiler.getTimeDiff(startTime, "for showing");
}
/**
* @param args the command line arguments
*/
public static void main(final String[] args) {
Application.launch(args);
}
class MetaInfoGausFunction extends GaussFunction implements DataSetMetaData {
private static final long serialVersionUID = -397052291718132117L;
private int range;
public MetaInfoGausFunction(String name, int count, int range2) {
super(name, count);
counter2++;
range = range2;
this.setStyle("fillColor=green");
}
@Override
public double get(final int dimIndex, final int index) {
if (dimIndex == DataSet.DIM_X) {
return (double) index / ((double) this.getDataCount()) * range;
} else {
double x = get(DIM_X, index);
return 1000 * MetaInfoGausFunction.gauss(x, 0.5 * range, 1000);
}
}
@Override
public List<String> getErrorList() {
if (counter2 % 2 == 0) {
return Collections.singletonList(DataSetMetaData.TAG_OVERSHOOT);
}
return Collections.emptyList();
}
@Override
public List<String> getInfoList() {
if (counter1 % 4 == 0) {
return Collections.singletonList("info1");
}
return Collections.emptyList();
}
@Override
public List<String> getWarningList() {
if (counter1 % 2 == 0) {
return Collections.singletonList(DataSetMetaData.TAG_GAIN_RANGE);
}
return Collections.emptyList();
}
}
class MetaInfoRandomWalkFunction extends RandomWalkFunction implements DataSetMetaData {
private static final long serialVersionUID = -7647999890793017350L;
public MetaInfoRandomWalkFunction(String name, int count) {
super(name, count);
counter1++;
}
@Override
public List<String> getErrorList() {
if (counter1 % 3 == 0) {
return Arrays.asList(DataSetMetaData.TAG_OVERSHOOT, DataSetMetaData.TAG_UNDERSHOOT);
}
return Collections.emptyList();
}
@Override
public List<String> getInfoList() {
if (counter1 % 2 == 0) {
return Arrays.asList("info1", "info2");
}
return Collections.emptyList();
}
@Override
public List<String> getWarningList() {
if (counter1 % 2 == 0) {
return Collections.singletonList(DataSetMetaData.TAG_GAIN_RANGE);
}
return Collections.emptyList();
}
}
}