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;
105 private List<Supplier<Pair<String, DynamicArrowContribution>>> edgeArrowSuppliers;
107 private Button saveVisualisationTemplateAsButton;
109 private Button hideEdgesButton;
110 private Button hidePointsButton;
111 private Button hideConsumersButton;
112 private Button hideProducersButton;
113 private Button hideValvesButton;
114 private Button hidePumpingStationsButton;
116 private Button networkBranchesStaticPropertiesButton;
117 private Button pointsStaticPropertiesButton;
118 private Button consumersStaticPropertiesButton;
120 private Button dynamicSymbolsEdgesButton;
121 private Button dynamicSymbolsProducersButton;
122 private Button dynamicSymbolsValvesButton;
123 private Button dynamicSymbolsPumpingStationsButton;
125 private Text intervalText;
127 public DynamicVisualisationsUI(Composite parent) {
128 this.parent = parent;
129 ScrolledComposite scrolledComposite = new ScrolledComposite(parent, SWT.V_SCROLL | SWT.H_SCROLL);
130 scrolledComposite.setLayout(new GridLayout(1, false));
131 scrolledComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
133 Composite firstContent = new Composite(scrolledComposite, SWT.NONE);
134 firstContent.setLayout(new GridLayout(1, false));
135 firstContent.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
137 defaultInitializeUI(firstContent);
139 scrolledComposite.setContent(firstContent);
140 scrolledComposite.setExpandHorizontal(true);
141 scrolledComposite.setExpandVertical(true);
142 scrolledComposite.setMinSize(firstContent.computeSize(SWT.DEFAULT, SWT.DEFAULT));
145 private void defaultInitializeUI(Composite parent) {
147 GridDataFactory.fillDefaults().grab(true, true).applyTo(parent);
148 GridLayoutFactory.fillDefaults().numColumns(1).margins(5, 5).applyTo(parent);
150 Composite selectionComposite = new Composite(parent, SWT.NONE);
151 GridDataFactory.fillDefaults().grab(true, false).applyTo(selectionComposite);
152 GridLayoutFactory.fillDefaults().numColumns(2).margins(5, 5).applyTo(selectionComposite);
154 Label templateNameLabel = new Label(selectionComposite, SWT.NONE);
155 templateNameLabel.setText("Visualisation template");
156 templateSelectionCombo = new Combo(selectionComposite, SWT.READ_ONLY);
157 GridDataFactory.fillDefaults().grab(true, false).applyTo(templateSelectionCombo);
158 templateSelectionCombo.addSelectionListener(new SelectionAdapter() {
161 public void widgetSelected(SelectionEvent e) {
162 String item = templateSelectionCombo.getItem(templateSelectionCombo.getSelectionIndex());
163 for (NamedResource template : visualisations) {
164 if (item.equals(template.getName())) {
165 if (parentResource != null) {
166 Resource res = parentResource;
167 Simantics.getSession().asyncRequest(new WriteRequest() {
170 public void perform(WriteGraph graph) throws DatabaseException {
171 Resource vf = DynamicVisualisations.getVisualisationFolder(graph, res);
172 DynamicVisualisations.setActiveVisualisation(graph, vf, template.getResource());
182 Composite intervalElementsComposite = new Composite(parent, SWT.NONE);
183 GridDataFactory.fillDefaults().grab(true, false).applyTo(intervalElementsComposite);
184 GridLayoutFactory.fillDefaults().numColumns(1).applyTo(intervalElementsComposite);
185 initializeIntervalElements(intervalElementsComposite);
187 Composite hideElementsComposite = new Composite(parent, SWT.NONE);
188 GridDataFactory.fillDefaults().grab(true, false).applyTo(hideElementsComposite);
189 GridLayoutFactory.fillDefaults().numColumns(1).applyTo(hideElementsComposite);
190 initializeHideElements(hideElementsComposite);
192 Composite staticPropertiesComposite = new Composite(parent, SWT.NONE);
193 GridDataFactory.fillDefaults().grab(true, false).applyTo(staticPropertiesComposite);
194 GridLayoutFactory.fillDefaults().numColumns(1).applyTo(staticPropertiesComposite);
195 initializeStaticProperties(staticPropertiesComposite);
197 Composite dynamicSymbolsComposite = new Composite(parent, SWT.NONE);
198 GridDataFactory.fillDefaults().grab(true, false).applyTo(dynamicSymbolsComposite);
199 GridLayoutFactory.fillDefaults().numColumns(1).applyTo(dynamicSymbolsComposite);
200 initializeDynamicSymbols(dynamicSymbolsComposite);
202 Composite coloringObjectsComposite = new Composite(parent, SWT.NONE);
203 GridDataFactory.fillDefaults().grab(true, false).applyTo(coloringObjectsComposite);
204 GridLayoutFactory.fillDefaults().numColumns(1).applyTo(coloringObjectsComposite);
205 initializeColoringObjects(coloringObjectsComposite);
207 Composite colorBarsComposite = new Composite(parent, SWT.NONE);
208 GridDataFactory.fillDefaults().grab(true, false).applyTo(colorBarsComposite);
209 GridLayoutFactory.fillDefaults().numColumns(1).applyTo(colorBarsComposite);
210 initializeColorBars(colorBarsComposite);
212 Composite objectSizesComposite = new Composite(parent, SWT.NONE);
213 GridDataFactory.fillDefaults().grab(true, false).applyTo(objectSizesComposite);
214 GridLayoutFactory.fillDefaults().numColumns(1).applyTo(objectSizesComposite);
215 initializeObjectSizes(objectSizesComposite);
217 Composite sizeBarsComposite = new Composite(parent, SWT.NONE);
218 GridDataFactory.fillDefaults().grab(true, false).applyTo(sizeBarsComposite);
219 GridLayoutFactory.fillDefaults().numColumns(1).applyTo(sizeBarsComposite);
220 initializeSizeBars(sizeBarsComposite);
222 Composite edgeArrowsComposite = new Composite(parent, SWT.NONE);
223 GridDataFactory.fillDefaults().grab(true, false).applyTo(edgeArrowsComposite);
224 GridLayoutFactory.fillDefaults().numColumns(1).applyTo(edgeArrowsComposite);
225 initializeEdgeArrows(edgeArrowsComposite);
227 Composite buttonBarsComposite = new Composite(parent, SWT.NONE);
228 GridDataFactory.fillDefaults().grab(true, false).applyTo(buttonBarsComposite);
229 GridLayoutFactory.fillDefaults().numColumns(3).applyTo(buttonBarsComposite);
231 saveVisualisationTemplateAsButton = new Button(buttonBarsComposite, SWT.NONE);
232 saveVisualisationTemplateAsButton.setText("Save as visualisation template");
233 saveVisualisationTemplateAsButton.addSelectionListener(new SelectionAdapter() {
236 public void widgetSelected(SelectionEvent e) {
237 showSaveVisualisationTemplateDialog(e.widget.getDisplay().getActiveShell());
241 removeVisualisationTemplateButton = new Button(buttonBarsComposite, SWT.NONE);
242 removeVisualisationTemplateButton.setText("Remove");
243 removeVisualisationTemplateButton.setEnabled(visualisation != null && visualisation.getVisualisationResource() != null);
244 removeVisualisationTemplateButton.addSelectionListener(new SelectionAdapter() {
247 public void widgetSelected(SelectionEvent e) {
248 removeVisualisationTemplate(visualisation.getName(), Optional.of(visualisation.getVisualisationResource()));
253 private void initializeIntervalElements(Composite parent) {
254 Group group = new Group(parent, SWT.NONE);
255 group.setText("Interval");
256 GridDataFactory.fillDefaults().grab(true, false).applyTo(group);
257 GridLayoutFactory.fillDefaults().numColumns(6).margins(5, 5).applyTo(group);
259 createIntervalElements(group);
262 private void createIntervalElements(Composite parent) {
264 Label label = new Label(parent, SWT.NONE);
265 label.setText("Generic");
266 intervalText = new Text(parent, SWT.BORDER);
267 addSelectionListener(intervalText);
269 disableUpdatesButton = new Button(parent, SWT.CHECK);
270 disableUpdatesButton.setText("Disable updates");
271 addSelectionListener(disableUpdatesButton);
273 resetVisualisationButton = new Button(parent, SWT.CHECK);
274 resetVisualisationButton.setText("Reset Visualisation");
275 addSelectionListener(resetVisualisationButton);
277 hoveringVertexEnabledButton = new Button(parent, SWT.CHECK);
278 hoveringVertexEnabledButton.setText("Vertex Key Variables on Hover");
279 addSelectionListener(hoveringVertexEnabledButton);
281 hoveringEdgesEnabledButton = new Button(parent, SWT.CHECK);
282 hoveringEdgesEnabledButton.setText("Edge Key Variables on Hover");
283 addSelectionListener(hoveringEdgesEnabledButton);
286 private void initializeHideElements(Composite parent) {
287 Group group = new Group(parent, SWT.NONE);
288 group.setText("Hide Elements");
289 GridDataFactory.fillDefaults().grab(true, false).applyTo(group);
290 GridLayoutFactory.fillDefaults().numColumns(8).margins(5, 5).applyTo(group);
292 createHideElements(group);
295 private void createHideElements(Composite parent) {
297 hideEdgesButton = new Button(parent, SWT.CHECK);
298 hideEdgesButton.setText("Edges");
299 addSelectionListener(hideEdgesButton);
301 hidePointsButton = new Button(parent, SWT.CHECK);
302 hidePointsButton.setText("Points");
303 addSelectionListener(hidePointsButton);
305 hideConsumersButton = new Button(parent, SWT.CHECK);
306 hideConsumersButton.setText("Consumers");
307 addSelectionListener(hideConsumersButton);
309 hideProducersButton = new Button(parent, SWT.CHECK);
310 hideProducersButton.setText("Producers");
311 addSelectionListener(hideProducersButton);
313 hideValvesButton = new Button(parent, SWT.CHECK);
314 hideValvesButton.setText("Valves");
315 addSelectionListener(hideValvesButton);
317 hidePumpingStationsButton = new Button(parent, SWT.CHECK);
318 hidePumpingStationsButton.setText("Pumping Stations");
319 addSelectionListener(hidePumpingStationsButton);
322 private void initializeStaticProperties(Composite parent) {
323 Group group = new Group(parent, SWT.NONE);
324 group.setText("Static Properties");
325 GridDataFactory.fillDefaults().grab(true, false).applyTo(group);
326 GridLayoutFactory.fillDefaults().numColumns(8).margins(5, 5).applyTo(group);
328 createStaticProperties(group);
331 private void createStaticProperties(Composite parent) {
333 networkBranchesStaticPropertiesButton = new Button(parent, SWT.CHECK);
334 networkBranchesStaticPropertiesButton.setText("Network Branches");
335 addSelectionListener(networkBranchesStaticPropertiesButton);
337 pointsStaticPropertiesButton = new Button(parent, SWT.CHECK);
338 pointsStaticPropertiesButton.setText("Points");
339 addSelectionListener(pointsStaticPropertiesButton);
341 consumersStaticPropertiesButton = new Button(parent, SWT.CHECK);
342 consumersStaticPropertiesButton.setText("Consumers");
343 addSelectionListener(consumersStaticPropertiesButton);
347 private void initializeDynamicSymbols(Composite parent) {
348 Group group = new Group(parent, SWT.NONE);
349 group.setText("Dynamic Symbols");
350 GridDataFactory.fillDefaults().grab(true, false).applyTo(group);
351 GridLayoutFactory.fillDefaults().numColumns(8).margins(5, 5).applyTo(group);
353 createDynamicSymbols(group);
356 private void createDynamicSymbols(Composite parent) {
358 dynamicSymbolsEdgesButton = new Button(parent, SWT.CHECK);
359 dynamicSymbolsEdgesButton.setText("Shutoff Valves in Pipes");
360 addSelectionListener(dynamicSymbolsEdgesButton);
362 dynamicSymbolsProducersButton = new Button(parent, SWT.CHECK);
363 dynamicSymbolsProducersButton.setText("Producers");
364 addSelectionListener(dynamicSymbolsProducersButton);
366 dynamicSymbolsValvesButton = new Button(parent, SWT.CHECK);
367 dynamicSymbolsValvesButton.setText("Valves");
368 addSelectionListener(dynamicSymbolsValvesButton);
370 dynamicSymbolsPumpingStationsButton = new Button(parent, SWT.CHECK);
371 dynamicSymbolsPumpingStationsButton.setText("Pumping Stations");
372 addSelectionListener(dynamicSymbolsPumpingStationsButton);
375 private void initializeEdgeArrows(Composite parent) {
376 Group group = new Group(parent, SWT.NONE);
377 group.setText("Edge Arrows");
378 GridDataFactory.fillDefaults().grab(true, false).applyTo(group);
379 GridLayoutFactory.fillDefaults().numColumns(6).margins(5, 5).applyTo(group);
381 createEdgeArrowsHeaderRow(group);
383 edgeArrowSuppliers = new ArrayList<>();
386 Collection<DynamicArrowObject> result = Simantics.getSession().syncRequest(new UniqueRead<Collection<DynamicArrowObject>>() {
389 public Collection<DynamicArrowObject> perform(ReadGraph graph) throws DatabaseException {
390 return DynamicVisualisationsContributions.dynamicEdgeArrowObjects(graph);
394 for (DynamicArrowObject object : result) {
395 edgeArrowSuppliers.add(createEdgeArrowRow(group, object));
397 } catch (DatabaseException e) {
398 LOGGER.error("Could not create coloring objecst", e);
404 private void createEdgeArrowsHeaderRow(Composite parent) {
406 Label label = new Label(parent, SWT.NONE);
407 label.setText("Label");
408 GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
410 label = new Label(parent, SWT.NONE);
411 label.setText("Used");
412 GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
414 label = new Label(parent, SWT.NONE);
415 label.setText("Variable");
416 GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
418 label = new Label(parent, SWT.NONE);
419 label.setText("Gain");
420 GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
422 label = new Label(parent, SWT.NONE);
423 label.setText("Bias");
424 GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
426 label = new Label(parent, SWT.NONE);
427 label.setText("Default");
428 GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
431 private Supplier<Pair<String, DynamicArrowContribution>> createEdgeArrowRow(Composite parent, DynamicArrowObject object) {
433 Map<String, DynamicArrowContribution> arrowContributions = object.getArrowContributions();
434 if (arrowContributions.isEmpty()) {
435 // ok, no point in showing empty combo boxes
439 Label label = new Label(parent, SWT.NONE);
440 label.setText(object.getArrowObject().getName());
441 GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(label);
443 Button usedButton = new Button(parent, SWT.CHECK);
444 GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(usedButton);
445 addSelectionListener(usedButton);
447 Combo variableCombo = new Combo(parent, SWT.READ_ONLY);
448 variableCombo.setItems(arrowContributions.keySet().toArray(new String[arrowContributions.size()]));
450 GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(variableCombo);
452 Text gainText = new Text(parent, SWT.BORDER);
453 GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(gainText);
454 addSelectionListener(gainText);
456 Text biasText = new Text(parent, SWT.BORDER);
457 GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(biasText);
458 addSelectionListener(biasText);
460 Button defaultButton = new Button(parent, SWT.CHECK);
461 GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(defaultButton);
462 defaultButton.addSelectionListener(new SelectionAdapter() {
465 public void widgetSelected(SelectionEvent e) {
466 int index = variableCombo.getSelectionIndex();
468 String key = variableCombo.getItem(index);
469 DynamicArrowContribution cont = arrowContributions.get(key);
471 gainText.setText(Double.toString(cont.getDefaultGain()));
472 gainText.setEnabled(!defaultButton.getSelection());
473 biasText.setText(Double.toString(cont.getDefaultBias()));
474 biasText.setEnabled(!defaultButton.getSelection());
479 addSelectionListener(defaultButton);
481 variableCombo.addSelectionListener(new SelectionAdapter() {
484 public void widgetSelected(SelectionEvent e) {
485 // handle update for others
486 String key = variableCombo.getItem(variableCombo.getSelectionIndex());
487 DynamicArrowContribution cont = arrowContributions.get(key);
489 if (gainText.getText().isEmpty()) {
490 gainText.setText(Double.toString(cont.getDefaultGain()));
492 if (biasText.getText().isEmpty()) {
493 biasText.setText(Double.toString(cont.getDefaultBias()));
496 defaultButton.setSelection(true);
499 addSelectionListener(variableCombo);
501 arrowRows.put(object.getArrowObject().getName(), new ArrowObjectRow(label, usedButton, variableCombo, gainText, biasText, defaultButton));
503 return new Supplier<Pair<String, DynamicArrowContribution>>() {
506 public Pair<String, DynamicArrowContribution> get() {
507 int selectionIndex = variableCombo.getSelectionIndex();
508 if (selectionIndex >= 0) {
509 String key = variableCombo.getItem(selectionIndex);
510 DynamicArrowContribution cont = arrowContributions.get(key);
512 String label = variableCombo.getItem(variableCombo.getSelectionIndex());
514 double gain = cont.getDefaultGain();
515 String gainS = gainText.getText();
516 if (gainS != null && !gainS.isEmpty()) {
517 gain = Double.parseDouble(gainS);
519 double bias = cont.getDefaultBias();
520 String biasS = biasText.getText();
521 if (biasS != null && !biasS.isEmpty()) {
522 bias = Double.parseDouble(biasText.getText());
525 DynamicArrowContribution dsc = new DynamicArrowContribution(label, cont.getModuleName(), cont.getAttributeName(), gain, bias);
526 dsc.setUsed(usedButton.getSelection());
527 dsc.setUseDefault(defaultButton.getSelection());
529 return Pair.make(object.getArrowObject().getName(), dsc);
537 protected void removeVisualisationTemplate(String name, Optional<Resource> of) {
538 if (of.isPresent()) {
539 Resource visualisation = of.get();
540 Simantics.getSession().asyncRequest(new WriteRequest() {
543 public void perform(WriteGraph graph) throws DatabaseException {
544 RemoverUtil.remove(graph, visualisation);
550 private void showSaveVisualisationTemplateDialog(Shell shell) {
552 InputDialog dialog = new InputDialog(shell, "Save visualisation template", "Give template a name", "", new IInputValidator() {
555 public String isValid(String newText) {
556 if (newText == null || newText.isEmpty())
557 return "Name cannot be empty";
562 if (dialog.open() == Dialog.OK) {
563 String name = dialog.getValue();
565 persistVisualisationTemplate(name, Optional.empty());
566 } catch (Exception e) {
567 LOGGER.error("Could not persist visualisation template", e);
568 ShowError.showError("Could not persist visualisation template", e.getMessage(), e);
573 private void persistCurrentVisualisationTemplateIfAvailable() {
574 if (visualisation != null) {
576 persistVisualisationTemplate(visualisation.getName(), Optional.of(visualisation.getVisualisationResource()));
577 } catch (Exception e1) {
578 LOGGER.error("Could not persist visualisation template", e1);
579 ShowError.showError("Could not persist visualisation template", e1.getMessage(), e1);
582 LOGGER.info("No current visualisation template selected for saving");
586 private void persistVisualisationTemplate(String templateName, Optional<Resource> existing) throws Exception {
588 List<Pair<String, DynamicColorContribution>> colorCollect = colorSuppliers.stream().filter(Objects::nonNull).map(s -> s.get()).filter(Objects::nonNull).collect(Collectors.toList());
590 String colorLocation = colorLocationCombo.getItem(colorLocationCombo.getSelectionIndex());
591 String colorSize = colorSizeCombo.getItem(colorSizeCombo.getSelectionIndex());
593 ColorBarOptions colorBarOptions = new ColorBarOptions()
594 .showColorBars(showColorButton.getSelection())
595 .showColorBarsTicks(colorTicksButton.getSelection())
596 .useGradients(colorGradientButton.getSelection())
597 .withLocation(ColorBarsLocation.valueOf(colorLocation))
598 .withSize(ColorBarsSize.valueOf(colorSize));
600 List<Pair<String, DynamicSizeContribution>> sizeCollect = sizeSuppliers.stream().filter(Objects::nonNull).map(s -> s.get()).filter(Objects::nonNull).collect(Collectors.toList());
602 String sizeLocation = sizeLocationCombo.getItem(sizeLocationCombo.getSelectionIndex());
603 String sizeSize = sizeSizeCombo.getItem(sizeSizeCombo.getSelectionIndex());
605 final SizeBarOptions sizeBarOptions = new SizeBarOptions()
606 .showSizeBars(showSizeButton.getSelection())
607 .showSizeBarsTicks(sizeTicksButton.getSelection())
608 .useGradients(sizeGradientButton.getSelection())
609 .withLocation(SizeBarsLocation.valueOf(sizeLocation))
610 .withSize(SizeBarsSize.valueOf(sizeSize));
612 List<Pair<String, DynamicArrowContribution>> edgeArrowCollect = edgeArrowSuppliers.stream().filter(Objects::nonNull).map(s -> s.get()).filter(Objects::nonNull).collect(Collectors.toList());
614 boolean hideEdges = hideEdgesButton.getSelection();
615 boolean hidePoints = hidePointsButton.getSelection();
616 boolean hideConsumers = hideConsumersButton.getSelection();
617 boolean hideProducers = hideProducersButton.getSelection();
618 boolean hideValves = hideValvesButton.getSelection();
619 boolean hidePumpingStations = hidePumpingStationsButton.getSelection();
621 boolean networkBranchesStaticProperties = networkBranchesStaticPropertiesButton.getSelection();
622 boolean pointsStaticProperties = pointsStaticPropertiesButton.getSelection();
623 boolean consumersStaticProperties = consumersStaticPropertiesButton.getSelection();
625 boolean dynamicSymbolsEdges = dynamicSymbolsEdgesButton.getSelection();
626 boolean dynamicSymbolsProducers = dynamicSymbolsProducersButton.getSelection();
627 boolean dynamicSymbolsValves = dynamicSymbolsValvesButton.getSelection();
628 boolean dynamicSymbolsPumpingStations = dynamicSymbolsPumpingStationsButton.getSelection();
630 boolean disabled = disableUpdatesButton.getSelection();
631 boolean resetVisualisation = resetVisualisationButton.getSelection();
634 interval = Long.parseLong(intervalText.getText());
635 } catch (NumberFormatException e) {
639 final long finalInterval = interval;
641 boolean hoverVertex = hoveringVertexEnabledButton.getSelection();
642 boolean hoverEdges = hoveringEdgesEnabledButton.getSelection();
644 Simantics.getSession().asyncRequest(new WriteRequest() {
647 public void perform(WriteGraph graph) throws DatabaseException {
649 if (existing.isPresent()) {
650 exist = existing.get();
652 exist = DynamicVisualisations.createVisualisation(graph, parentResource, templateName);
654 DynamicVisualisations.setIntervalAndDisabled(graph, exist, finalInterval, disabled, resetVisualisation);
655 DynamicVisualisations.setColorContributions(graph, exist, colorCollect);
656 DynamicVisualisations.setColorBarOptions(graph, exist, colorBarOptions);
657 DynamicVisualisations.setSizeContributions(graph, exist, sizeCollect);
658 DynamicVisualisations.setSizeBarOptions(graph, exist, sizeBarOptions);
659 DynamicVisualisations.setEdgeArrowContributions(graph, exist, edgeArrowCollect);
660 DynamicVisualisations.setHideElements(graph, exist,
669 DynamicVisualisations.setStaticProperties(graph, exist,
670 networkBranchesStaticProperties,
671 pointsStaticProperties,
672 consumersStaticProperties
675 DynamicVisualisations.setDynamicSymbols(graph, exist,
677 dynamicSymbolsProducers,
678 dynamicSymbolsValves,
679 dynamicSymbolsPumpingStations
681 DynamicVisualisations.setKeyVariablesHover(graph, exist, hoverVertex, hoverEdges);
686 private void initializeColoringObjects(Composite parent) {
687 Group group = new Group(parent, SWT.NONE);
688 group.setText("Coloring Objects");
689 GridDataFactory.fillDefaults().grab(true, false).applyTo(group);
690 GridLayoutFactory.fillDefaults().numColumns(8).margins(5, 5).applyTo(group);
693 createColoringObjectHeaderRow(group);
695 colorSuppliers = new ArrayList<>();
698 Pair<Collection<DynamicColoringObject>, Map<String, DynamicColorMap>> result = Simantics.getSession().syncRequest(new UniqueRead<Pair<Collection<DynamicColoringObject>, Map<String, DynamicColorMap>>>() {
701 public Pair<Collection<DynamicColoringObject>, Map<String, DynamicColorMap>> perform(ReadGraph graph) throws DatabaseException {
702 Map<String, DynamicColorMap> dynamicColorMaps = DynamicVisualisationsContributions.dynamicColorMaps(graph);
703 return Pair.make(DynamicVisualisationsContributions.dynamicColoringObjects(graph), dynamicColorMaps);
707 for (DynamicColoringObject object : result.first) {
708 colorSuppliers.add(createColoringObjectRow(group, object, result.second));
711 } catch (DatabaseException e) {
712 LOGGER.error("Could not create coloring objecst", e);
717 private void createColoringObjectHeaderRow(Composite parent) {
719 Label label = new Label(parent, SWT.NONE);
720 label.setText("Label");
721 GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
723 label = new Label(parent, SWT.NONE);
724 label.setText("Used");
725 GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
727 label = new Label(parent, SWT.NONE);
728 label.setText("Variable");
729 GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
731 label = new Label(parent, SWT.NONE);
732 label.setText("Min");
733 GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
735 label = new Label(parent, SWT.NONE);
736 label.setText("Max");
737 GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
739 label = new Label(parent, SWT.NONE);
740 label.setText("Unit");
741 GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
743 label = new Label(parent, SWT.NONE);
744 label.setText("ColorMap");
745 GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
747 label = new Label(parent, SWT.NONE);
748 label.setText("Default");
749 GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
752 private Map<String, ColoringObjectRow> coloringRows = new HashMap<>();
753 private Map<String, SizingObjectRow> sizingRows = new HashMap<>();
754 private Map<String, ArrowObjectRow> arrowRows = new HashMap<>();
756 private VisualisationsListener visualisationsListener;
758 private Collection<NamedResource> visualisations;
760 private List<Supplier<Pair<String, DynamicSizeContribution>>> sizeSuppliers;
762 private static class ColoringObjectRow {
764 private final Label label;
765 private final Button usedButton;
766 private final Combo variableCombo;
767 private final Text minText;
768 private final Text maxText;
769 private final Text unit;
770 private final Combo colorMapCombo;
771 private final Button defaultButton;
773 public ColoringObjectRow(Label label, Button usedButton, Combo variableCombo, Text minText, Text maxText, Text unit,
774 Combo colorMapCombo, Button defaultButton) {
777 this.usedButton = usedButton;
778 this.variableCombo = variableCombo;
779 this.minText = minText;
780 this.maxText = maxText;
782 this.colorMapCombo = colorMapCombo;
783 this.defaultButton = defaultButton;
786 public void update(DynamicColorContribution colorContribution) {
787 String[] items = variableCombo.getItems();
788 for (int i = 0; i < items.length; i++) {
789 if (colorContribution.getLabel().equals(items[i])) {
790 variableCombo.select(i);
794 minText.setText(Double.toString(colorContribution.getDefaultMin()));
795 maxText.setText(Double.toString(colorContribution.getDefaultMax()));
796 unit.setText(colorContribution.getUnit());
798 String[] colorItems = colorMapCombo.getItems();
799 for (int i = 0; i < colorItems.length; i++) {
801 if (colorContribution.getDefaultColorMap().getLabel().equals(colorItems[i])) {
802 colorMapCombo.select(i);
806 usedButton.setSelection(colorContribution.isUsed());
807 defaultButton.setSelection(colorContribution.isUseDefault());
809 minText.setEnabled(!colorContribution.isUseDefault());
810 maxText.setEnabled(!colorContribution.isUseDefault());
811 colorMapCombo.setEnabled(!colorContribution.isUseDefault());
815 private static class SizingObjectRow {
817 private final Label label;
818 private final Button usedButton;
819 private final Combo variableCombo;
820 private final Text minText;
821 private final Text maxText;
822 private final Label unit;
823 private final Combo sizeMapCombo;
824 private final Button defaultButton;
826 public SizingObjectRow(Label label, Button usedButton, Combo variableCombo, Text minText, Text maxText, Label unit,
827 Combo sizeMapCombo, Button defaultButton) {
830 this.usedButton = usedButton;
831 this.variableCombo = variableCombo;
832 this.minText = minText;
833 this.maxText = maxText;
835 this.sizeMapCombo = sizeMapCombo;
836 this.defaultButton = defaultButton;
839 public void update(DynamicSizeContribution sizeContribution) {
840 String[] items = variableCombo.getItems();
841 for (int i = 0; i < items.length; i++) {
842 if (sizeContribution.getLabel().equals(items[i])) {
843 variableCombo.select(i);
847 minText.setText(Double.toString(sizeContribution.getDefaultMin()));
848 maxText.setText(Double.toString(sizeContribution.getDefaultMax()));
849 unit.setText(sizeContribution.getUnit());
851 String[] sizeItems = sizeMapCombo.getItems();
852 for (int i = 0; i < sizeItems.length; i++) {
853 if (sizeContribution.getDefaultSizeMap().getLabel().equals(sizeItems[i])) {
854 sizeMapCombo.select(i);
858 usedButton.setSelection(sizeContribution.isUsed());
859 defaultButton.setSelection(sizeContribution.isUseDefault());
861 minText.setEnabled(!sizeContribution.isUseDefault());
862 maxText.setEnabled(!sizeContribution.isUseDefault());
863 sizeMapCombo.setEnabled(!sizeContribution.isUseDefault());
867 private static class ArrowObjectRow {
869 private final Label label;
870 private final Button usedButton;
871 private final Combo variableCombo;
872 private final Text gainText;
873 private final Text biasText;
874 private final Button defaultButton;
876 public ArrowObjectRow(Label label, Button usedButton, Combo variableCombo, Text gainText, Text biasText, Button defaultButton) {
878 this.usedButton = usedButton;
879 this.variableCombo = variableCombo;
880 this.gainText = gainText;
881 this.biasText = biasText;
882 this.defaultButton = defaultButton;
885 public void update(DynamicColorContribution colorContribution) {
886 String[] items = variableCombo.getItems();
887 for (int i = 0; i < items.length; i++) {
888 if (colorContribution.getLabel().equals(items[i])) {
889 variableCombo.select(i);
893 gainText.setText(Double.toString(colorContribution.getDefaultMin()));
894 biasText.setText(Double.toString(colorContribution.getDefaultMax()));
896 usedButton.setSelection(colorContribution.isUsed());
897 defaultButton.setSelection(colorContribution.isUseDefault());
899 gainText.setEnabled(!colorContribution.isUseDefault());
900 biasText.setEnabled(!colorContribution.isUseDefault());
904 private Supplier<Pair<String, DynamicColorContribution>> createColoringObjectRow(Composite parent, DynamicColoringObject object, Map<String, DynamicColorMap> colorMaps) {
905 Label label = new Label(parent, SWT.NONE);
906 label.setText(object.getColoringObject().getName());
907 GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(label);
909 Map<String, DynamicColorContribution> colorContributions = object.getColorContributions();
911 Button usedButton = new Button(parent, SWT.CHECK);
912 GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(usedButton);
913 addSelectionListener(usedButton);
915 Combo variableCombo = new Combo(parent, SWT.READ_ONLY);
916 variableCombo.setItems(colorContributions.keySet().toArray(new String[colorContributions.size()]));
918 GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(variableCombo);
920 Text minText = new Text(parent, SWT.BORDER);
921 GridDataFactory.fillDefaults().grab(true, false).hint(150, SWT.DEFAULT).align(SWT.CENTER, SWT.CENTER).applyTo(minText);
922 addSelectionListener(minText);
924 Text maxText = new Text(parent, SWT.BORDER);
925 GridDataFactory.fillDefaults().grab(true, false).hint(150, SWT.DEFAULT).align(SWT.CENTER, SWT.CENTER).applyTo(maxText);
926 addSelectionListener(maxText);
928 Text unit = new Text(parent, SWT.READ_ONLY);
929 GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(unit);
931 Combo colorMapCombo = new Combo(parent, SWT.READ_ONLY);
932 GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(colorMapCombo);
933 colorMapCombo.setItems(colorMaps.keySet().toArray(new String[colorMaps.keySet().size()]));
934 addSelectionListener(colorMapCombo);
936 Button defaultButton = new Button(parent, SWT.CHECK);
937 GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(defaultButton);
938 defaultButton.addSelectionListener(new SelectionAdapter() {
941 public void widgetSelected(SelectionEvent e) {
942 int index = variableCombo.getSelectionIndex();
944 String key = variableCombo.getItem(index);
945 DynamicColorContribution cont = colorContributions.get(key);
947 minText.setText(Double.toString(cont.getDefaultMin()));
948 minText.setEnabled(!defaultButton.getSelection());
949 maxText.setText(Double.toString(cont.getDefaultMax()));
950 maxText.setEnabled(!defaultButton.getSelection());
951 unit.setText(cont.getUnit());
953 String[] items = colorMapCombo.getItems();
954 for (int i = 0; i < items.length; i++) {
955 String item = items[i];
956 if (item.equals(cont.getDefaultColorMap().getLabel())) {
957 colorMapCombo.select(i);
961 colorMapCombo.setEnabled(!defaultButton.getSelection());
965 addSelectionListener(defaultButton);
967 variableCombo.addSelectionListener(new SelectionAdapter() {
970 public void widgetSelected(SelectionEvent e) {
971 // handle update for others
972 int index = variableCombo.getSelectionIndex();
974 String key = variableCombo.getItem(index);
975 DynamicColorContribution cont = colorContributions.get(key);
977 if (minText.getText().isEmpty()) {
978 minText.setText(Double.toString(cont.getDefaultMin()));
980 if (maxText.getText().isEmpty()) {
981 maxText.setText(Double.toString(cont.getDefaultMax()));
983 unit.setText(cont.getUnit());
985 String[] items = colorMapCombo.getItems();
986 for (int i = 0; i < items.length; i++) {
987 String item = items[i];
988 if (item.equals(cont.getDefaultColorMap().getLabel())) {
989 colorMapCombo.select(i);
994 defaultButton.setSelection(true);
998 addSelectionListener(variableCombo);
1000 coloringRows.put(object.getColoringObject().getName(), new ColoringObjectRow(label, usedButton, variableCombo, minText, maxText, unit, colorMapCombo, defaultButton));
1002 return new Supplier<Pair<String, DynamicColorContribution>>() {
1005 public Pair<String, DynamicColorContribution> get() {
1006 int selectionIndex = variableCombo.getSelectionIndex();
1007 if (selectionIndex >= 0) {
1008 String key = variableCombo.getItem(selectionIndex);
1009 DynamicColorContribution cont = colorContributions.get(key);
1012 String label = variableCombo.getItem(variableCombo.getSelectionIndex());
1013 DynamicColorContribution dcc;
1014 if (colorMapCombo.getSelectionIndex() > -1) {
1015 String colorMap = colorMapCombo.getItem(colorMapCombo.getSelectionIndex());
1016 DynamicColorMap dColorMap = colorMaps.get(colorMap);
1017 dcc = new DynamicColorContribution(label, cont.getModuleName(), cont.getAttributeName(), unit.getText(), cont.getVariableGain(), cont.getVariableBias(), dColorMap, Double.parseDouble(minText.getText()), Double.parseDouble(maxText.getText()));
1019 dcc = colorContributions.get(label);
1021 dcc.setUsed(usedButton.getSelection());
1022 dcc.setUseDefault(defaultButton.getSelection());
1024 return Pair.make(object.getColoringObject().getName(), dcc);
1032 private void createSizingObjectHeaderRow(Composite parent) {
1034 Label label = new Label(parent, SWT.NONE);
1035 label.setText("Label");
1036 GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
1038 label = new Label(parent, SWT.NONE);
1039 label.setText("Used");
1040 GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
1042 label = new Label(parent, SWT.NONE);
1043 label.setText("Variable");
1044 GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
1046 label = new Label(parent, SWT.NONE);
1047 label.setText("Min");
1048 GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
1050 label = new Label(parent, SWT.NONE);
1051 label.setText("Max");
1052 GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
1054 label = new Label(parent, SWT.NONE);
1055 label.setText("Unit");
1056 GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
1058 label = new Label(parent, SWT.NONE);
1059 label.setText("SizeMap");
1060 GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
1062 label = new Label(parent, SWT.NONE);
1063 label.setText("Default");
1064 GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
1067 private Supplier<Pair<String, DynamicSizeContribution>> createSizingObjectRow(Composite parent, DynamicSizingObject object, Map<String, DynamicSizeMap> sizeMaps) {
1068 Label label = new Label(parent, SWT.NONE);
1069 label.setText(object.getSizingObject().getName());
1070 GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(label);
1072 Map<String, DynamicSizeContribution> sizeContributions = object.getSizeContributions();
1074 Button usedButton = new Button(parent, SWT.CHECK);
1075 GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(usedButton);
1076 addSelectionListener(usedButton);
1078 Combo variableCombo = new Combo(parent, SWT.READ_ONLY);
1079 variableCombo.setItems(sizeContributions.keySet().toArray(new String[sizeContributions.size()]));
1081 GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(variableCombo);
1083 Text minText = new Text(parent, SWT.BORDER);
1084 GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(minText);
1085 addSelectionListener(minText);
1087 Text maxText = new Text(parent, SWT.BORDER);
1088 GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(maxText);
1089 addSelectionListener(maxText);
1091 Label unit = new Label(parent, SWT.NONE);
1092 GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(unit);
1094 Combo sizeMapCombo = new Combo(parent, SWT.READ_ONLY);
1095 GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(sizeMapCombo);
1096 sizeMapCombo.setItems(sizeMaps.keySet().toArray(new String[sizeMaps.keySet().size()]));
1097 addSelectionListener(sizeMapCombo);
1099 Button defaultButton = new Button(parent, SWT.CHECK);
1100 GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(defaultButton);
1101 defaultButton.addSelectionListener(new SelectionAdapter() {
1104 public void widgetSelected(SelectionEvent e) {
1105 int index = variableCombo.getSelectionIndex();
1107 String key = variableCombo.getItem(index);
1108 DynamicSizeContribution cont = sizeContributions.get(key);
1110 minText.setText(Double.toString(cont.getDefaultMin()));
1111 minText.setEnabled(!defaultButton.getSelection());
1112 maxText.setText(Double.toString(cont.getDefaultMax()));
1113 maxText.setEnabled(!defaultButton.getSelection());
1114 unit.setText(cont.getUnit());
1116 String[] items = sizeMapCombo.getItems();
1117 for (int i = 0; i < items.length; i++) {
1118 String item = items[i];
1119 if (item.equals(cont.getDefaultSizeMap().getLabel())) {
1120 sizeMapCombo.select(i);
1124 sizeMapCombo.setEnabled(!defaultButton.getSelection());
1128 addSelectionListener(defaultButton);
1130 variableCombo.addSelectionListener(new SelectionAdapter() {
1133 public void widgetSelected(SelectionEvent e) {
1134 // handle update for others
1135 String key = variableCombo.getItem(variableCombo.getSelectionIndex());
1136 DynamicSizeContribution cont = sizeContributions.get(key);
1138 if (minText.getText().isEmpty()) {
1139 minText.setText(Double.toString(cont.getDefaultMin()));
1141 if (maxText.getText().isEmpty()) {
1142 maxText.setText(Double.toString(cont.getDefaultMax()));
1144 unit.setText(cont.getUnit());
1146 String[] items = sizeMapCombo.getItems();
1147 for (int i = 0; i < items.length; i++) {
1148 String item = items[i];
1149 if (item.equals(cont.getDefaultSizeMap().getLabel())) {
1150 sizeMapCombo.select(i);
1155 defaultButton.setSelection(true);
1158 addSelectionListener(variableCombo);
1160 sizingRows.put(object.getSizingObject().getName(), new SizingObjectRow(label, usedButton, variableCombo, minText, maxText, unit, sizeMapCombo, defaultButton));
1162 return new Supplier<Pair<String, DynamicSizeContribution>>() {
1165 public Pair<String, DynamicSizeContribution> get() {
1166 int selectionIndex = variableCombo.getSelectionIndex();
1167 if (selectionIndex >= 0) {
1168 String key = variableCombo.getItem(selectionIndex);
1169 DynamicSizeContribution cont = sizeContributions.get(key);
1172 String label = variableCombo.getItem(variableCombo.getSelectionIndex());
1173 DynamicSizeContribution dsc;
1174 if (sizeMapCombo.getSelectionIndex() > -1) {
1175 String sizeMap = sizeMapCombo.getItem(sizeMapCombo.getSelectionIndex());
1176 DynamicSizeMap dSizeMap = sizeMaps.get(sizeMap);
1177 dsc = new DynamicSizeContribution(label, cont.getModuleName(), cont.getAttributeName(), unit.getText(), cont.getVariableGain(), cont.getVariableBias(), dSizeMap, Double.parseDouble(minText.getText()), Double.parseDouble(maxText.getText()));
1179 dsc = sizeContributions.get(label);
1181 dsc.setUsed(usedButton.getSelection());
1182 dsc.setUseDefault(defaultButton.getSelection());
1184 return Pair.make(object.getSizingObject().getName(), dsc);
1192 private void initializeColorBars(Composite parent) {
1193 Group group = new Group(parent, SWT.NONE);
1194 group.setText("Color Bars");
1195 GridDataFactory.fillDefaults().grab(true, false).applyTo(group);
1196 GridLayoutFactory.fillDefaults().numColumns(8).margins(5, 5).applyTo(group);
1198 createColorBars(group);
1201 private void createColorBars(Composite parent) {
1203 showColorButton = new Button(parent, SWT.CHECK);
1204 showColorButton.setText("Show");
1205 addSelectionListener(showColorButton);
1207 colorTicksButton = new Button(parent, SWT.CHECK);
1208 colorTicksButton.setText("Ticks");
1209 addSelectionListener(colorTicksButton);
1211 colorGradientButton = new Button(parent, SWT.CHECK);
1212 colorGradientButton.setText("Gradients");
1213 addSelectionListener(colorGradientButton);
1215 Label label = new Label(parent, SWT.NONE);
1216 label.setText("Location");
1217 colorLocationCombo = new Combo(parent, SWT.READ_ONLY);
1218 String[] colorLocationItems = Stream.of(ColorBarsLocation.values()).map(size -> size.toString()).toArray(String[]::new);
1219 colorLocationCombo.setItems(colorLocationItems);
1220 if (colorLocationItems.length > 0) {
1221 colorLocationCombo.select(0);
1223 addSelectionListener(colorLocationCombo);
1225 label = new Label(parent, SWT.NONE);
1226 label.setText("Size");
1227 colorSizeCombo = new Combo(parent, SWT.READ_ONLY);
1228 String[] colorSizeItems = Stream.of(ColorBarsSize.values()).map(size -> size.toString()).toArray(String[]::new);
1229 colorSizeCombo.setItems(colorSizeItems);
1230 if (colorSizeItems.length > 0) {
1231 colorSizeCombo.select(0);
1233 addSelectionListener(colorSizeCombo);
1236 private void initializeObjectSizes(Composite parent) {
1237 Group group = new Group(parent, SWT.NONE);
1238 group.setText("Object Sizes");
1239 GridDataFactory.fillDefaults().grab(true, false).applyTo(group);
1240 GridLayoutFactory.fillDefaults().numColumns(8).margins(5, 5).applyTo(group);
1243 createSizingObjectHeaderRow(group);
1244 createObjectSizes(group);
1248 private void createObjectSizes(Composite parent) {
1250 sizeSuppliers = new ArrayList<>();
1252 Pair<Collection<DynamicSizingObject>, Map<String, DynamicSizeMap>> resultSizing = Simantics.getSession().syncRequest(new UniqueRead<Pair<Collection<DynamicSizingObject>, Map<String, DynamicSizeMap>>>() {
1255 public Pair<Collection<DynamicSizingObject>, Map<String, DynamicSizeMap>> perform(ReadGraph graph) throws DatabaseException {
1256 Map<String, DynamicSizeMap> dynamicSizeMaps = DynamicVisualisationsContributions.dynamicSizeMaps(graph);
1257 return Pair.make(DynamicVisualisationsContributions.dynamicSizingObjects(graph), dynamicSizeMaps);
1261 for (DynamicSizingObject object : resultSizing.first) {
1262 sizeSuppliers.add(createSizingObjectRow(parent, object, resultSizing.second));
1264 } catch (DatabaseException e) {
1265 LOGGER.error("Could not create object sizes", e);
1269 private void initializeSizeBars(Composite parent) {
1270 Group group = new Group(parent, SWT.NONE);
1271 group.setText("Size Bars");
1272 GridDataFactory.fillDefaults().grab(true, false).applyTo(group);
1273 GridLayoutFactory.fillDefaults().numColumns(8).margins(5, 5).applyTo(group);
1275 createSizeBars(group);
1278 private void createSizeBars(Composite parent) {
1279 showSizeButton = new Button(parent, SWT.CHECK);
1280 showSizeButton.setText("Show");
1281 addSelectionListener(showSizeButton);
1283 sizeTicksButton = new Button(parent, SWT.CHECK);
1284 sizeTicksButton.setText("Ticks");
1285 addSelectionListener(sizeTicksButton);
1287 sizeGradientButton = new Button(parent, SWT.CHECK);
1288 sizeGradientButton.setText("Gradient");
1289 addSelectionListener(sizeGradientButton);
1291 Label label = new Label(parent, SWT.NONE);
1292 label.setText("Location");
1293 sizeLocationCombo = new Combo(parent, SWT.READ_ONLY);
1294 String[] sizeLocationItems = Stream.of(SizeBarsLocation.values()).map(size -> size.toString()).toArray(String[]::new);
1295 sizeLocationCombo.setItems(sizeLocationItems);
1296 if (sizeLocationItems.length > 0) {
1297 sizeLocationCombo.select(0);
1299 addSelectionListener(sizeLocationCombo);
1301 label = new Label(parent, SWT.NONE);
1302 label.setText("Size");
1303 sizeSizeCombo = new Combo(parent, SWT.READ_ONLY);
1304 String[] sizeSizeItems = Stream.of(SizeBarsSize.values()).map(size -> size.toString()).toArray(String[]::new);
1305 sizeSizeCombo.setItems(sizeSizeItems);
1306 if (sizeSizeItems.length > 0) {
1307 sizeSizeCombo.select(0);
1309 addSelectionListener(sizeSizeCombo);
1312 private void addSelectionListener(Widget widget) {
1313 if (widget instanceof Button) {
1314 ((Button) widget).addSelectionListener(new SelectionAdapter() {
1317 public void widgetSelected(SelectionEvent e) {
1318 persistCurrentVisualisationTemplateIfAvailable();
1321 } else if (widget instanceof Combo) {
1322 ((Combo) widget).addSelectionListener(new SelectionAdapter() {
1325 public void widgetSelected(SelectionEvent e) {
1326 persistCurrentVisualisationTemplateIfAvailable();
1329 } else if (widget instanceof Text) {
1330 ((Text) widget).addFocusListener(new FocusAdapter() {
1333 public void focusLost(FocusEvent e) {
1334 persistCurrentVisualisationTemplateIfAvailable();
1337 ((Text) widget).addKeyListener(new KeyAdapter() {
1340 public void keyReleased(KeyEvent e) {
1341 if(e.keyCode == SWT.CR || e.keyCode == SWT.LF) {
1342 persistCurrentVisualisationTemplateIfAvailable();
1349 public void setParentResource(Resource parentResource) {
1350 if (this.parentResource != parentResource) {
1351 this.parentResource = parentResource;
1354 saveVisualisationTemplateAsButton.setEnabled(parentResource != null);
1357 private void updateListening() {
1358 if (visualisationsListener != null)
1359 visualisationsListener.dispose();
1360 if (parentResource != null) {
1361 visualisationsListener = new VisualisationsListener(this);
1362 Simantics.getSession().asyncRequest(new DynamicVisualisationsRequest(parentResource), visualisationsListener);
1365 if (listener != null)
1367 if (parentResource != null) {
1368 listener = new VisualisationListener(this);
1369 Simantics.getSession().asyncRequest(new ActiveDynamicVisualisationsRequest(parentResource), listener);
1373 private static class VisualisationsListener implements Listener<Collection<NamedResource>> {
1375 private static final Logger LOGGER = LoggerFactory.getLogger(VisualisationsListener.class);
1377 private boolean disposed;
1378 private DynamicVisualisationsUI ui;
1380 public VisualisationsListener(DynamicVisualisationsUI ui) {
1385 public void execute(Collection<NamedResource> result) {
1386 ui.updateVisualisations(result);
1390 public void exception(Throwable t) {
1391 LOGGER.error("Could not listen visualisation", t);
1395 public boolean isDisposed() {
1396 return disposed || ui.getParent().isDisposed();
1399 public void dispose() {
1400 this.disposed = true;
1404 private static class VisualisationListener implements Listener<DynamicVisualisation> {
1406 private static final Logger LOGGER = LoggerFactory.getLogger(VisualisationListener.class);
1408 private boolean disposed;
1409 private DynamicVisualisationsUI ui;
1411 public VisualisationListener(DynamicVisualisationsUI ui) {
1416 public void execute(DynamicVisualisation result) {
1417 ui.updateVisualisation(result);
1421 public void exception(Throwable t) {
1422 LOGGER.error("Could not listen visualisation", t);
1426 public boolean isDisposed() {
1427 return disposed ||ui.getParent().isDisposed();
1430 public void dispose() {
1431 this.disposed = true;
1435 public void updateVisualisation(DynamicVisualisation result) {
1436 this.visualisation = result;
1437 Display.getDefault().asyncExec(() -> {
1438 if (getParent().isDisposed())
1441 removeVisualisationTemplateButton.setEnabled(visualisation != null && visualisation.getVisualisationResource() != null);
1443 if (visualisation != null) {
1444 String[] items = templateSelectionCombo.getItems();
1445 for (int i = 0; i < items.length; i++) {
1446 if (visualisation.getName().equals(items[i])) {
1447 templateSelectionCombo.select(i);
1452 intervalText.setText(Long.toString(visualisation.getInterval()));
1453 disableUpdatesButton.setSelection(visualisation.disabledUpdates());
1455 hoveringVertexEnabledButton.setSelection(visualisation.isKeyVariablesVertexHover());
1456 hoveringEdgesEnabledButton.setSelection(visualisation.isKeyVariablesEdgesHover());
1458 Map<String, DynamicColorContribution> colorContributions = visualisation.getColorContributions();
1459 for (Entry<String, DynamicColorContribution> entry : colorContributions.entrySet()) {
1461 ColoringObjectRow coloringObjectRow = coloringRows.get(entry.getKey());
1462 if (coloringObjectRow != null) {
1464 coloringObjectRow.update(entry.getValue());
1467 LOGGER.info("No coloring object visualisation row for key {}", entry.getKey());
1470 ColorBarOptions colorOptions = visualisation.getColorBarOptions();
1471 showColorButton.setSelection(colorOptions.isShowColorBars());
1472 colorTicksButton.setSelection(colorOptions.isShowColorBarsTicks());
1473 colorGradientButton.setSelection(colorOptions.isUseGradients());
1474 for (int i = 0; i < colorLocationCombo.getItems().length; i++) {
1475 String item = colorLocationCombo.getItem(i);
1476 if (item.equals(colorOptions.getLocation().toString())) {
1477 colorLocationCombo.select(i);
1481 for (int i = 0; i < colorSizeCombo.getItems().length; i++) {
1482 String item = colorSizeCombo.getItem(i);
1483 if (item.equals(colorOptions.getSize().toString())) {
1484 colorSizeCombo.select(i);
1489 Map<String, DynamicSizeContribution> sizeContributions = visualisation.getSizeContributions();
1490 for (Entry<String, DynamicSizeContribution> entry : sizeContributions.entrySet()) {
1492 SizingObjectRow sizingObjectRow = sizingRows.get(entry.getKey());
1493 if (sizingObjectRow != null) {
1495 sizingObjectRow.update(entry.getValue());
1498 LOGGER.info("No sizing object visualisation row for key {}", entry.getKey());
1501 SizeBarOptions sizeOptions = visualisation.getSizeBarOptions();
1502 showSizeButton.setSelection(sizeOptions.isShowSizeBars());
1503 sizeTicksButton.setSelection(sizeOptions.isShowSizeBarsTicks());
1504 sizeGradientButton.setSelection(sizeOptions.isUseGradients());
1505 for (int i = 0; i < sizeLocationCombo.getItems().length; i++) {
1506 String item = sizeLocationCombo.getItem(i);
1507 if (item.equals(sizeOptions.getLocation().toString())) {
1508 sizeLocationCombo.select(i);
1512 for (int i = 0; i < sizeSizeCombo.getItems().length; i++) {
1513 String item = sizeSizeCombo.getItem(i);
1514 if (item.equals(sizeOptions.getSize().toString())) {
1515 sizeSizeCombo.select(i);
1523 public void updateVisualisations(Collection<NamedResource> result) {
1524 this.visualisations = result;
1526 Display.getDefault().asyncExec(() -> {
1527 if (getParent().isDisposed())
1529 templateSelectionCombo.setItems(visualisations.stream().map(NamedResource::getName).collect(Collectors.toList()).toArray(new String[visualisations.size()]));
1531 if (visualisation != null) {
1532 String[] items = templateSelectionCombo.getItems();
1533 for (int i = 0; i < items.length; i++) {
1534 if (visualisation.getName().equals(items[i])) {
1535 templateSelectionCombo.select(i);
1544 public Composite getParent() {