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 Simantics.getSession().asyncRequest(new WriteRequest() {
168 public void perform(WriteGraph graph) throws DatabaseException {
169 Resource vf = DynamicVisualisations.getVisualisationFolder(graph, parentResource);
170 DynamicVisualisations.setActiveVisualisation(graph, vf, template.getResource());
179 Composite intervalElementsComposite = new Composite(parent, SWT.NONE);
180 GridDataFactory.fillDefaults().grab(true, false).applyTo(intervalElementsComposite);
181 GridLayoutFactory.fillDefaults().numColumns(1).applyTo(intervalElementsComposite);
182 initializeIntervalElements(intervalElementsComposite);
184 Composite hideElementsComposite = new Composite(parent, SWT.NONE);
185 GridDataFactory.fillDefaults().grab(true, false).applyTo(hideElementsComposite);
186 GridLayoutFactory.fillDefaults().numColumns(1).applyTo(hideElementsComposite);
187 initializeHideElements(hideElementsComposite);
189 Composite staticPropertiesComposite = new Composite(parent, SWT.NONE);
190 GridDataFactory.fillDefaults().grab(true, false).applyTo(staticPropertiesComposite);
191 GridLayoutFactory.fillDefaults().numColumns(1).applyTo(staticPropertiesComposite);
192 initializeStaticProperties(staticPropertiesComposite);
194 Composite dynamicSymbolsComposite = new Composite(parent, SWT.NONE);
195 GridDataFactory.fillDefaults().grab(true, false).applyTo(dynamicSymbolsComposite);
196 GridLayoutFactory.fillDefaults().numColumns(1).applyTo(dynamicSymbolsComposite);
197 initializeDynamicSymbols(dynamicSymbolsComposite);
199 Composite coloringObjectsComposite = new Composite(parent, SWT.NONE);
200 GridDataFactory.fillDefaults().grab(true, false).applyTo(coloringObjectsComposite);
201 GridLayoutFactory.fillDefaults().numColumns(1).applyTo(coloringObjectsComposite);
202 initializeColoringObjects(coloringObjectsComposite);
204 Composite colorBarsComposite = new Composite(parent, SWT.NONE);
205 GridDataFactory.fillDefaults().grab(true, false).applyTo(colorBarsComposite);
206 GridLayoutFactory.fillDefaults().numColumns(1).applyTo(colorBarsComposite);
207 initializeColorBars(colorBarsComposite);
209 Composite objectSizesComposite = new Composite(parent, SWT.NONE);
210 GridDataFactory.fillDefaults().grab(true, false).applyTo(objectSizesComposite);
211 GridLayoutFactory.fillDefaults().numColumns(1).applyTo(objectSizesComposite);
212 initializeObjectSizes(objectSizesComposite);
214 Composite sizeBarsComposite = new Composite(parent, SWT.NONE);
215 GridDataFactory.fillDefaults().grab(true, false).applyTo(sizeBarsComposite);
216 GridLayoutFactory.fillDefaults().numColumns(1).applyTo(sizeBarsComposite);
217 initializeSizeBars(sizeBarsComposite);
219 Composite edgeArrowsComposite = new Composite(parent, SWT.NONE);
220 GridDataFactory.fillDefaults().grab(true, false).applyTo(edgeArrowsComposite);
221 GridLayoutFactory.fillDefaults().numColumns(1).applyTo(edgeArrowsComposite);
222 initializeEdgeArrows(edgeArrowsComposite);
224 Composite buttonBarsComposite = new Composite(parent, SWT.NONE);
225 GridDataFactory.fillDefaults().grab(true, false).applyTo(buttonBarsComposite);
226 GridLayoutFactory.fillDefaults().numColumns(3).applyTo(buttonBarsComposite);
228 saveVisualisationTemplateAsButton = new Button(buttonBarsComposite, SWT.NONE);
229 saveVisualisationTemplateAsButton.setText("Save as visualisation template");
230 saveVisualisationTemplateAsButton.addSelectionListener(new SelectionAdapter() {
233 public void widgetSelected(SelectionEvent e) {
234 showSaveVisualisationTemplateDialog(e.widget.getDisplay().getActiveShell());
238 removeVisualisationTemplateButton = new Button(buttonBarsComposite, SWT.NONE);
239 removeVisualisationTemplateButton.setText("Remove");
240 removeVisualisationTemplateButton.setEnabled(visualisation != null && visualisation.getVisualisationResource() != null);
241 removeVisualisationTemplateButton.addSelectionListener(new SelectionAdapter() {
244 public void widgetSelected(SelectionEvent e) {
245 removeVisualisationTemplate(visualisation.getName(), Optional.of(visualisation.getVisualisationResource()));
250 private void initializeIntervalElements(Composite parent) {
251 Group group = new Group(parent, SWT.NONE);
252 group.setText("Interval");
253 GridDataFactory.fillDefaults().grab(true, false).applyTo(group);
254 GridLayoutFactory.fillDefaults().numColumns(6).margins(5, 5).applyTo(group);
256 createIntervalElements(group);
259 private void createIntervalElements(Composite parent) {
261 Label label = new Label(parent, SWT.NONE);
262 label.setText("Generic");
263 intervalText = new Text(parent, SWT.BORDER);
264 addSelectionListener(intervalText);
266 disableUpdatesButton = new Button(parent, SWT.CHECK);
267 disableUpdatesButton.setText("Disable updates");
268 addSelectionListener(disableUpdatesButton);
270 resetVisualisationButton = new Button(parent, SWT.CHECK);
271 resetVisualisationButton.setText("Reset Visualisation");
272 addSelectionListener(resetVisualisationButton);
274 hoveringVertexEnabledButton = new Button(parent, SWT.CHECK);
275 hoveringVertexEnabledButton.setText("Vertex Key Variables on Hover");
276 addSelectionListener(hoveringVertexEnabledButton);
278 hoveringEdgesEnabledButton = new Button(parent, SWT.CHECK);
279 hoveringEdgesEnabledButton.setText("Edge Key Variables on Hover");
280 addSelectionListener(hoveringEdgesEnabledButton);
283 private void initializeHideElements(Composite parent) {
284 Group group = new Group(parent, SWT.NONE);
285 group.setText("Hide Elements");
286 GridDataFactory.fillDefaults().grab(true, false).applyTo(group);
287 GridLayoutFactory.fillDefaults().numColumns(8).margins(5, 5).applyTo(group);
289 createHideElements(group);
292 private void createHideElements(Composite parent) {
294 hideEdgesButton = new Button(parent, SWT.CHECK);
295 hideEdgesButton.setText("Edges");
296 addSelectionListener(hideEdgesButton);
298 hidePointsButton = new Button(parent, SWT.CHECK);
299 hidePointsButton.setText("Points");
300 addSelectionListener(hidePointsButton);
302 hideConsumersButton = new Button(parent, SWT.CHECK);
303 hideConsumersButton.setText("Consumers");
304 addSelectionListener(hideConsumersButton);
306 hideProducersButton = new Button(parent, SWT.CHECK);
307 hideProducersButton.setText("Producers");
308 addSelectionListener(hideProducersButton);
310 hideValvesButton = new Button(parent, SWT.CHECK);
311 hideValvesButton.setText("Valves");
312 addSelectionListener(hideValvesButton);
314 hidePumpingStationsButton = new Button(parent, SWT.CHECK);
315 hidePumpingStationsButton.setText("Pumping Stations");
316 addSelectionListener(hidePumpingStationsButton);
319 private void initializeStaticProperties(Composite parent) {
320 Group group = new Group(parent, SWT.NONE);
321 group.setText("Static Properties");
322 GridDataFactory.fillDefaults().grab(true, false).applyTo(group);
323 GridLayoutFactory.fillDefaults().numColumns(8).margins(5, 5).applyTo(group);
325 createStaticProperties(group);
328 private void createStaticProperties(Composite parent) {
330 networkBranchesStaticPropertiesButton = new Button(parent, SWT.CHECK);
331 networkBranchesStaticPropertiesButton.setText("Network Branches");
332 addSelectionListener(networkBranchesStaticPropertiesButton);
334 pointsStaticPropertiesButton = new Button(parent, SWT.CHECK);
335 pointsStaticPropertiesButton.setText("Points");
336 addSelectionListener(pointsStaticPropertiesButton);
338 consumersStaticPropertiesButton = new Button(parent, SWT.CHECK);
339 consumersStaticPropertiesButton.setText("Consumers");
340 addSelectionListener(consumersStaticPropertiesButton);
344 private void initializeDynamicSymbols(Composite parent) {
345 Group group = new Group(parent, SWT.NONE);
346 group.setText("Dynamic Symbols");
347 GridDataFactory.fillDefaults().grab(true, false).applyTo(group);
348 GridLayoutFactory.fillDefaults().numColumns(8).margins(5, 5).applyTo(group);
350 createDynamicSymbols(group);
353 private void createDynamicSymbols(Composite parent) {
355 dynamicSymbolsEdgesButton = new Button(parent, SWT.CHECK);
356 dynamicSymbolsEdgesButton.setText("Shutoff Valves in Pipes");
357 addSelectionListener(dynamicSymbolsEdgesButton);
359 dynamicSymbolsProducersButton = new Button(parent, SWT.CHECK);
360 dynamicSymbolsProducersButton.setText("Producers");
361 addSelectionListener(dynamicSymbolsProducersButton);
363 dynamicSymbolsValvesButton = new Button(parent, SWT.CHECK);
364 dynamicSymbolsValvesButton.setText("Valves");
365 addSelectionListener(dynamicSymbolsValvesButton);
367 dynamicSymbolsPumpingStationsButton = new Button(parent, SWT.CHECK);
368 dynamicSymbolsPumpingStationsButton.setText("Pumping Stations");
369 addSelectionListener(dynamicSymbolsPumpingStationsButton);
372 private void initializeEdgeArrows(Composite parent) {
373 Group group = new Group(parent, SWT.NONE);
374 group.setText("Edge Arrows");
375 GridDataFactory.fillDefaults().grab(true, false).applyTo(group);
376 GridLayoutFactory.fillDefaults().numColumns(6).margins(5, 5).applyTo(group);
378 createEdgeArrowsHeaderRow(group);
380 edgeArrowSuppliers = new ArrayList<>();
383 Collection<DynamicArrowObject> result = Simantics.getSession().syncRequest(new UniqueRead<Collection<DynamicArrowObject>>() {
386 public Collection<DynamicArrowObject> perform(ReadGraph graph) throws DatabaseException {
387 return DynamicVisualisationsContributions.dynamicEdgeArrowObjects(graph);
391 for (DynamicArrowObject object : result) {
392 edgeArrowSuppliers.add(createEdgeArrowRow(group, object));
394 } catch (DatabaseException e) {
395 LOGGER.error("Could not create coloring objecst", e);
401 private void createEdgeArrowsHeaderRow(Composite parent) {
403 Label label = new Label(parent, SWT.NONE);
404 label.setText("Label");
405 GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
407 label = new Label(parent, SWT.NONE);
408 label.setText("Used");
409 GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
411 label = new Label(parent, SWT.NONE);
412 label.setText("Variable");
413 GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
415 label = new Label(parent, SWT.NONE);
416 label.setText("Gain");
417 GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
419 label = new Label(parent, SWT.NONE);
420 label.setText("Bias");
421 GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
423 label = new Label(parent, SWT.NONE);
424 label.setText("Default");
425 GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
428 private Supplier<Pair<String, DynamicArrowContribution>> createEdgeArrowRow(Composite parent, DynamicArrowObject object) {
430 Map<String, DynamicArrowContribution> arrowContributions = object.getArrowContributions();
431 if (arrowContributions.isEmpty()) {
432 // ok, no point in showing empty combo boxes
436 Label label = new Label(parent, SWT.NONE);
437 label.setText(object.getArrowObject().getName());
438 GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(label);
440 Button usedButton = new Button(parent, SWT.CHECK);
441 GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(usedButton);
442 addSelectionListener(usedButton);
444 Combo variableCombo = new Combo(parent, SWT.READ_ONLY);
445 variableCombo.setItems(arrowContributions.keySet().toArray(new String[arrowContributions.size()]));
447 GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(variableCombo);
449 Text gainText = new Text(parent, SWT.BORDER);
450 GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(gainText);
451 addSelectionListener(gainText);
453 Text biasText = new Text(parent, SWT.BORDER);
454 GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(biasText);
455 addSelectionListener(biasText);
457 Button defaultButton = new Button(parent, SWT.CHECK);
458 GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(defaultButton);
459 defaultButton.addSelectionListener(new SelectionAdapter() {
462 public void widgetSelected(SelectionEvent e) {
463 int index = variableCombo.getSelectionIndex();
465 String key = variableCombo.getItem(index);
466 DynamicArrowContribution cont = arrowContributions.get(key);
468 gainText.setText(Double.toString(cont.getDefaultGain()));
469 gainText.setEnabled(!defaultButton.getSelection());
470 biasText.setText(Double.toString(cont.getDefaultBias()));
471 biasText.setEnabled(!defaultButton.getSelection());
476 addSelectionListener(defaultButton);
478 variableCombo.addSelectionListener(new SelectionAdapter() {
481 public void widgetSelected(SelectionEvent e) {
482 // handle update for others
483 String key = variableCombo.getItem(variableCombo.getSelectionIndex());
484 DynamicArrowContribution cont = arrowContributions.get(key);
486 if (gainText.getText().isEmpty()) {
487 gainText.setText(Double.toString(cont.getDefaultGain()));
489 if (biasText.getText().isEmpty()) {
490 biasText.setText(Double.toString(cont.getDefaultBias()));
493 defaultButton.setSelection(true);
496 addSelectionListener(variableCombo);
498 arrowRows.put(object.getArrowObject().getName(), new ArrowObjectRow(label, usedButton, variableCombo, gainText, biasText, defaultButton));
500 return new Supplier<Pair<String, DynamicArrowContribution>>() {
503 public Pair<String, DynamicArrowContribution> get() {
504 int selectionIndex = variableCombo.getSelectionIndex();
505 if (selectionIndex >= 0) {
506 String key = variableCombo.getItem(selectionIndex);
507 DynamicArrowContribution cont = arrowContributions.get(key);
509 String label = variableCombo.getItem(variableCombo.getSelectionIndex());
511 double gain = cont.getDefaultGain();
512 String gainS = gainText.getText();
513 if (gainS != null && !gainS.isEmpty()) {
514 gain = Double.parseDouble(gainS);
516 double bias = cont.getDefaultBias();
517 String biasS = biasText.getText();
518 if (biasS != null && !biasS.isEmpty()) {
519 bias = Double.parseDouble(biasText.getText());
522 DynamicArrowContribution dsc = new DynamicArrowContribution(label, cont.getModuleName(), cont.getAttributeName(), gain, bias);
523 dsc.setUsed(usedButton.getSelection());
524 dsc.setUseDefault(defaultButton.getSelection());
526 return Pair.make(object.getArrowObject().getName(), dsc);
534 protected void removeVisualisationTemplate(String name, Optional<Resource> of) {
535 if (of.isPresent()) {
536 Resource visualisation = of.get();
537 Simantics.getSession().asyncRequest(new WriteRequest() {
540 public void perform(WriteGraph graph) throws DatabaseException {
541 RemoverUtil.remove(graph, visualisation);
547 private void showSaveVisualisationTemplateDialog(Shell shell) {
549 InputDialog dialog = new InputDialog(shell, "Save visualisation template", "Give template a name", "", new IInputValidator() {
552 public String isValid(String newText) {
553 if (newText == null || newText.isEmpty())
554 return "Name cannot be empty";
559 if (dialog.open() == Dialog.OK) {
560 String name = dialog.getValue();
562 persistVisualisationTemplate(name, Optional.empty());
563 } catch (Exception e) {
564 LOGGER.error("Could not persist visualisation template", e);
565 ShowError.showError("Could not persist visualisation template", e.getMessage(), e);
570 private void persistCurrentVisualisationTemplateIfAvailable() {
571 if (visualisation != null) {
573 persistVisualisationTemplate(visualisation.getName(), Optional.of(visualisation.getVisualisationResource()));
574 } catch (Exception e1) {
575 LOGGER.error("Could not persist visualisation template", e1);
576 ShowError.showError("Could not persist visualisation template", e1.getMessage(), e1);
579 LOGGER.info("No current visualisation template selected for saving");
583 private void persistVisualisationTemplate(String templateName, Optional<Resource> existing) throws Exception {
585 List<Pair<String, DynamicColorContribution>> colorCollect = colorSuppliers.stream().filter(Objects::nonNull).map(s -> s.get()).filter(Objects::nonNull).collect(Collectors.toList());
587 String colorLocation = colorLocationCombo.getItem(colorLocationCombo.getSelectionIndex());
588 String colorSize = colorSizeCombo.getItem(colorSizeCombo.getSelectionIndex());
590 ColorBarOptions colorBarOptions = new ColorBarOptions()
591 .showColorBars(showColorButton.getSelection())
592 .showColorBarsTicks(colorTicksButton.getSelection())
593 .useGradients(colorGradientButton.getSelection())
594 .withLocation(ColorBarsLocation.valueOf(colorLocation))
595 .withSize(ColorBarsSize.valueOf(colorSize));
597 List<Pair<String, DynamicSizeContribution>> sizeCollect = sizeSuppliers.stream().filter(Objects::nonNull).map(s -> s.get()).filter(Objects::nonNull).collect(Collectors.toList());
599 String sizeLocation = sizeLocationCombo.getItem(sizeLocationCombo.getSelectionIndex());
600 String sizeSize = sizeSizeCombo.getItem(sizeSizeCombo.getSelectionIndex());
602 final SizeBarOptions sizeBarOptions = new SizeBarOptions()
603 .showSizeBars(showSizeButton.getSelection())
604 .showSizeBarsTicks(sizeTicksButton.getSelection())
605 .useGradients(sizeGradientButton.getSelection())
606 .withLocation(SizeBarsLocation.valueOf(sizeLocation))
607 .withSize(SizeBarsSize.valueOf(sizeSize));
609 List<Pair<String, DynamicArrowContribution>> edgeArrowCollect = edgeArrowSuppliers.stream().filter(Objects::nonNull).map(s -> s.get()).filter(Objects::nonNull).collect(Collectors.toList());
611 boolean hideEdges = hideEdgesButton.getSelection();
612 boolean hidePoints = hidePointsButton.getSelection();
613 boolean hideConsumers = hideConsumersButton.getSelection();
614 boolean hideProducers = hideProducersButton.getSelection();
615 boolean hideValves = hideValvesButton.getSelection();
616 boolean hidePumpingStations = hidePumpingStationsButton.getSelection();
618 boolean networkBranchesStaticProperties = networkBranchesStaticPropertiesButton.getSelection();
619 boolean pointsStaticProperties = pointsStaticPropertiesButton.getSelection();
620 boolean consumersStaticProperties = consumersStaticPropertiesButton.getSelection();
622 boolean dynamicSymbolsEdges = dynamicSymbolsEdgesButton.getSelection();
623 boolean dynamicSymbolsProducers = dynamicSymbolsProducersButton.getSelection();
624 boolean dynamicSymbolsValves = dynamicSymbolsValvesButton.getSelection();
625 boolean dynamicSymbolsPumpingStations = dynamicSymbolsPumpingStationsButton.getSelection();
627 boolean disabled = disableUpdatesButton.getSelection();
628 boolean resetVisualisation = resetVisualisationButton.getSelection();
631 interval = Long.parseLong(intervalText.getText());
632 } catch (NumberFormatException e) {
636 final long finalInterval = interval;
638 boolean hoverVertex = hoveringVertexEnabledButton.getSelection();
639 boolean hoverEdges = hoveringEdgesEnabledButton.getSelection();
641 Simantics.getSession().asyncRequest(new WriteRequest() {
644 public void perform(WriteGraph graph) throws DatabaseException {
646 if (existing.isPresent()) {
647 exist = existing.get();
649 exist = DynamicVisualisations.createVisualisation(graph, parentResource, templateName);
651 DynamicVisualisations.setIntervalAndDisabled(graph, exist, finalInterval, disabled, resetVisualisation);
652 DynamicVisualisations.setColorContributions(graph, exist, colorCollect);
653 DynamicVisualisations.setColorBarOptions(graph, exist, colorBarOptions);
654 DynamicVisualisations.setSizeContributions(graph, exist, sizeCollect);
655 DynamicVisualisations.setSizeBarOptions(graph, exist, sizeBarOptions);
656 DynamicVisualisations.setEdgeArrowContributions(graph, exist, edgeArrowCollect);
657 DynamicVisualisations.setHideElements(graph, exist,
666 DynamicVisualisations.setStaticProperties(graph, exist,
667 networkBranchesStaticProperties,
668 pointsStaticProperties,
669 consumersStaticProperties
672 DynamicVisualisations.setDynamicSymbols(graph, exist,
674 dynamicSymbolsProducers,
675 dynamicSymbolsValves,
676 dynamicSymbolsPumpingStations
678 DynamicVisualisations.setKeyVariablesHover(graph, exist, hoverVertex, hoverEdges);
683 private void initializeColoringObjects(Composite parent) {
684 Group group = new Group(parent, SWT.NONE);
685 group.setText("Coloring Objects");
686 GridDataFactory.fillDefaults().grab(true, false).applyTo(group);
687 GridLayoutFactory.fillDefaults().numColumns(8).margins(5, 5).applyTo(group);
690 createColoringObjectHeaderRow(group);
692 colorSuppliers = new ArrayList<>();
695 Pair<Collection<DynamicColoringObject>, Map<String, DynamicColorMap>> result = Simantics.getSession().syncRequest(new UniqueRead<Pair<Collection<DynamicColoringObject>, Map<String, DynamicColorMap>>>() {
698 public Pair<Collection<DynamicColoringObject>, Map<String, DynamicColorMap>> perform(ReadGraph graph) throws DatabaseException {
699 Map<String, DynamicColorMap> dynamicColorMaps = DynamicVisualisationsContributions.dynamicColorMaps(graph);
700 return Pair.make(DynamicVisualisationsContributions.dynamicColoringObjects(graph), dynamicColorMaps);
704 for (DynamicColoringObject object : result.first) {
705 colorSuppliers.add(createColoringObjectRow(group, object, result.second));
708 } catch (DatabaseException e) {
709 LOGGER.error("Could not create coloring objecst", e);
714 private void createColoringObjectHeaderRow(Composite parent) {
716 Label label = new Label(parent, SWT.NONE);
717 label.setText("Label");
718 GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
720 label = new Label(parent, SWT.NONE);
721 label.setText("Used");
722 GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
724 label = new Label(parent, SWT.NONE);
725 label.setText("Variable");
726 GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
728 label = new Label(parent, SWT.NONE);
729 label.setText("Min");
730 GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
732 label = new Label(parent, SWT.NONE);
733 label.setText("Max");
734 GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
736 label = new Label(parent, SWT.NONE);
737 label.setText("Unit");
738 GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
740 label = new Label(parent, SWT.NONE);
741 label.setText("ColorMap");
742 GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
744 label = new Label(parent, SWT.NONE);
745 label.setText("Default");
746 GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
749 private Map<String, ColoringObjectRow> coloringRows = new HashMap<>();
750 private Map<String, SizingObjectRow> sizingRows = new HashMap<>();
751 private Map<String, ArrowObjectRow> arrowRows = new HashMap<>();
753 private VisualisationsListener visualisationsListener;
755 private Collection<NamedResource> visualisations;
757 private List<Supplier<Pair<String, DynamicSizeContribution>>> sizeSuppliers;
759 private static class ColoringObjectRow {
761 private final Label label;
762 private final Button usedButton;
763 private final Combo variableCombo;
764 private final Text minText;
765 private final Text maxText;
766 private final Text unit;
767 private final Combo colorMapCombo;
768 private final Button defaultButton;
770 public ColoringObjectRow(Label label, Button usedButton, Combo variableCombo, Text minText, Text maxText, Text unit,
771 Combo colorMapCombo, Button defaultButton) {
774 this.usedButton = usedButton;
775 this.variableCombo = variableCombo;
776 this.minText = minText;
777 this.maxText = maxText;
779 this.colorMapCombo = colorMapCombo;
780 this.defaultButton = defaultButton;
783 public void update(DynamicColorContribution colorContribution) {
784 String[] items = variableCombo.getItems();
785 for (int i = 0; i < items.length; i++) {
786 if (colorContribution.getLabel().equals(items[i])) {
787 variableCombo.select(i);
791 minText.setText(Double.toString(colorContribution.getDefaultMin()));
792 maxText.setText(Double.toString(colorContribution.getDefaultMax()));
793 unit.setText(colorContribution.getUnit());
795 String[] colorItems = colorMapCombo.getItems();
796 for (int i = 0; i < colorItems.length; i++) {
798 if (colorContribution.getDefaultColorMap().getLabel().equals(colorItems[i])) {
799 colorMapCombo.select(i);
803 usedButton.setSelection(colorContribution.isUsed());
804 defaultButton.setSelection(colorContribution.isUseDefault());
806 minText.setEnabled(!colorContribution.isUseDefault());
807 maxText.setEnabled(!colorContribution.isUseDefault());
808 colorMapCombo.setEnabled(!colorContribution.isUseDefault());
812 private static class SizingObjectRow {
814 private final Label label;
815 private final Button usedButton;
816 private final Combo variableCombo;
817 private final Text minText;
818 private final Text maxText;
819 private final Label unit;
820 private final Combo sizeMapCombo;
821 private final Button defaultButton;
823 public SizingObjectRow(Label label, Button usedButton, Combo variableCombo, Text minText, Text maxText, Label unit,
824 Combo sizeMapCombo, Button defaultButton) {
827 this.usedButton = usedButton;
828 this.variableCombo = variableCombo;
829 this.minText = minText;
830 this.maxText = maxText;
832 this.sizeMapCombo = sizeMapCombo;
833 this.defaultButton = defaultButton;
836 public void update(DynamicSizeContribution sizeContribution) {
837 String[] items = variableCombo.getItems();
838 for (int i = 0; i < items.length; i++) {
839 if (sizeContribution.getLabel().equals(items[i])) {
840 variableCombo.select(i);
844 minText.setText(Double.toString(sizeContribution.getDefaultMin()));
845 maxText.setText(Double.toString(sizeContribution.getDefaultMax()));
846 unit.setText(sizeContribution.getUnit());
848 String[] sizeItems = sizeMapCombo.getItems();
849 for (int i = 0; i < sizeItems.length; i++) {
850 if (sizeContribution.getDefaultSizeMap().getLabel().equals(sizeItems[i])) {
851 sizeMapCombo.select(i);
855 usedButton.setSelection(sizeContribution.isUsed());
856 defaultButton.setSelection(sizeContribution.isUseDefault());
858 minText.setEnabled(!sizeContribution.isUseDefault());
859 maxText.setEnabled(!sizeContribution.isUseDefault());
860 sizeMapCombo.setEnabled(!sizeContribution.isUseDefault());
864 private static class ArrowObjectRow {
866 private final Label label;
867 private final Button usedButton;
868 private final Combo variableCombo;
869 private final Text gainText;
870 private final Text biasText;
871 private final Button defaultButton;
873 public ArrowObjectRow(Label label, Button usedButton, Combo variableCombo, Text gainText, Text biasText, Button defaultButton) {
875 this.usedButton = usedButton;
876 this.variableCombo = variableCombo;
877 this.gainText = gainText;
878 this.biasText = biasText;
879 this.defaultButton = defaultButton;
882 public void update(DynamicColorContribution colorContribution) {
883 String[] items = variableCombo.getItems();
884 for (int i = 0; i < items.length; i++) {
885 if (colorContribution.getLabel().equals(items[i])) {
886 variableCombo.select(i);
890 gainText.setText(Double.toString(colorContribution.getDefaultMin()));
891 biasText.setText(Double.toString(colorContribution.getDefaultMax()));
893 usedButton.setSelection(colorContribution.isUsed());
894 defaultButton.setSelection(colorContribution.isUseDefault());
896 gainText.setEnabled(!colorContribution.isUseDefault());
897 biasText.setEnabled(!colorContribution.isUseDefault());
901 private Supplier<Pair<String, DynamicColorContribution>> createColoringObjectRow(Composite parent, DynamicColoringObject object, Map<String, DynamicColorMap> colorMaps) {
902 Label label = new Label(parent, SWT.NONE);
903 label.setText(object.getColoringObject().getName());
904 GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(label);
906 Map<String, DynamicColorContribution> colorContributions = object.getColorContributions();
908 Button usedButton = new Button(parent, SWT.CHECK);
909 GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(usedButton);
910 addSelectionListener(usedButton);
912 Combo variableCombo = new Combo(parent, SWT.READ_ONLY);
913 variableCombo.setItems(colorContributions.keySet().toArray(new String[colorContributions.size()]));
915 GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(variableCombo);
917 Text minText = new Text(parent, SWT.BORDER);
918 GridDataFactory.fillDefaults().grab(true, false).hint(150, SWT.DEFAULT).align(SWT.CENTER, SWT.CENTER).applyTo(minText);
919 addSelectionListener(minText);
921 Text maxText = new Text(parent, SWT.BORDER);
922 GridDataFactory.fillDefaults().grab(true, false).hint(150, SWT.DEFAULT).align(SWT.CENTER, SWT.CENTER).applyTo(maxText);
923 addSelectionListener(maxText);
925 Text unit = new Text(parent, SWT.READ_ONLY);
926 GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(unit);
928 Combo colorMapCombo = new Combo(parent, SWT.READ_ONLY);
929 GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(colorMapCombo);
930 colorMapCombo.setItems(colorMaps.keySet().toArray(new String[colorMaps.keySet().size()]));
931 addSelectionListener(colorMapCombo);
933 Button defaultButton = new Button(parent, SWT.CHECK);
934 GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(defaultButton);
935 defaultButton.addSelectionListener(new SelectionAdapter() {
938 public void widgetSelected(SelectionEvent e) {
939 int index = variableCombo.getSelectionIndex();
941 String key = variableCombo.getItem(index);
942 DynamicColorContribution cont = colorContributions.get(key);
944 minText.setText(Double.toString(cont.getDefaultMin()));
945 minText.setEnabled(!defaultButton.getSelection());
946 maxText.setText(Double.toString(cont.getDefaultMax()));
947 maxText.setEnabled(!defaultButton.getSelection());
948 unit.setText(cont.getUnit());
950 String[] items = colorMapCombo.getItems();
951 for (int i = 0; i < items.length; i++) {
952 String item = items[i];
953 if (item.equals(cont.getDefaultColorMap().getLabel())) {
954 colorMapCombo.select(i);
958 colorMapCombo.setEnabled(!defaultButton.getSelection());
962 addSelectionListener(defaultButton);
964 variableCombo.addSelectionListener(new SelectionAdapter() {
967 public void widgetSelected(SelectionEvent e) {
968 // handle update for others
969 int index = variableCombo.getSelectionIndex();
971 String key = variableCombo.getItem(index);
972 DynamicColorContribution cont = colorContributions.get(key);
974 if (minText.getText().isEmpty()) {
975 minText.setText(Double.toString(cont.getDefaultMin()));
977 if (maxText.getText().isEmpty()) {
978 maxText.setText(Double.toString(cont.getDefaultMax()));
980 unit.setText(cont.getUnit());
982 String[] items = colorMapCombo.getItems();
983 for (int i = 0; i < items.length; i++) {
984 String item = items[i];
985 if (item.equals(cont.getDefaultColorMap().getLabel())) {
986 colorMapCombo.select(i);
991 defaultButton.setSelection(true);
995 addSelectionListener(variableCombo);
997 coloringRows.put(object.getColoringObject().getName(), new ColoringObjectRow(label, usedButton, variableCombo, minText, maxText, unit, colorMapCombo, defaultButton));
999 return new Supplier<Pair<String, DynamicColorContribution>>() {
1002 public Pair<String, DynamicColorContribution> get() {
1003 int selectionIndex = variableCombo.getSelectionIndex();
1004 if (selectionIndex >= 0) {
1005 String key = variableCombo.getItem(selectionIndex);
1006 DynamicColorContribution cont = colorContributions.get(key);
1009 String label = variableCombo.getItem(variableCombo.getSelectionIndex());
1010 DynamicColorContribution dcc;
1011 if (colorMapCombo.getSelectionIndex() > -1) {
1012 String colorMap = colorMapCombo.getItem(colorMapCombo.getSelectionIndex());
1013 DynamicColorMap dColorMap = colorMaps.get(colorMap);
1014 dcc = new DynamicColorContribution(label, cont.getModuleName(), cont.getAttributeName(), unit.getText(), cont.getVariableGain(), cont.getVariableBias(), dColorMap, Double.parseDouble(minText.getText()), Double.parseDouble(maxText.getText()));
1016 dcc = colorContributions.get(label);
1018 dcc.setUsed(usedButton.getSelection());
1019 dcc.setUseDefault(defaultButton.getSelection());
1021 return Pair.make(object.getColoringObject().getName(), dcc);
1029 private void createSizingObjectHeaderRow(Composite parent) {
1031 Label label = new Label(parent, SWT.NONE);
1032 label.setText("Label");
1033 GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
1035 label = new Label(parent, SWT.NONE);
1036 label.setText("Used");
1037 GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
1039 label = new Label(parent, SWT.NONE);
1040 label.setText("Variable");
1041 GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
1043 label = new Label(parent, SWT.NONE);
1044 label.setText("Min");
1045 GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
1047 label = new Label(parent, SWT.NONE);
1048 label.setText("Max");
1049 GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
1051 label = new Label(parent, SWT.NONE);
1052 label.setText("Unit");
1053 GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
1055 label = new Label(parent, SWT.NONE);
1056 label.setText("SizeMap");
1057 GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
1059 label = new Label(parent, SWT.NONE);
1060 label.setText("Default");
1061 GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
1064 private Supplier<Pair<String, DynamicSizeContribution>> createSizingObjectRow(Composite parent, DynamicSizingObject object, Map<String, DynamicSizeMap> sizeMaps) {
1065 Label label = new Label(parent, SWT.NONE);
1066 label.setText(object.getSizingObject().getName());
1067 GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(label);
1069 Map<String, DynamicSizeContribution> sizeContributions = object.getSizeContributions();
1071 Button usedButton = new Button(parent, SWT.CHECK);
1072 GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(usedButton);
1073 addSelectionListener(usedButton);
1075 Combo variableCombo = new Combo(parent, SWT.READ_ONLY);
1076 variableCombo.setItems(sizeContributions.keySet().toArray(new String[sizeContributions.size()]));
1078 GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(variableCombo);
1080 Text minText = new Text(parent, SWT.BORDER);
1081 GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(minText);
1082 addSelectionListener(minText);
1084 Text maxText = new Text(parent, SWT.BORDER);
1085 GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(maxText);
1086 addSelectionListener(maxText);
1088 Label unit = new Label(parent, SWT.NONE);
1089 GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(unit);
1091 Combo sizeMapCombo = new Combo(parent, SWT.READ_ONLY);
1092 GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(sizeMapCombo);
1093 sizeMapCombo.setItems(sizeMaps.keySet().toArray(new String[sizeMaps.keySet().size()]));
1094 addSelectionListener(sizeMapCombo);
1096 Button defaultButton = new Button(parent, SWT.CHECK);
1097 GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(defaultButton);
1098 defaultButton.addSelectionListener(new SelectionAdapter() {
1101 public void widgetSelected(SelectionEvent e) {
1102 int index = variableCombo.getSelectionIndex();
1104 String key = variableCombo.getItem(index);
1105 DynamicSizeContribution cont = sizeContributions.get(key);
1107 minText.setText(Double.toString(cont.getDefaultMin()));
1108 minText.setEnabled(!defaultButton.getSelection());
1109 maxText.setText(Double.toString(cont.getDefaultMax()));
1110 maxText.setEnabled(!defaultButton.getSelection());
1111 unit.setText(cont.getUnit());
1113 String[] items = sizeMapCombo.getItems();
1114 for (int i = 0; i < items.length; i++) {
1115 String item = items[i];
1116 if (item.equals(cont.getDefaultSizeMap().getLabel())) {
1117 sizeMapCombo.select(i);
1121 sizeMapCombo.setEnabled(!defaultButton.getSelection());
1125 addSelectionListener(defaultButton);
1127 variableCombo.addSelectionListener(new SelectionAdapter() {
1130 public void widgetSelected(SelectionEvent e) {
1131 // handle update for others
1132 String key = variableCombo.getItem(variableCombo.getSelectionIndex());
1133 DynamicSizeContribution cont = sizeContributions.get(key);
1135 if (minText.getText().isEmpty()) {
1136 minText.setText(Double.toString(cont.getDefaultMin()));
1138 if (maxText.getText().isEmpty()) {
1139 maxText.setText(Double.toString(cont.getDefaultMax()));
1141 unit.setText(cont.getUnit());
1143 String[] items = sizeMapCombo.getItems();
1144 for (int i = 0; i < items.length; i++) {
1145 String item = items[i];
1146 if (item.equals(cont.getDefaultSizeMap().getLabel())) {
1147 sizeMapCombo.select(i);
1152 defaultButton.setSelection(true);
1155 addSelectionListener(variableCombo);
1157 sizingRows.put(object.getSizingObject().getName(), new SizingObjectRow(label, usedButton, variableCombo, minText, maxText, unit, sizeMapCombo, defaultButton));
1159 return new Supplier<Pair<String, DynamicSizeContribution>>() {
1162 public Pair<String, DynamicSizeContribution> get() {
1163 int selectionIndex = variableCombo.getSelectionIndex();
1164 if (selectionIndex >= 0) {
1165 String key = variableCombo.getItem(selectionIndex);
1166 DynamicSizeContribution cont = sizeContributions.get(key);
1169 String label = variableCombo.getItem(variableCombo.getSelectionIndex());
1170 DynamicSizeContribution dsc;
1171 if (sizeMapCombo.getSelectionIndex() > -1) {
1172 String sizeMap = sizeMapCombo.getItem(sizeMapCombo.getSelectionIndex());
1173 DynamicSizeMap dSizeMap = sizeMaps.get(sizeMap);
1174 dsc = new DynamicSizeContribution(label, cont.getModuleName(), cont.getAttributeName(), unit.getText(), cont.getVariableGain(), cont.getVariableBias(), dSizeMap, Double.parseDouble(minText.getText()), Double.parseDouble(maxText.getText()));
1176 dsc = sizeContributions.get(label);
1178 dsc.setUsed(usedButton.getSelection());
1179 dsc.setUseDefault(defaultButton.getSelection());
1181 return Pair.make(object.getSizingObject().getName(), dsc);
1189 private void initializeColorBars(Composite parent) {
1190 Group group = new Group(parent, SWT.NONE);
1191 group.setText("Color Bars");
1192 GridDataFactory.fillDefaults().grab(true, false).applyTo(group);
1193 GridLayoutFactory.fillDefaults().numColumns(8).margins(5, 5).applyTo(group);
1195 createColorBars(group);
1198 private void createColorBars(Composite parent) {
1200 showColorButton = new Button(parent, SWT.CHECK);
1201 showColorButton.setText("Show");
1202 addSelectionListener(showColorButton);
1204 colorTicksButton = new Button(parent, SWT.CHECK);
1205 colorTicksButton.setText("Ticks");
1206 addSelectionListener(colorTicksButton);
1208 colorGradientButton = new Button(parent, SWT.CHECK);
1209 colorGradientButton.setText("Gradients");
1210 addSelectionListener(colorGradientButton);
1212 Label label = new Label(parent, SWT.NONE);
1213 label.setText("Location");
1214 colorLocationCombo = new Combo(parent, SWT.READ_ONLY);
1215 String[] colorLocationItems = Stream.of(ColorBarsLocation.values()).map(size -> size.toString()).toArray(String[]::new);
1216 colorLocationCombo.setItems(colorLocationItems);
1217 if (colorLocationItems.length > 0) {
1218 colorLocationCombo.select(0);
1220 addSelectionListener(colorLocationCombo);
1222 label = new Label(parent, SWT.NONE);
1223 label.setText("Size");
1224 colorSizeCombo = new Combo(parent, SWT.READ_ONLY);
1225 String[] colorSizeItems = Stream.of(ColorBarsSize.values()).map(size -> size.toString()).toArray(String[]::new);
1226 colorSizeCombo.setItems(colorSizeItems);
1227 if (colorSizeItems.length > 0) {
1228 colorSizeCombo.select(0);
1230 addSelectionListener(colorSizeCombo);
1233 private void initializeObjectSizes(Composite parent) {
1234 Group group = new Group(parent, SWT.NONE);
1235 group.setText("Object Sizes");
1236 GridDataFactory.fillDefaults().grab(true, false).applyTo(group);
1237 GridLayoutFactory.fillDefaults().numColumns(8).margins(5, 5).applyTo(group);
1240 createSizingObjectHeaderRow(group);
1241 createObjectSizes(group);
1245 private void createObjectSizes(Composite parent) {
1247 sizeSuppliers = new ArrayList<>();
1249 Pair<Collection<DynamicSizingObject>, Map<String, DynamicSizeMap>> resultSizing = Simantics.getSession().syncRequest(new UniqueRead<Pair<Collection<DynamicSizingObject>, Map<String, DynamicSizeMap>>>() {
1252 public Pair<Collection<DynamicSizingObject>, Map<String, DynamicSizeMap>> perform(ReadGraph graph) throws DatabaseException {
1253 Map<String, DynamicSizeMap> dynamicSizeMaps = DynamicVisualisationsContributions.dynamicSizeMaps(graph);
1254 return Pair.make(DynamicVisualisationsContributions.dynamicSizingObjects(graph), dynamicSizeMaps);
1258 for (DynamicSizingObject object : resultSizing.first) {
1259 sizeSuppliers.add(createSizingObjectRow(parent, object, resultSizing.second));
1261 } catch (DatabaseException e) {
1262 LOGGER.error("Could not create object sizes", e);
1266 private void initializeSizeBars(Composite parent) {
1267 Group group = new Group(parent, SWT.NONE);
1268 group.setText("Size Bars");
1269 GridDataFactory.fillDefaults().grab(true, false).applyTo(group);
1270 GridLayoutFactory.fillDefaults().numColumns(8).margins(5, 5).applyTo(group);
1272 createSizeBars(group);
1275 private void createSizeBars(Composite parent) {
1276 showSizeButton = new Button(parent, SWT.CHECK);
1277 showSizeButton.setText("Show");
1278 addSelectionListener(showSizeButton);
1280 sizeTicksButton = new Button(parent, SWT.CHECK);
1281 sizeTicksButton.setText("Ticks");
1282 addSelectionListener(sizeTicksButton);
1284 sizeGradientButton = new Button(parent, SWT.CHECK);
1285 sizeGradientButton.setText("Gradient");
1286 addSelectionListener(sizeGradientButton);
1288 Label label = new Label(parent, SWT.NONE);
1289 label.setText("Location");
1290 sizeLocationCombo = new Combo(parent, SWT.READ_ONLY);
1291 String[] sizeLocationItems = Stream.of(SizeBarsLocation.values()).map(size -> size.toString()).toArray(String[]::new);
1292 sizeLocationCombo.setItems(sizeLocationItems);
1293 if (sizeLocationItems.length > 0) {
1294 sizeLocationCombo.select(0);
1296 addSelectionListener(sizeLocationCombo);
1298 label = new Label(parent, SWT.NONE);
1299 label.setText("Size");
1300 sizeSizeCombo = new Combo(parent, SWT.READ_ONLY);
1301 String[] sizeSizeItems = Stream.of(SizeBarsSize.values()).map(size -> size.toString()).toArray(String[]::new);
1302 sizeSizeCombo.setItems(sizeSizeItems);
1303 if (sizeSizeItems.length > 0) {
1304 sizeSizeCombo.select(0);
1306 addSelectionListener(sizeSizeCombo);
1309 private void addSelectionListener(Widget widget) {
1310 if (widget instanceof Button) {
1311 ((Button) widget).addSelectionListener(new SelectionAdapter() {
1314 public void widgetSelected(SelectionEvent e) {
1315 persistCurrentVisualisationTemplateIfAvailable();
1318 } else if (widget instanceof Combo) {
1319 ((Combo) widget).addSelectionListener(new SelectionAdapter() {
1322 public void widgetSelected(SelectionEvent e) {
1323 persistCurrentVisualisationTemplateIfAvailable();
1326 } else if (widget instanceof Text) {
1327 ((Text) widget).addFocusListener(new FocusAdapter() {
1330 public void focusLost(FocusEvent e) {
1331 persistCurrentVisualisationTemplateIfAvailable();
1334 ((Text) widget).addKeyListener(new KeyAdapter() {
1337 public void keyReleased(KeyEvent e) {
1338 if(e.keyCode == SWT.CR || e.keyCode == SWT.LF) {
1339 persistCurrentVisualisationTemplateIfAvailable();
1346 public void setParentResource(Resource parentResource) {
1347 if (this.parentResource != parentResource) {
1348 this.parentResource = parentResource;
1351 saveVisualisationTemplateAsButton.setEnabled(parentResource != null);
1354 private void updateListening() {
1355 if (visualisationsListener != null)
1356 visualisationsListener.dispose();
1357 visualisationsListener = new VisualisationsListener(this);
1358 Simantics.getSession().asyncRequest(new DynamicVisualisationsRequest(parentResource), visualisationsListener);
1360 if (listener != null)
1362 listener = new VisualisationListener(this);
1363 Simantics.getSession().asyncRequest(new ActiveDynamicVisualisationsRequest(parentResource), listener);
1366 private static class VisualisationsListener implements Listener<Collection<NamedResource>> {
1368 private static final Logger LOGGER = LoggerFactory.getLogger(VisualisationsListener.class);
1370 private boolean disposed;
1371 private DynamicVisualisationsUI ui;
1373 public VisualisationsListener(DynamicVisualisationsUI ui) {
1378 public void execute(Collection<NamedResource> result) {
1379 ui.updateVisualisations(result);
1383 public void exception(Throwable t) {
1384 LOGGER.error("Could not listen visualisation", t);
1388 public boolean isDisposed() {
1389 return disposed || ui.getParent().isDisposed();
1392 public void dispose() {
1393 this.disposed = true;
1397 private static class VisualisationListener implements Listener<DynamicVisualisation> {
1399 private static final Logger LOGGER = LoggerFactory.getLogger(VisualisationListener.class);
1401 private boolean disposed;
1402 private DynamicVisualisationsUI ui;
1404 public VisualisationListener(DynamicVisualisationsUI ui) {
1409 public void execute(DynamicVisualisation result) {
1410 ui.updateVisualisation(result);
1414 public void exception(Throwable t) {
1415 LOGGER.error("Could not listen visualisation", t);
1419 public boolean isDisposed() {
1420 return disposed ||ui.getParent().isDisposed();
1423 public void dispose() {
1424 this.disposed = true;
1428 public void updateVisualisation(DynamicVisualisation result) {
1429 this.visualisation = result;
1430 Display.getDefault().asyncExec(() -> {
1431 if (getParent().isDisposed())
1434 removeVisualisationTemplateButton.setEnabled(visualisation != null && visualisation.getVisualisationResource() != null);
1436 if (visualisation != null) {
1437 String[] items = templateSelectionCombo.getItems();
1438 for (int i = 0; i < items.length; i++) {
1439 if (visualisation.getName().equals(items[i])) {
1440 templateSelectionCombo.select(i);
1445 intervalText.setText(Long.toString(visualisation.getInterval()));
1446 disableUpdatesButton.setSelection(visualisation.disabledUpdates());
1448 hoveringVertexEnabledButton.setSelection(visualisation.isKeyVariablesVertexHover());
1449 hoveringEdgesEnabledButton.setSelection(visualisation.isKeyVariablesEdgesHover());
1451 Map<String, DynamicColorContribution> colorContributions = visualisation.getColorContributions();
1452 for (Entry<String, DynamicColorContribution> entry : colorContributions.entrySet()) {
1454 ColoringObjectRow coloringObjectRow = coloringRows.get(entry.getKey());
1455 if (coloringObjectRow != null) {
1457 coloringObjectRow.update(entry.getValue());
1460 LOGGER.info("No coloring object visualisation row for key {}", entry.getKey());
1463 ColorBarOptions colorOptions = visualisation.getColorBarOptions();
1464 showColorButton.setSelection(colorOptions.isShowColorBars());
1465 colorTicksButton.setSelection(colorOptions.isShowColorBarsTicks());
1466 colorGradientButton.setSelection(colorOptions.isUseGradients());
1467 for (int i = 0; i < colorLocationCombo.getItems().length; i++) {
1468 String item = colorLocationCombo.getItem(i);
1469 if (item.equals(colorOptions.getLocation().toString())) {
1470 colorLocationCombo.select(i);
1474 for (int i = 0; i < colorSizeCombo.getItems().length; i++) {
1475 String item = colorSizeCombo.getItem(i);
1476 if (item.equals(colorOptions.getSize().toString())) {
1477 colorSizeCombo.select(i);
1482 Map<String, DynamicSizeContribution> sizeContributions = visualisation.getSizeContributions();
1483 for (Entry<String, DynamicSizeContribution> entry : sizeContributions.entrySet()) {
1485 SizingObjectRow sizingObjectRow = sizingRows.get(entry.getKey());
1486 if (sizingObjectRow != null) {
1488 sizingObjectRow.update(entry.getValue());
1491 LOGGER.info("No sizing object visualisation row for key {}", entry.getKey());
1494 SizeBarOptions sizeOptions = visualisation.getSizeBarOptions();
1495 showSizeButton.setSelection(sizeOptions.isShowSizeBars());
1496 sizeTicksButton.setSelection(sizeOptions.isShowSizeBarsTicks());
1497 sizeGradientButton.setSelection(sizeOptions.isUseGradients());
1498 for (int i = 0; i < sizeLocationCombo.getItems().length; i++) {
1499 String item = sizeLocationCombo.getItem(i);
1500 if (item.equals(sizeOptions.getLocation().toString())) {
1501 sizeLocationCombo.select(i);
1505 for (int i = 0; i < sizeSizeCombo.getItems().length; i++) {
1506 String item = sizeSizeCombo.getItem(i);
1507 if (item.equals(sizeOptions.getSize().toString())) {
1508 sizeSizeCombo.select(i);
1516 public void updateVisualisations(Collection<NamedResource> result) {
1517 this.visualisations = result;
1519 Display.getDefault().asyncExec(() -> {
1520 if (getParent().isDisposed())
1522 templateSelectionCombo.setItems(visualisations.stream().map(NamedResource::getName).collect(Collectors.toList()).toArray(new String[visualisations.size()]));
1524 if (visualisation != null) {
1525 String[] items = templateSelectionCombo.getItems();
1526 for (int i = 0; i < items.length; i++) {
1527 if (visualisation.getName().equals(items[i])) {
1528 templateSelectionCombo.select(i);
1537 public Composite getParent() {