1 package org.simantics.district.network.ui.visualisations;
3 import java.util.ArrayList;
4 import java.util.Collection;
5 import java.util.HashMap;
8 import java.util.Map.Entry;
9 import java.util.Objects;
10 import java.util.Optional;
11 import java.util.function.Supplier;
12 import java.util.stream.Collectors;
13 import java.util.stream.Stream;
15 import org.eclipse.jface.dialogs.Dialog;
16 import org.eclipse.jface.dialogs.IInputValidator;
17 import org.eclipse.jface.dialogs.InputDialog;
18 import org.eclipse.jface.layout.GridDataFactory;
19 import org.eclipse.jface.layout.GridLayoutFactory;
20 import org.eclipse.swt.SWT;
21 import org.eclipse.swt.custom.ScrolledComposite;
22 import org.eclipse.swt.events.FocusAdapter;
23 import org.eclipse.swt.events.FocusEvent;
24 import org.eclipse.swt.events.KeyAdapter;
25 import org.eclipse.swt.events.KeyEvent;
26 import org.eclipse.swt.events.SelectionAdapter;
27 import org.eclipse.swt.events.SelectionEvent;
28 import org.eclipse.swt.layout.GridData;
29 import org.eclipse.swt.layout.GridLayout;
30 import org.eclipse.swt.widgets.Button;
31 import org.eclipse.swt.widgets.Combo;
32 import org.eclipse.swt.widgets.Composite;
33 import org.eclipse.swt.widgets.Display;
34 import org.eclipse.swt.widgets.Group;
35 import org.eclipse.swt.widgets.Label;
36 import org.eclipse.swt.widgets.Shell;
37 import org.eclipse.swt.widgets.Text;
38 import org.eclipse.swt.widgets.Widget;
39 import org.simantics.Simantics;
40 import org.simantics.db.ReadGraph;
41 import org.simantics.db.Resource;
42 import org.simantics.db.WriteGraph;
43 import org.simantics.db.common.NamedResource;
44 import org.simantics.db.common.request.UniqueRead;
45 import org.simantics.db.common.request.WriteRequest;
46 import org.simantics.db.exception.DatabaseException;
47 import org.simantics.db.layer0.util.RemoverUtil;
48 import org.simantics.db.procedure.Listener;
49 import org.simantics.district.network.profile.ActiveDynamicVisualisationsRequest;
50 import org.simantics.district.network.profile.DynamicVisualisationsRequest;
51 import org.simantics.district.network.visualisations.DynamicVisualisations;
52 import org.simantics.district.network.visualisations.DynamicVisualisationsContributions;
53 import org.simantics.district.network.visualisations.DynamicVisualisationsContributions.DynamicArrowObject;
54 import org.simantics.district.network.visualisations.DynamicVisualisationsContributions.DynamicColoringObject;
55 import org.simantics.district.network.visualisations.DynamicVisualisationsContributions.DynamicSizingObject;
56 import org.simantics.district.network.visualisations.model.ColorBarOptions;
57 import org.simantics.district.network.visualisations.model.ColorBarOptions.ColorBarsLocation;
58 import org.simantics.district.network.visualisations.model.ColorBarOptions.ColorBarsSize;
59 import org.simantics.district.network.visualisations.model.DynamicArrowContribution;
60 import org.simantics.district.network.visualisations.model.DynamicColorContribution;
61 import org.simantics.district.network.visualisations.model.DynamicColorMap;
62 import org.simantics.district.network.visualisations.model.DynamicSizeContribution;
63 import org.simantics.district.network.visualisations.model.DynamicSizeMap;
64 import org.simantics.district.network.visualisations.model.DynamicVisualisation;
65 import org.simantics.district.network.visualisations.model.SizeBarOptions;
66 import org.simantics.district.network.visualisations.model.SizeBarOptions.SizeBarsLocation;
67 import org.simantics.district.network.visualisations.model.SizeBarOptions.SizeBarsSize;
68 import org.simantics.utils.datastructures.Pair;
69 import org.simantics.utils.ui.dialogs.ShowError;
70 import org.slf4j.Logger;
71 import org.slf4j.LoggerFactory;
73 public class DynamicVisualisationsUI {
75 private static final Logger LOGGER = LoggerFactory.getLogger(DynamicVisualisationsUI.class);
77 private Resource parentResource;
78 private VisualisationListener listener;
79 private DynamicVisualisation visualisation;
81 private Button showSizeButton;
82 private Button sizeTicksButton;
83 private Button sizeGradientButton;
84 private Combo sizeLocationCombo;
85 private Combo sizeSizeCombo;
86 private Button showColorButton;
87 private Button colorTicksButton;
88 private Button colorGradientButton;
89 private Combo colorLocationCombo;
90 private Combo colorSizeCombo;
92 private Combo templateSelectionCombo;
94 private List<Supplier<Pair<String, DynamicColorContribution>>> colorSuppliers;
96 private Button removeVisualisationTemplateButton;
98 private Composite parent;
100 private Button disableUpdatesButton;
101 private Button resetVisualisationButton;
102 private Button hoveringVertexEnabledButton;
103 private Button hoveringEdgesEnabledButton;
104 private Button elevationServerEnabledButton;
105 private Button notInSimulationButton;
107 private List<Supplier<Pair<String, DynamicArrowContribution>>> edgeArrowSuppliers;
109 private Button saveVisualisationTemplateAsButton;
111 private Button hideEdgesButton;
112 private Button hidePointsButton;
113 private Button hideConsumersButton;
114 private Button hideProducersButton;
115 private Button hideValvesButton;
116 private Button hidePumpingStationsButton;
118 private Button networkBranchesStaticPropertiesButton;
119 private Button pointsStaticPropertiesButton;
120 private Button consumersStaticPropertiesButton;
122 private Button dynamicSymbolsEdgesButton;
123 private Button dynamicSymbolsProducersButton;
124 private Button dynamicSymbolsValvesButton;
125 private Button dynamicSymbolsPumpingStationsButton;
127 private Text intervalText;
129 public DynamicVisualisationsUI(Composite parent) {
130 this.parent = parent;
131 ScrolledComposite scrolledComposite = new ScrolledComposite(parent, SWT.V_SCROLL | SWT.H_SCROLL);
132 scrolledComposite.setLayout(new GridLayout(1, false));
133 scrolledComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
135 Composite firstContent = new Composite(scrolledComposite, SWT.NONE);
136 firstContent.setLayout(new GridLayout(1, false));
137 firstContent.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
139 defaultInitializeUI(firstContent);
141 scrolledComposite.setContent(firstContent);
142 scrolledComposite.setExpandHorizontal(true);
143 scrolledComposite.setExpandVertical(true);
144 scrolledComposite.setMinSize(firstContent.computeSize(SWT.DEFAULT, SWT.DEFAULT));
147 private void defaultInitializeUI(Composite parent) {
149 GridDataFactory.fillDefaults().grab(true, true).applyTo(parent);
150 GridLayoutFactory.fillDefaults().numColumns(1).margins(5, 5).applyTo(parent);
152 Composite selectionComposite = new Composite(parent, SWT.NONE);
153 GridDataFactory.fillDefaults().grab(true, false).applyTo(selectionComposite);
154 GridLayoutFactory.fillDefaults().numColumns(2).margins(5, 5).applyTo(selectionComposite);
156 Label templateNameLabel = new Label(selectionComposite, SWT.NONE);
157 templateNameLabel.setText("Visualisation template");
158 templateSelectionCombo = new Combo(selectionComposite, SWT.READ_ONLY);
159 GridDataFactory.fillDefaults().grab(true, false).applyTo(templateSelectionCombo);
160 templateSelectionCombo.addSelectionListener(new SelectionAdapter() {
163 public void widgetSelected(SelectionEvent e) {
164 String item = templateSelectionCombo.getItem(templateSelectionCombo.getSelectionIndex());
165 for (NamedResource template : visualisations) {
166 if (item.equals(template.getName())) {
167 if (parentResource != null) {
168 Resource res = parentResource;
169 Simantics.getSession().asyncRequest(new WriteRequest() {
172 public void perform(WriteGraph graph) throws DatabaseException {
173 Resource vf = DynamicVisualisations.getVisualisationFolder(graph, res);
174 DynamicVisualisations.setActiveVisualisation(graph, vf, template.getResource());
184 Composite intervalElementsComposite = new Composite(parent, SWT.NONE);
185 GridDataFactory.fillDefaults().grab(true, false).applyTo(intervalElementsComposite);
186 GridLayoutFactory.fillDefaults().numColumns(1).applyTo(intervalElementsComposite);
187 initializeIntervalElements(intervalElementsComposite);
189 Composite hoverElementsComposite = new Composite(parent, SWT.NONE);
190 GridDataFactory.fillDefaults().grab(true, false).applyTo(hoverElementsComposite);
191 GridLayoutFactory.fillDefaults().numColumns(1).applyTo(hoverElementsComposite);
192 initializeHoverElements(hoverElementsComposite);
194 Composite hideElementsComposite = new Composite(parent, SWT.NONE);
195 GridDataFactory.fillDefaults().grab(true, false).applyTo(hideElementsComposite);
196 GridLayoutFactory.fillDefaults().numColumns(1).applyTo(hideElementsComposite);
197 initializeHideElements(hideElementsComposite);
199 Composite staticPropertiesComposite = new Composite(parent, SWT.NONE);
200 GridDataFactory.fillDefaults().grab(true, false).applyTo(staticPropertiesComposite);
201 GridLayoutFactory.fillDefaults().numColumns(1).applyTo(staticPropertiesComposite);
202 initializeStaticProperties(staticPropertiesComposite);
204 Composite dynamicSymbolsComposite = new Composite(parent, SWT.NONE);
205 GridDataFactory.fillDefaults().grab(true, false).applyTo(dynamicSymbolsComposite);
206 GridLayoutFactory.fillDefaults().numColumns(1).applyTo(dynamicSymbolsComposite);
207 initializeDynamicSymbols(dynamicSymbolsComposite);
209 Composite coloringObjectsComposite = new Composite(parent, SWT.NONE);
210 GridDataFactory.fillDefaults().grab(true, false).applyTo(coloringObjectsComposite);
211 GridLayoutFactory.fillDefaults().numColumns(1).applyTo(coloringObjectsComposite);
212 initializeColoringObjects(coloringObjectsComposite);
214 Composite colorBarsComposite = new Composite(parent, SWT.NONE);
215 GridDataFactory.fillDefaults().grab(true, false).applyTo(colorBarsComposite);
216 GridLayoutFactory.fillDefaults().numColumns(1).applyTo(colorBarsComposite);
217 initializeColorBars(colorBarsComposite);
219 Composite objectSizesComposite = new Composite(parent, SWT.NONE);
220 GridDataFactory.fillDefaults().grab(true, false).applyTo(objectSizesComposite);
221 GridLayoutFactory.fillDefaults().numColumns(1).applyTo(objectSizesComposite);
222 initializeObjectSizes(objectSizesComposite);
224 Composite sizeBarsComposite = new Composite(parent, SWT.NONE);
225 GridDataFactory.fillDefaults().grab(true, false).applyTo(sizeBarsComposite);
226 GridLayoutFactory.fillDefaults().numColumns(1).applyTo(sizeBarsComposite);
227 initializeSizeBars(sizeBarsComposite);
229 Composite edgeArrowsComposite = new Composite(parent, SWT.NONE);
230 GridDataFactory.fillDefaults().grab(true, false).applyTo(edgeArrowsComposite);
231 GridLayoutFactory.fillDefaults().numColumns(1).applyTo(edgeArrowsComposite);
232 initializeEdgeArrows(edgeArrowsComposite);
234 Composite buttonBarsComposite = new Composite(parent, SWT.NONE);
235 GridDataFactory.fillDefaults().grab(true, false).applyTo(buttonBarsComposite);
236 GridLayoutFactory.fillDefaults().numColumns(3).applyTo(buttonBarsComposite);
238 saveVisualisationTemplateAsButton = new Button(buttonBarsComposite, SWT.NONE);
239 saveVisualisationTemplateAsButton.setText("Save as visualisation template");
240 saveVisualisationTemplateAsButton.addSelectionListener(new SelectionAdapter() {
243 public void widgetSelected(SelectionEvent e) {
244 showSaveVisualisationTemplateDialog(e.widget.getDisplay().getActiveShell());
248 removeVisualisationTemplateButton = new Button(buttonBarsComposite, SWT.NONE);
249 removeVisualisationTemplateButton.setText("Remove");
250 removeVisualisationTemplateButton.setEnabled(visualisation != null && visualisation.getVisualisationResource() != null);
251 removeVisualisationTemplateButton.addSelectionListener(new SelectionAdapter() {
254 public void widgetSelected(SelectionEvent e) {
255 removeVisualisationTemplate(visualisation.getName(), Optional.of(visualisation.getVisualisationResource()));
260 private void initializeIntervalElements(Composite parent) {
261 Group group = new Group(parent, SWT.NONE);
262 group.setText("Generic");
263 GridDataFactory.fillDefaults().grab(true, false).applyTo(group);
264 GridLayoutFactory.fillDefaults().numColumns(2).margins(5, 5).applyTo(group);
266 createIntervalElements(group);
269 private void createIntervalElements(Composite parent) {
271 Label label = new Label(parent, SWT.NONE);
272 label.setText("Interval (seconds)");
273 intervalText = new Text(parent, SWT.BORDER);
274 GridDataFactory.fillDefaults().grab(true, false).applyTo(intervalText);
275 addSelectionListener(intervalText);
277 disableUpdatesButton = new Button(parent, SWT.CHECK);
278 disableUpdatesButton.setText("Disable updates");
279 addSelectionListener(disableUpdatesButton);
281 resetVisualisationButton = new Button(parent, SWT.CHECK);
282 resetVisualisationButton.setText("Reset Visualisation");
283 addSelectionListener(resetVisualisationButton);
285 notInSimulationButton = new Button(parent, SWT.CHECK);
286 notInSimulationButton.setText("Not in Simulation");
287 addSelectionListener(notInSimulationButton);
289 elevationServerEnabledButton = new Button(parent, SWT.CHECK);
290 elevationServerEnabledButton.setText("Elevation Server Bounding Box");
291 addSelectionListener(elevationServerEnabledButton);
294 private void initializeHoverElements(Composite parent) {
295 Group group = new Group(parent, SWT.NONE);
296 group.setText("Hover");
297 GridDataFactory.fillDefaults().grab(true, false).applyTo(group);
298 GridLayoutFactory.fillDefaults().numColumns(2).margins(5, 5).applyTo(group);
300 createHoverElements(group);
303 private void createHoverElements(Composite parent) {
304 hoveringVertexEnabledButton = new Button(parent, SWT.CHECK);
305 hoveringVertexEnabledButton.setText("Vertex Key Variables on Hover");
306 addSelectionListener(hoveringVertexEnabledButton);
308 hoveringEdgesEnabledButton = new Button(parent, SWT.CHECK);
309 hoveringEdgesEnabledButton.setText("Edge Key Variables on Hover");
310 addSelectionListener(hoveringEdgesEnabledButton);
313 private void initializeHideElements(Composite parent) {
314 Group group = new Group(parent, SWT.NONE);
315 group.setText("Hide Elements");
316 GridDataFactory.fillDefaults().grab(true, false).applyTo(group);
317 GridLayoutFactory.fillDefaults().numColumns(8).margins(5, 5).applyTo(group);
319 createHideElements(group);
322 private void createHideElements(Composite parent) {
324 hideEdgesButton = new Button(parent, SWT.CHECK);
325 hideEdgesButton.setText("Edges");
326 addSelectionListener(hideEdgesButton);
328 hidePointsButton = new Button(parent, SWT.CHECK);
329 hidePointsButton.setText("Points");
330 addSelectionListener(hidePointsButton);
332 hideConsumersButton = new Button(parent, SWT.CHECK);
333 hideConsumersButton.setText("Consumers");
334 addSelectionListener(hideConsumersButton);
336 hideProducersButton = new Button(parent, SWT.CHECK);
337 hideProducersButton.setText("Producers");
338 addSelectionListener(hideProducersButton);
340 hideValvesButton = new Button(parent, SWT.CHECK);
341 hideValvesButton.setText("Valves");
342 addSelectionListener(hideValvesButton);
344 hidePumpingStationsButton = new Button(parent, SWT.CHECK);
345 hidePumpingStationsButton.setText("Pumping Stations");
346 addSelectionListener(hidePumpingStationsButton);
349 private void initializeStaticProperties(Composite parent) {
350 Group group = new Group(parent, SWT.NONE);
351 group.setText("Static Properties");
352 GridDataFactory.fillDefaults().grab(true, false).applyTo(group);
353 GridLayoutFactory.fillDefaults().numColumns(8).margins(5, 5).applyTo(group);
355 createStaticProperties(group);
358 private void createStaticProperties(Composite parent) {
360 networkBranchesStaticPropertiesButton = new Button(parent, SWT.CHECK);
361 networkBranchesStaticPropertiesButton.setText("Network Branches");
362 addSelectionListener(networkBranchesStaticPropertiesButton);
364 pointsStaticPropertiesButton = new Button(parent, SWT.CHECK);
365 pointsStaticPropertiesButton.setText("Points");
366 addSelectionListener(pointsStaticPropertiesButton);
368 consumersStaticPropertiesButton = new Button(parent, SWT.CHECK);
369 consumersStaticPropertiesButton.setText("Consumers");
370 addSelectionListener(consumersStaticPropertiesButton);
374 private void initializeDynamicSymbols(Composite parent) {
375 Group group = new Group(parent, SWT.NONE);
376 group.setText("Dynamic Symbols");
377 GridDataFactory.fillDefaults().grab(true, false).applyTo(group);
378 GridLayoutFactory.fillDefaults().numColumns(8).margins(5, 5).applyTo(group);
380 createDynamicSymbols(group);
383 private void createDynamicSymbols(Composite parent) {
385 dynamicSymbolsEdgesButton = new Button(parent, SWT.CHECK);
386 dynamicSymbolsEdgesButton.setText("Shutoff Valves in Pipes");
387 addSelectionListener(dynamicSymbolsEdgesButton);
389 dynamicSymbolsProducersButton = new Button(parent, SWT.CHECK);
390 dynamicSymbolsProducersButton.setText("Producers");
391 addSelectionListener(dynamicSymbolsProducersButton);
393 dynamicSymbolsValvesButton = new Button(parent, SWT.CHECK);
394 dynamicSymbolsValvesButton.setText("Valves");
395 addSelectionListener(dynamicSymbolsValvesButton);
397 dynamicSymbolsPumpingStationsButton = new Button(parent, SWT.CHECK);
398 dynamicSymbolsPumpingStationsButton.setText("Pumping Stations");
399 addSelectionListener(dynamicSymbolsPumpingStationsButton);
402 private void initializeEdgeArrows(Composite parent) {
403 Group group = new Group(parent, SWT.NONE);
404 group.setText("Edge Arrows");
405 GridDataFactory.fillDefaults().grab(true, false).applyTo(group);
406 GridLayoutFactory.fillDefaults().numColumns(6).margins(5, 5).applyTo(group);
408 createEdgeArrowsHeaderRow(group);
410 edgeArrowSuppliers = new ArrayList<>();
413 Collection<DynamicArrowObject> result = Simantics.getSession().syncRequest(new UniqueRead<Collection<DynamicArrowObject>>() {
416 public Collection<DynamicArrowObject> perform(ReadGraph graph) throws DatabaseException {
417 return DynamicVisualisationsContributions.dynamicEdgeArrowObjects(graph);
421 for (DynamicArrowObject object : result) {
422 edgeArrowSuppliers.add(createEdgeArrowRow(group, object));
424 } catch (DatabaseException e) {
425 LOGGER.error("Could not create coloring objecst", e);
431 private void createEdgeArrowsHeaderRow(Composite parent) {
433 Label label = new Label(parent, SWT.NONE);
434 label.setText("Label");
435 GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
437 label = new Label(parent, SWT.NONE);
438 label.setText("Used");
439 GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
441 label = new Label(parent, SWT.NONE);
442 label.setText("Variable");
443 GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
445 label = new Label(parent, SWT.NONE);
446 label.setText("Gain");
447 GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
449 label = new Label(parent, SWT.NONE);
450 label.setText("Bias");
451 GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
453 label = new Label(parent, SWT.NONE);
454 label.setText("Default");
455 GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
458 private Supplier<Pair<String, DynamicArrowContribution>> createEdgeArrowRow(Composite parent, DynamicArrowObject object) {
460 Map<String, DynamicArrowContribution> arrowContributions = object.getArrowContributions();
461 if (arrowContributions.isEmpty()) {
462 // ok, no point in showing empty combo boxes
466 Label label = new Label(parent, SWT.NONE);
467 label.setText(object.getArrowObject().getName());
468 GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(label);
470 Button usedButton = new Button(parent, SWT.CHECK);
471 GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(usedButton);
472 addSelectionListener(usedButton);
474 Combo variableCombo = new Combo(parent, SWT.READ_ONLY);
475 variableCombo.setItems(arrowContributions.keySet().toArray(new String[arrowContributions.size()]));
476 GridDataFactory.fillDefaults().grab(true, false).hint(100, SWT.DEFAULT).align(SWT.CENTER, SWT.CENTER).applyTo(variableCombo);
478 Text gainText = new Text(parent, SWT.BORDER);
479 GridDataFactory.fillDefaults().grab(true, false).hint(100, SWT.DEFAULT).align(SWT.CENTER, SWT.CENTER).applyTo(gainText);
480 addSelectionListener(gainText);
482 Text biasText = new Text(parent, SWT.BORDER);
483 GridDataFactory.fillDefaults().grab(true, false).hint(100, SWT.DEFAULT).align(SWT.CENTER, SWT.CENTER).applyTo(biasText);
484 addSelectionListener(biasText);
486 Button defaultButton = new Button(parent, SWT.CHECK);
487 GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(defaultButton);
488 defaultButton.addSelectionListener(new SelectionAdapter() {
491 public void widgetSelected(SelectionEvent e) {
492 int index = variableCombo.getSelectionIndex();
494 String key = variableCombo.getItem(index);
495 DynamicArrowContribution cont = arrowContributions.get(key);
497 gainText.setText(Double.toString(cont.getDefaultGain()));
498 gainText.setEnabled(!defaultButton.getSelection());
499 biasText.setText(Double.toString(cont.getDefaultBias()));
500 biasText.setEnabled(!defaultButton.getSelection());
505 addSelectionListener(defaultButton);
507 variableCombo.addSelectionListener(new SelectionAdapter() {
510 public void widgetSelected(SelectionEvent e) {
511 // handle update for others
512 String key = variableCombo.getItem(variableCombo.getSelectionIndex());
513 DynamicArrowContribution cont = arrowContributions.get(key);
515 if (gainText.getText().isEmpty()) {
516 gainText.setText(Double.toString(cont.getDefaultGain()));
518 if (biasText.getText().isEmpty()) {
519 biasText.setText(Double.toString(cont.getDefaultBias()));
522 defaultButton.setSelection(true);
525 addSelectionListener(variableCombo);
527 arrowRows.put(object.getArrowObject().getName(), new ArrowObjectRow(label, usedButton, variableCombo, gainText, biasText, defaultButton));
529 return new Supplier<Pair<String, DynamicArrowContribution>>() {
532 public Pair<String, DynamicArrowContribution> get() {
533 int selectionIndex = variableCombo.getSelectionIndex();
534 if (selectionIndex >= 0) {
535 String key = variableCombo.getItem(selectionIndex);
536 DynamicArrowContribution cont = arrowContributions.get(key);
538 String label = variableCombo.getItem(variableCombo.getSelectionIndex());
540 double gain = cont.getDefaultGain();
541 String gainS = gainText.getText();
542 if (gainS != null && !gainS.isEmpty()) {
543 gain = Double.parseDouble(gainS);
545 double bias = cont.getDefaultBias();
546 String biasS = biasText.getText();
547 if (biasS != null && !biasS.isEmpty()) {
548 bias = Double.parseDouble(biasText.getText());
551 DynamicArrowContribution dsc = new DynamicArrowContribution(label, cont.getModuleName(), cont.getAttributeName(), gain, bias);
552 dsc.setUsed(usedButton.getSelection());
553 dsc.setUseDefault(defaultButton.getSelection());
555 return Pair.make(object.getArrowObject().getName(), dsc);
563 protected void removeVisualisationTemplate(String name, Optional<Resource> of) {
564 if (of.isPresent()) {
565 Resource visualisation = of.get();
566 Simantics.getSession().asyncRequest(new WriteRequest() {
569 public void perform(WriteGraph graph) throws DatabaseException {
570 RemoverUtil.remove(graph, visualisation);
576 private void showSaveVisualisationTemplateDialog(Shell shell) {
578 InputDialog dialog = new InputDialog(shell, "Save visualisation template", "Give template a name", "", new IInputValidator() {
581 public String isValid(String newText) {
582 if (newText == null || newText.isEmpty())
583 return "Name cannot be empty";
588 if (dialog.open() == Dialog.OK) {
589 String name = dialog.getValue();
591 persistVisualisationTemplate(name, Optional.empty());
592 } catch (Exception e) {
593 LOGGER.error("Could not persist visualisation template", e);
594 ShowError.showError("Could not persist visualisation template", e.getMessage(), e);
599 private void persistCurrentVisualisationTemplateIfAvailable() {
600 if (visualisation != null) {
602 persistVisualisationTemplate(visualisation.getName(), Optional.of(visualisation.getVisualisationResource()));
603 } catch (Exception e1) {
604 LOGGER.error("Could not persist visualisation template", e1);
605 ShowError.showError("Could not persist visualisation template", e1.getMessage(), e1);
608 LOGGER.info("No current visualisation template selected for saving");
612 private void persistVisualisationTemplate(String templateName, Optional<Resource> existing) throws Exception {
614 List<Pair<String, DynamicColorContribution>> colorCollect = colorSuppliers.stream().filter(Objects::nonNull).map(s -> s.get()).filter(Objects::nonNull).collect(Collectors.toList());
616 String colorLocation = colorLocationCombo.getItem(colorLocationCombo.getSelectionIndex());
617 String colorSize = colorSizeCombo.getItem(colorSizeCombo.getSelectionIndex());
619 ColorBarOptions colorBarOptions = new ColorBarOptions()
620 .showColorBars(showColorButton.getSelection())
621 .showColorBarsTicks(colorTicksButton.getSelection())
622 .useGradients(colorGradientButton.getSelection())
623 .withLocation(ColorBarsLocation.valueOf(colorLocation))
624 .withSize(ColorBarsSize.valueOf(colorSize));
626 List<Pair<String, DynamicSizeContribution>> sizeCollect = sizeSuppliers.stream().filter(Objects::nonNull).map(s -> s.get()).filter(Objects::nonNull).collect(Collectors.toList());
628 String sizeLocation = sizeLocationCombo.getItem(sizeLocationCombo.getSelectionIndex());
629 String sizeSize = sizeSizeCombo.getItem(sizeSizeCombo.getSelectionIndex());
631 final SizeBarOptions sizeBarOptions = new SizeBarOptions()
632 .showSizeBars(showSizeButton.getSelection())
633 .showSizeBarsTicks(sizeTicksButton.getSelection())
634 .useGradients(sizeGradientButton.getSelection())
635 .withLocation(SizeBarsLocation.valueOf(sizeLocation))
636 .withSize(SizeBarsSize.valueOf(sizeSize));
638 List<Pair<String, DynamicArrowContribution>> edgeArrowCollect = edgeArrowSuppliers.stream().filter(Objects::nonNull).map(s -> s.get()).filter(Objects::nonNull).collect(Collectors.toList());
640 boolean hideEdges = hideEdgesButton.getSelection();
641 boolean hidePoints = hidePointsButton.getSelection();
642 boolean hideConsumers = hideConsumersButton.getSelection();
643 boolean hideProducers = hideProducersButton.getSelection();
644 boolean hideValves = hideValvesButton.getSelection();
645 boolean hidePumpingStations = hidePumpingStationsButton.getSelection();
647 boolean networkBranchesStaticProperties = networkBranchesStaticPropertiesButton.getSelection();
648 boolean pointsStaticProperties = pointsStaticPropertiesButton.getSelection();
649 boolean consumersStaticProperties = consumersStaticPropertiesButton.getSelection();
651 boolean dynamicSymbolsEdges = dynamicSymbolsEdgesButton.getSelection();
652 boolean dynamicSymbolsProducers = dynamicSymbolsProducersButton.getSelection();
653 boolean dynamicSymbolsValves = dynamicSymbolsValvesButton.getSelection();
654 boolean dynamicSymbolsPumpingStations = dynamicSymbolsPumpingStationsButton.getSelection();
656 boolean disabled = disableUpdatesButton.getSelection();
657 boolean resetVisualisation = resetVisualisationButton.getSelection();
660 // inteval is in milliseconds but shown as seconds
662 interval = (long)(Double.parseDouble(intervalText.getText()) * 1000);
663 } catch (NumberFormatException e) {
667 final long finalInterval = interval;
669 boolean hoverVertex = hoveringVertexEnabledButton.getSelection();
670 boolean hoverEdges = hoveringEdgesEnabledButton.getSelection();
672 boolean elevationServerBoundingBox = elevationServerEnabledButton.getSelection();
673 boolean notInSimulation = notInSimulationButton.getSelection();
675 Simantics.getSession().asyncRequest(new WriteRequest() {
678 public void perform(WriteGraph graph) throws DatabaseException {
680 if (existing.isPresent()) {
681 exist = existing.get();
683 exist = DynamicVisualisations.createVisualisation(graph, parentResource, templateName);
685 DynamicVisualisations.setIntervalAndDisabled(graph, exist, finalInterval, disabled, resetVisualisation);
686 DynamicVisualisations.setColorContributions(graph, exist, colorCollect);
687 DynamicVisualisations.setColorBarOptions(graph, exist, colorBarOptions);
688 DynamicVisualisations.setSizeContributions(graph, exist, sizeCollect);
689 DynamicVisualisations.setSizeBarOptions(graph, exist, sizeBarOptions);
690 DynamicVisualisations.setEdgeArrowContributions(graph, exist, edgeArrowCollect);
691 DynamicVisualisations.setHideElements(graph, exist,
700 DynamicVisualisations.setStaticProperties(graph, exist,
701 networkBranchesStaticProperties,
702 pointsStaticProperties,
703 consumersStaticProperties
706 DynamicVisualisations.setDynamicSymbols(graph, exist,
708 dynamicSymbolsProducers,
709 dynamicSymbolsValves,
710 dynamicSymbolsPumpingStations
712 DynamicVisualisations.setKeyVariablesHover(graph, exist, hoverVertex, hoverEdges);
714 DynamicVisualisations.setElevationServerBoundingBox(graph, exist, elevationServerBoundingBox);
715 DynamicVisualisations.setNotInSimulation(graph, exist, notInSimulation);
720 private void initializeColoringObjects(Composite parent) {
721 Group group = new Group(parent, SWT.NONE);
722 group.setText("Coloring Objects");
723 GridDataFactory.fillDefaults().grab(true, false).applyTo(group);
724 GridLayoutFactory.fillDefaults().numColumns(8).margins(5, 5).applyTo(group);
727 createColoringObjectHeaderRow(group);
729 colorSuppliers = new ArrayList<>();
732 Pair<Collection<DynamicColoringObject>, Map<String, DynamicColorMap>> result = Simantics.getSession().syncRequest(new UniqueRead<Pair<Collection<DynamicColoringObject>, Map<String, DynamicColorMap>>>() {
735 public Pair<Collection<DynamicColoringObject>, Map<String, DynamicColorMap>> perform(ReadGraph graph) throws DatabaseException {
736 Map<String, DynamicColorMap> dynamicColorMaps = DynamicVisualisationsContributions.dynamicColorMaps(graph);
737 return Pair.make(DynamicVisualisationsContributions.dynamicColoringObjects(graph), dynamicColorMaps);
741 for (DynamicColoringObject object : result.first) {
742 colorSuppliers.add(createColoringObjectRow(group, object, result.second));
745 } catch (DatabaseException e) {
746 LOGGER.error("Could not create coloring objecst", e);
751 private void createColoringObjectHeaderRow(Composite parent) {
753 Label label = new Label(parent, SWT.NONE);
754 label.setText("Label");
755 GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
757 label = new Label(parent, SWT.NONE);
758 label.setText("Used");
759 GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
761 label = new Label(parent, SWT.NONE);
762 label.setText("Variable");
763 GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
765 label = new Label(parent, SWT.NONE);
766 label.setText("Min");
767 GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
769 label = new Label(parent, SWT.NONE);
770 label.setText("Max");
771 GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
773 label = new Label(parent, SWT.NONE);
774 label.setText("Unit");
775 GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
777 label = new Label(parent, SWT.NONE);
778 label.setText("ColorMap");
779 GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
781 label = new Label(parent, SWT.NONE);
782 label.setText("Default");
783 GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
786 private Map<String, ColoringObjectRow> coloringRows = new HashMap<>();
787 private Map<String, SizingObjectRow> sizingRows = new HashMap<>();
788 private Map<String, ArrowObjectRow> arrowRows = new HashMap<>();
790 private VisualisationsListener visualisationsListener;
792 private Collection<NamedResource> visualisations;
794 private List<Supplier<Pair<String, DynamicSizeContribution>>> sizeSuppliers;
796 private static class ColoringObjectRow {
798 private final Label label;
799 private final Button usedButton;
800 private final Combo variableCombo;
801 private final Text minText;
802 private final Text maxText;
803 private final Text unit;
804 private final Combo colorMapCombo;
805 private final Button defaultButton;
807 public ColoringObjectRow(Label label, Button usedButton, Combo variableCombo, Text minText, Text maxText, Text unit,
808 Combo colorMapCombo, Button defaultButton) {
811 this.usedButton = usedButton;
812 this.variableCombo = variableCombo;
813 this.minText = minText;
814 this.maxText = maxText;
816 this.colorMapCombo = colorMapCombo;
817 this.defaultButton = defaultButton;
820 public void update(DynamicColorContribution colorContribution) {
821 String[] items = variableCombo.getItems();
822 for (int i = 0; i < items.length; i++) {
823 if (colorContribution.getLabel().equals(items[i])) {
824 variableCombo.select(i);
828 minText.setText(Double.toString(colorContribution.getDefaultMin()));
829 maxText.setText(Double.toString(colorContribution.getDefaultMax()));
830 unit.setText(colorContribution.getUnit());
832 String[] colorItems = colorMapCombo.getItems();
833 for (int i = 0; i < colorItems.length; i++) {
835 if (colorContribution.getDefaultColorMap().getLabel().equals(colorItems[i])) {
836 colorMapCombo.select(i);
840 usedButton.setSelection(colorContribution.isUsed());
841 defaultButton.setSelection(colorContribution.isUseDefault());
843 minText.setEnabled(!colorContribution.isUseDefault());
844 maxText.setEnabled(!colorContribution.isUseDefault());
845 colorMapCombo.setEnabled(!colorContribution.isUseDefault());
849 private static class SizingObjectRow {
851 private final Label label;
852 private final Button usedButton;
853 private final Combo variableCombo;
854 private final Text minText;
855 private final Text maxText;
856 private final Label unit;
857 private final Combo sizeMapCombo;
858 private final Button defaultButton;
860 public SizingObjectRow(Label label, Button usedButton, Combo variableCombo, Text minText, Text maxText, Label unit,
861 Combo sizeMapCombo, Button defaultButton) {
864 this.usedButton = usedButton;
865 this.variableCombo = variableCombo;
866 this.minText = minText;
867 this.maxText = maxText;
869 this.sizeMapCombo = sizeMapCombo;
870 this.defaultButton = defaultButton;
873 public void update(DynamicSizeContribution sizeContribution) {
874 String[] items = variableCombo.getItems();
875 for (int i = 0; i < items.length; i++) {
876 if (sizeContribution.getLabel().equals(items[i])) {
877 variableCombo.select(i);
881 minText.setText(Double.toString(sizeContribution.getDefaultMin()));
882 maxText.setText(Double.toString(sizeContribution.getDefaultMax()));
883 unit.setText(sizeContribution.getUnit());
885 String[] sizeItems = sizeMapCombo.getItems();
886 for (int i = 0; i < sizeItems.length; i++) {
887 if (sizeContribution.getDefaultSizeMap().getLabel().equals(sizeItems[i])) {
888 sizeMapCombo.select(i);
892 usedButton.setSelection(sizeContribution.isUsed());
893 defaultButton.setSelection(sizeContribution.isUseDefault());
895 minText.setEnabled(!sizeContribution.isUseDefault());
896 maxText.setEnabled(!sizeContribution.isUseDefault());
897 sizeMapCombo.setEnabled(!sizeContribution.isUseDefault());
901 private static class ArrowObjectRow {
903 private final Label label;
904 private final Button usedButton;
905 private final Combo variableCombo;
906 private final Text gainText;
907 private final Text biasText;
908 private final Button defaultButton;
910 public ArrowObjectRow(Label label, Button usedButton, Combo variableCombo, Text gainText, Text biasText, Button defaultButton) {
912 this.usedButton = usedButton;
913 this.variableCombo = variableCombo;
914 this.gainText = gainText;
915 this.biasText = biasText;
916 this.defaultButton = defaultButton;
919 public void update(DynamicColorContribution colorContribution) {
920 String[] items = variableCombo.getItems();
921 for (int i = 0; i < items.length; i++) {
922 if (colorContribution.getLabel().equals(items[i])) {
923 variableCombo.select(i);
927 gainText.setText(Double.toString(colorContribution.getDefaultMin()));
928 biasText.setText(Double.toString(colorContribution.getDefaultMax()));
930 usedButton.setSelection(colorContribution.isUsed());
931 defaultButton.setSelection(colorContribution.isUseDefault());
933 gainText.setEnabled(!colorContribution.isUseDefault());
934 biasText.setEnabled(!colorContribution.isUseDefault());
938 private Supplier<Pair<String, DynamicColorContribution>> createColoringObjectRow(Composite parent, DynamicColoringObject object, Map<String, DynamicColorMap> colorMaps) {
939 Label label = new Label(parent, SWT.NONE);
940 label.setText(object.getColoringObject().getName());
941 GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(label);
943 Map<String, DynamicColorContribution> colorContributions = object.getColorContributions();
945 Button usedButton = new Button(parent, SWT.CHECK);
946 GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(usedButton);
947 addSelectionListener(usedButton);
949 Combo variableCombo = new Combo(parent, SWT.READ_ONLY);
950 variableCombo.setItems(colorContributions.keySet().toArray(new String[colorContributions.size()]));
952 GridDataFactory.fillDefaults().grab(true, false).hint(100, SWT.DEFAULT).align(SWT.CENTER, SWT.CENTER).applyTo(variableCombo);
954 Text minText = new Text(parent, SWT.BORDER);
955 GridDataFactory.fillDefaults().grab(true, false).hint(100, SWT.DEFAULT).align(SWT.CENTER, SWT.CENTER).applyTo(minText);
956 addSelectionListener(minText);
958 Text maxText = new Text(parent, SWT.BORDER);
959 GridDataFactory.fillDefaults().grab(true, false).hint(100, SWT.DEFAULT).align(SWT.CENTER, SWT.CENTER).applyTo(maxText);
960 addSelectionListener(maxText);
962 Text unit = new Text(parent, SWT.READ_ONLY);
963 GridDataFactory.fillDefaults().grab(true, false).hint(30, SWT.DEFAULT).align(SWT.CENTER, SWT.CENTER).applyTo(unit);
965 Combo colorMapCombo = new Combo(parent, SWT.READ_ONLY);
966 GridDataFactory.fillDefaults().grab(true, false).hint(100, SWT.DEFAULT).align(SWT.CENTER, SWT.CENTER).applyTo(colorMapCombo);
967 colorMapCombo.setItems(colorMaps.keySet().toArray(new String[colorMaps.keySet().size()]));
968 addSelectionListener(colorMapCombo);
970 Button defaultButton = new Button(parent, SWT.CHECK);
971 GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(defaultButton);
972 defaultButton.addSelectionListener(new SelectionAdapter() {
975 public void widgetSelected(SelectionEvent e) {
976 int index = variableCombo.getSelectionIndex();
978 String key = variableCombo.getItem(index);
979 DynamicColorContribution cont = colorContributions.get(key);
981 minText.setText(Double.toString(cont.getDefaultMin()));
982 minText.setEnabled(!defaultButton.getSelection());
983 maxText.setText(Double.toString(cont.getDefaultMax()));
984 maxText.setEnabled(!defaultButton.getSelection());
985 unit.setText(cont.getUnit());
987 String[] items = colorMapCombo.getItems();
988 for (int i = 0; i < items.length; i++) {
989 String item = items[i];
990 if (item.equals(cont.getDefaultColorMap().getLabel())) {
991 colorMapCombo.select(i);
995 colorMapCombo.setEnabled(!defaultButton.getSelection());
999 addSelectionListener(defaultButton);
1001 variableCombo.addSelectionListener(new SelectionAdapter() {
1004 public void widgetSelected(SelectionEvent e) {
1005 // handle update for others
1006 int index = variableCombo.getSelectionIndex();
1008 String key = variableCombo.getItem(index);
1009 DynamicColorContribution cont = colorContributions.get(key);
1011 if (minText.getText().isEmpty()) {
1012 minText.setText(Double.toString(cont.getDefaultMin()));
1014 if (maxText.getText().isEmpty()) {
1015 maxText.setText(Double.toString(cont.getDefaultMax()));
1017 unit.setText(cont.getUnit());
1019 String[] items = colorMapCombo.getItems();
1020 for (int i = 0; i < items.length; i++) {
1021 String item = items[i];
1022 if (item.equals(cont.getDefaultColorMap().getLabel())) {
1023 colorMapCombo.select(i);
1028 defaultButton.setSelection(true);
1032 addSelectionListener(variableCombo);
1034 coloringRows.put(object.getColoringObject().getName(), new ColoringObjectRow(label, usedButton, variableCombo, minText, maxText, unit, colorMapCombo, defaultButton));
1036 return new Supplier<Pair<String, DynamicColorContribution>>() {
1039 public Pair<String, DynamicColorContribution> get() {
1040 int selectionIndex = variableCombo.getSelectionIndex();
1041 if (selectionIndex >= 0) {
1042 String key = variableCombo.getItem(selectionIndex);
1043 DynamicColorContribution cont = colorContributions.get(key);
1046 String label = variableCombo.getItem(variableCombo.getSelectionIndex());
1047 DynamicColorContribution dcc;
1048 if (colorMapCombo.getSelectionIndex() > -1) {
1049 String colorMap = colorMapCombo.getItem(colorMapCombo.getSelectionIndex());
1050 DynamicColorMap dColorMap = colorMaps.get(colorMap);
1051 dcc = new DynamicColorContribution(label, cont.getModuleName(), cont.getAttributeName(), unit.getText(), cont.getVariableGain(), cont.getVariableBias(), dColorMap, Double.parseDouble(minText.getText()), Double.parseDouble(maxText.getText()));
1053 dcc = colorContributions.get(label);
1055 dcc.setUsed(usedButton.getSelection());
1056 dcc.setUseDefault(defaultButton.getSelection());
1058 return Pair.make(object.getColoringObject().getName(), dcc);
1066 private void createSizingObjectHeaderRow(Composite parent) {
1068 Label label = new Label(parent, SWT.NONE);
1069 label.setText("Label");
1070 GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
1072 label = new Label(parent, SWT.NONE);
1073 label.setText("Used");
1074 GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
1076 label = new Label(parent, SWT.NONE);
1077 label.setText("Variable");
1078 GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
1080 label = new Label(parent, SWT.NONE);
1081 label.setText("Min");
1082 GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
1084 label = new Label(parent, SWT.NONE);
1085 label.setText("Max");
1086 GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
1088 label = new Label(parent, SWT.NONE);
1089 label.setText("Unit");
1090 GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
1092 label = new Label(parent, SWT.NONE);
1093 label.setText("SizeMap");
1094 GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
1096 label = new Label(parent, SWT.NONE);
1097 label.setText("Default");
1098 GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
1101 private Supplier<Pair<String, DynamicSizeContribution>> createSizingObjectRow(Composite parent, DynamicSizingObject object, Map<String, DynamicSizeMap> sizeMaps) {
1102 Label label = new Label(parent, SWT.NONE);
1103 label.setText(object.getSizingObject().getName());
1104 GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(label);
1106 Map<String, DynamicSizeContribution> sizeContributions = object.getSizeContributions();
1108 Button usedButton = new Button(parent, SWT.CHECK);
1109 GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(usedButton);
1110 addSelectionListener(usedButton);
1112 Combo variableCombo = new Combo(parent, SWT.READ_ONLY);
1113 variableCombo.setItems(sizeContributions.keySet().toArray(new String[sizeContributions.size()]));
1114 GridDataFactory.fillDefaults().grab(true, false).hint(100, SWT.DEFAULT).align(SWT.CENTER, SWT.CENTER).applyTo(variableCombo);
1116 Text minText = new Text(parent, SWT.BORDER);
1117 GridDataFactory.fillDefaults().grab(true, false).hint(100, SWT.DEFAULT).align(SWT.CENTER, SWT.CENTER).applyTo(minText);
1118 addSelectionListener(minText);
1120 Text maxText = new Text(parent, SWT.BORDER);
1121 GridDataFactory.fillDefaults().grab(true, false).hint(100, SWT.DEFAULT).align(SWT.CENTER, SWT.CENTER).applyTo(maxText);
1122 addSelectionListener(maxText);
1124 Label unit = new Label(parent, SWT.NONE);
1125 GridDataFactory.fillDefaults().grab(true, false).hint(30, SWT.DEFAULT).align(SWT.CENTER, SWT.CENTER).applyTo(unit);
1127 Combo sizeMapCombo = new Combo(parent, SWT.READ_ONLY);
1128 GridDataFactory.fillDefaults().grab(true, false).hint(100, SWT.DEFAULT).align(SWT.CENTER, SWT.CENTER).applyTo(sizeMapCombo);
1129 sizeMapCombo.setItems(sizeMaps.keySet().toArray(new String[sizeMaps.keySet().size()]));
1130 addSelectionListener(sizeMapCombo);
1132 Button defaultButton = new Button(parent, SWT.CHECK);
1133 GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(defaultButton);
1134 defaultButton.addSelectionListener(new SelectionAdapter() {
1137 public void widgetSelected(SelectionEvent e) {
1138 int index = variableCombo.getSelectionIndex();
1140 String key = variableCombo.getItem(index);
1141 DynamicSizeContribution cont = sizeContributions.get(key);
1143 minText.setText(Double.toString(cont.getDefaultMin()));
1144 minText.setEnabled(!defaultButton.getSelection());
1145 maxText.setText(Double.toString(cont.getDefaultMax()));
1146 maxText.setEnabled(!defaultButton.getSelection());
1147 unit.setText(cont.getUnit());
1149 String[] items = sizeMapCombo.getItems();
1150 for (int i = 0; i < items.length; i++) {
1151 String item = items[i];
1152 if (item.equals(cont.getDefaultSizeMap().getLabel())) {
1153 sizeMapCombo.select(i);
1157 sizeMapCombo.setEnabled(!defaultButton.getSelection());
1161 addSelectionListener(defaultButton);
1163 variableCombo.addSelectionListener(new SelectionAdapter() {
1166 public void widgetSelected(SelectionEvent e) {
1167 // handle update for others
1168 String key = variableCombo.getItem(variableCombo.getSelectionIndex());
1169 DynamicSizeContribution cont = sizeContributions.get(key);
1171 if (minText.getText().isEmpty()) {
1172 minText.setText(Double.toString(cont.getDefaultMin()));
1174 if (maxText.getText().isEmpty()) {
1175 maxText.setText(Double.toString(cont.getDefaultMax()));
1177 unit.setText(cont.getUnit());
1179 String[] items = sizeMapCombo.getItems();
1180 for (int i = 0; i < items.length; i++) {
1181 String item = items[i];
1182 if (item.equals(cont.getDefaultSizeMap().getLabel())) {
1183 sizeMapCombo.select(i);
1188 defaultButton.setSelection(true);
1191 addSelectionListener(variableCombo);
1193 sizingRows.put(object.getSizingObject().getName(), new SizingObjectRow(label, usedButton, variableCombo, minText, maxText, unit, sizeMapCombo, defaultButton));
1195 return new Supplier<Pair<String, DynamicSizeContribution>>() {
1198 public Pair<String, DynamicSizeContribution> get() {
1199 int selectionIndex = variableCombo.getSelectionIndex();
1200 if (selectionIndex >= 0) {
1201 String key = variableCombo.getItem(selectionIndex);
1202 DynamicSizeContribution cont = sizeContributions.get(key);
1205 String label = variableCombo.getItem(variableCombo.getSelectionIndex());
1206 DynamicSizeContribution dsc;
1207 if (sizeMapCombo.getSelectionIndex() > -1) {
1208 String sizeMap = sizeMapCombo.getItem(sizeMapCombo.getSelectionIndex());
1209 DynamicSizeMap dSizeMap = sizeMaps.get(sizeMap);
1210 dsc = new DynamicSizeContribution(label, cont.getModuleName(), cont.getAttributeName(), unit.getText(), cont.getVariableGain(), cont.getVariableBias(), dSizeMap, Double.parseDouble(minText.getText()), Double.parseDouble(maxText.getText()));
1212 dsc = sizeContributions.get(label);
1214 dsc.setUsed(usedButton.getSelection());
1215 dsc.setUseDefault(defaultButton.getSelection());
1217 return Pair.make(object.getSizingObject().getName(), dsc);
1225 private void initializeColorBars(Composite parent) {
1226 Group group = new Group(parent, SWT.NONE);
1227 group.setText("Color Bars");
1228 GridDataFactory.fillDefaults().grab(true, false).applyTo(group);
1229 GridLayoutFactory.fillDefaults().numColumns(8).margins(5, 5).applyTo(group);
1231 createColorBars(group);
1234 private void createColorBars(Composite parent) {
1236 showColorButton = new Button(parent, SWT.CHECK);
1237 showColorButton.setText("Show");
1238 addSelectionListener(showColorButton);
1240 colorTicksButton = new Button(parent, SWT.CHECK);
1241 colorTicksButton.setText("Ticks");
1242 addSelectionListener(colorTicksButton);
1244 colorGradientButton = new Button(parent, SWT.CHECK);
1245 colorGradientButton.setText("Gradients");
1246 addSelectionListener(colorGradientButton);
1248 Label label = new Label(parent, SWT.NONE);
1249 label.setText("Location");
1250 colorLocationCombo = new Combo(parent, SWT.READ_ONLY);
1251 String[] colorLocationItems = Stream.of(ColorBarsLocation.values()).map(size -> size.toString()).toArray(String[]::new);
1252 colorLocationCombo.setItems(colorLocationItems);
1253 if (colorLocationItems.length > 0) {
1254 colorLocationCombo.select(0);
1256 addSelectionListener(colorLocationCombo);
1258 label = new Label(parent, SWT.NONE);
1259 label.setText("Size");
1260 colorSizeCombo = new Combo(parent, SWT.READ_ONLY);
1261 String[] colorSizeItems = Stream.of(ColorBarsSize.values()).map(size -> size.toString()).toArray(String[]::new);
1262 colorSizeCombo.setItems(colorSizeItems);
1263 if (colorSizeItems.length > 0) {
1264 colorSizeCombo.select(0);
1266 addSelectionListener(colorSizeCombo);
1269 private void initializeObjectSizes(Composite parent) {
1270 Group group = new Group(parent, SWT.NONE);
1271 group.setText("Object Sizes");
1272 GridDataFactory.fillDefaults().grab(true, false).applyTo(group);
1273 GridLayoutFactory.fillDefaults().numColumns(8).margins(5, 5).applyTo(group);
1276 createSizingObjectHeaderRow(group);
1277 createObjectSizes(group);
1281 private void createObjectSizes(Composite parent) {
1283 sizeSuppliers = new ArrayList<>();
1285 Pair<Collection<DynamicSizingObject>, Map<String, DynamicSizeMap>> resultSizing = Simantics.getSession().syncRequest(new UniqueRead<Pair<Collection<DynamicSizingObject>, Map<String, DynamicSizeMap>>>() {
1288 public Pair<Collection<DynamicSizingObject>, Map<String, DynamicSizeMap>> perform(ReadGraph graph) throws DatabaseException {
1289 Map<String, DynamicSizeMap> dynamicSizeMaps = DynamicVisualisationsContributions.dynamicSizeMaps(graph);
1290 return Pair.make(DynamicVisualisationsContributions.dynamicSizingObjects(graph), dynamicSizeMaps);
1294 for (DynamicSizingObject object : resultSizing.first) {
1295 sizeSuppliers.add(createSizingObjectRow(parent, object, resultSizing.second));
1297 } catch (DatabaseException e) {
1298 LOGGER.error("Could not create object sizes", e);
1302 private void initializeSizeBars(Composite parent) {
1303 Group group = new Group(parent, SWT.NONE);
1304 group.setText("Size Bars");
1305 GridDataFactory.fillDefaults().grab(true, false).applyTo(group);
1306 GridLayoutFactory.fillDefaults().numColumns(8).margins(5, 5).applyTo(group);
1308 createSizeBars(group);
1311 private void createSizeBars(Composite parent) {
1312 showSizeButton = new Button(parent, SWT.CHECK);
1313 showSizeButton.setText("Show");
1314 addSelectionListener(showSizeButton);
1316 sizeTicksButton = new Button(parent, SWT.CHECK);
1317 sizeTicksButton.setText("Ticks");
1318 addSelectionListener(sizeTicksButton);
1320 sizeGradientButton = new Button(parent, SWT.CHECK);
1321 sizeGradientButton.setText("Gradient");
1322 addSelectionListener(sizeGradientButton);
1324 Label label = new Label(parent, SWT.NONE);
1325 label.setText("Location");
1326 sizeLocationCombo = new Combo(parent, SWT.READ_ONLY);
1327 String[] sizeLocationItems = Stream.of(SizeBarsLocation.values()).map(size -> size.toString()).toArray(String[]::new);
1328 sizeLocationCombo.setItems(sizeLocationItems);
1329 if (sizeLocationItems.length > 0) {
1330 sizeLocationCombo.select(0);
1332 addSelectionListener(sizeLocationCombo);
1334 label = new Label(parent, SWT.NONE);
1335 label.setText("Size");
1336 sizeSizeCombo = new Combo(parent, SWT.READ_ONLY);
1337 String[] sizeSizeItems = Stream.of(SizeBarsSize.values()).map(size -> size.toString()).toArray(String[]::new);
1338 sizeSizeCombo.setItems(sizeSizeItems);
1339 if (sizeSizeItems.length > 0) {
1340 sizeSizeCombo.select(0);
1342 addSelectionListener(sizeSizeCombo);
1345 private void addSelectionListener(Widget widget) {
1346 if (widget instanceof Button) {
1347 ((Button) widget).addSelectionListener(new SelectionAdapter() {
1350 public void widgetSelected(SelectionEvent e) {
1351 persistCurrentVisualisationTemplateIfAvailable();
1354 } else if (widget instanceof Combo) {
1355 ((Combo) widget).addSelectionListener(new SelectionAdapter() {
1358 public void widgetSelected(SelectionEvent e) {
1359 persistCurrentVisualisationTemplateIfAvailable();
1362 } else if (widget instanceof Text) {
1363 ((Text) widget).addFocusListener(new FocusAdapter() {
1366 public void focusLost(FocusEvent e) {
1367 persistCurrentVisualisationTemplateIfAvailable();
1370 ((Text) widget).addKeyListener(new KeyAdapter() {
1373 public void keyReleased(KeyEvent e) {
1374 if(e.keyCode == SWT.CR || e.keyCode == SWT.LF) {
1375 persistCurrentVisualisationTemplateIfAvailable();
1382 public void setParentResource(Resource parentResource) {
1383 if (this.parentResource != parentResource) {
1384 this.parentResource = parentResource;
1387 saveVisualisationTemplateAsButton.setEnabled(parentResource != null);
1390 private void updateListening() {
1391 if (visualisationsListener != null)
1392 visualisationsListener.dispose();
1393 if (parentResource != null) {
1394 visualisationsListener = new VisualisationsListener(this);
1395 Simantics.getSession().asyncRequest(new DynamicVisualisationsRequest(parentResource), visualisationsListener);
1398 if (listener != null)
1400 if (parentResource != null) {
1401 listener = new VisualisationListener(this);
1402 Simantics.getSession().asyncRequest(new ActiveDynamicVisualisationsRequest(parentResource), listener);
1406 private static class VisualisationsListener implements Listener<Collection<NamedResource>> {
1408 private static final Logger LOGGER = LoggerFactory.getLogger(VisualisationsListener.class);
1410 private boolean disposed;
1411 private DynamicVisualisationsUI ui;
1413 public VisualisationsListener(DynamicVisualisationsUI ui) {
1418 public void execute(Collection<NamedResource> result) {
1419 ui.updateVisualisations(result);
1423 public void exception(Throwable t) {
1424 LOGGER.error("Could not listen visualisation", t);
1428 public boolean isDisposed() {
1429 return disposed || ui.getParent().isDisposed();
1432 public void dispose() {
1433 this.disposed = true;
1437 private static class VisualisationListener implements Listener<DynamicVisualisation> {
1439 private static final Logger LOGGER = LoggerFactory.getLogger(VisualisationListener.class);
1441 private boolean disposed;
1442 private DynamicVisualisationsUI ui;
1444 public VisualisationListener(DynamicVisualisationsUI ui) {
1449 public void execute(DynamicVisualisation result) {
1450 ui.updateVisualisation(result);
1454 public void exception(Throwable t) {
1455 LOGGER.error("Could not listen visualisation", t);
1459 public boolean isDisposed() {
1460 return disposed ||ui.getParent().isDisposed();
1463 public void dispose() {
1464 this.disposed = true;
1468 public void updateVisualisation(DynamicVisualisation result) {
1469 this.visualisation = result;
1470 Display.getDefault().asyncExec(() -> {
1471 if (getParent().isDisposed())
1474 removeVisualisationTemplateButton.setEnabled(visualisation != null && visualisation.getVisualisationResource() != null);
1476 if (visualisation != null) {
1477 String[] items = templateSelectionCombo.getItems();
1478 for (int i = 0; i < items.length; i++) {
1479 if (visualisation.getName().equals(items[i])) {
1480 templateSelectionCombo.select(i);
1485 intervalText.setText(Double.toString(((double)visualisation.getInterval()) / 1000.0));
1486 disableUpdatesButton.setSelection(visualisation.disabledUpdates());
1488 hoveringVertexEnabledButton.setSelection(visualisation.isKeyVariablesVertexHover());
1489 hoveringEdgesEnabledButton.setSelection(visualisation.isKeyVariablesEdgesHover());
1491 hideConsumersButton.setSelection(visualisation.isHideConsumers());
1492 hideEdgesButton.setSelection(visualisation.isHideEdges());
1493 hideProducersButton.setSelection(visualisation.isHideProducers());
1494 hideValvesButton.setSelection(visualisation.isHideValves());
1495 hidePumpingStationsButton.setSelection(visualisation.isHidePumpingStations());
1496 hidePointsButton.setSelection(visualisation.isHidePoints());
1498 Map<String, DynamicColorContribution> colorContributions = visualisation.getColorContributions();
1499 for (Entry<String, DynamicColorContribution> entry : colorContributions.entrySet()) {
1501 ColoringObjectRow coloringObjectRow = coloringRows.get(entry.getKey());
1502 if (coloringObjectRow != null) {
1504 coloringObjectRow.update(entry.getValue());
1507 LOGGER.info("No coloring object visualisation row for key {}", entry.getKey());
1510 ColorBarOptions colorOptions = visualisation.getColorBarOptions();
1511 showColorButton.setSelection(colorOptions.isShowColorBars());
1512 colorTicksButton.setSelection(colorOptions.isShowColorBarsTicks());
1513 colorGradientButton.setSelection(colorOptions.isUseGradients());
1514 for (int i = 0; i < colorLocationCombo.getItems().length; i++) {
1515 String item = colorLocationCombo.getItem(i);
1516 if (item.equals(colorOptions.getLocation().toString())) {
1517 colorLocationCombo.select(i);
1521 for (int i = 0; i < colorSizeCombo.getItems().length; i++) {
1522 String item = colorSizeCombo.getItem(i);
1523 if (item.equals(colorOptions.getSize().toString())) {
1524 colorSizeCombo.select(i);
1529 Map<String, DynamicSizeContribution> sizeContributions = visualisation.getSizeContributions();
1530 for (Entry<String, DynamicSizeContribution> entry : sizeContributions.entrySet()) {
1532 SizingObjectRow sizingObjectRow = sizingRows.get(entry.getKey());
1533 if (sizingObjectRow != null) {
1535 sizingObjectRow.update(entry.getValue());
1538 LOGGER.info("No sizing object visualisation row for key {}", entry.getKey());
1541 SizeBarOptions sizeOptions = visualisation.getSizeBarOptions();
1542 showSizeButton.setSelection(sizeOptions.isShowSizeBars());
1543 sizeTicksButton.setSelection(sizeOptions.isShowSizeBarsTicks());
1544 sizeGradientButton.setSelection(sizeOptions.isUseGradients());
1545 for (int i = 0; i < sizeLocationCombo.getItems().length; i++) {
1546 String item = sizeLocationCombo.getItem(i);
1547 if (item.equals(sizeOptions.getLocation().toString())) {
1548 sizeLocationCombo.select(i);
1552 for (int i = 0; i < sizeSizeCombo.getItems().length; i++) {
1553 String item = sizeSizeCombo.getItem(i);
1554 if (item.equals(sizeOptions.getSize().toString())) {
1555 sizeSizeCombo.select(i);
1560 pointsStaticPropertiesButton.setSelection(visualisation.isStaticPropertiesPoints());
1561 networkBranchesStaticPropertiesButton.setSelection(visualisation.isStaticPropertiesNetworkBranches());
1562 consumersStaticPropertiesButton.setSelection(visualisation.isStaticPropertiesConsumers());
1567 public void updateVisualisations(Collection<NamedResource> result) {
1568 this.visualisations = result;
1570 Display.getDefault().asyncExec(() -> {
1571 if (getParent().isDisposed())
1573 templateSelectionCombo.setItems(visualisations.stream().map(NamedResource::getName).collect(Collectors.toList()).toArray(new String[visualisations.size()]));
1575 if (visualisation != null) {
1576 String[] items = templateSelectionCombo.getItems();
1577 for (int i = 0; i < items.length; i++) {
1578 if (visualisation.getName().equals(items[i])) {
1579 templateSelectionCombo.select(i);
1588 public Composite getParent() {