package org.simantics.district.network.ui.visualisations; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Objects; import java.util.Optional; import java.util.function.Supplier; import java.util.stream.Collectors; import java.util.stream.Stream; import org.eclipse.jface.dialogs.Dialog; import org.eclipse.jface.dialogs.IInputValidator; import org.eclipse.jface.dialogs.InputDialog; import org.eclipse.jface.layout.GridDataFactory; import org.eclipse.jface.layout.GridLayoutFactory; import org.eclipse.swt.SWT; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Combo; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Group; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Text; import org.eclipse.ui.IEditorPart; import org.simantics.Simantics; import org.simantics.db.ReadGraph; import org.simantics.db.Resource; import org.simantics.db.WriteGraph; import org.simantics.db.common.NamedResource; import org.simantics.db.common.request.UniqueRead; import org.simantics.db.common.request.WriteRequest; import org.simantics.db.exception.DatabaseException; import org.simantics.db.procedure.Listener; import org.simantics.district.network.DistrictNetworkUtil; import org.simantics.district.network.ontology.DistrictNetworkResource; import org.simantics.district.network.profile.ActiveDynamicVisualisationsRequest; import org.simantics.district.network.profile.DynamicVisualisationsRequest; import org.simantics.district.network.visualisations.DynamicVisualisationsContributions; import org.simantics.district.network.visualisations.DynamicVisualisationsContributions.DynamicColoringObject; import org.simantics.district.network.visualisations.DynamicVisualisationsContributions.DynamicSizingObject; import org.simantics.district.network.visualisations.model.ColorBarOptions; import org.simantics.district.network.visualisations.model.ColorBarOptions.ColorBarsLocation; import org.simantics.district.network.visualisations.model.ColorBarOptions.ColorBarsSize; import org.simantics.district.network.visualisations.model.DynamicColorContribution; import org.simantics.district.network.visualisations.model.DynamicColorMap; import org.simantics.district.network.visualisations.model.DynamicSizeContribution; import org.simantics.district.network.visualisations.model.DynamicSizeMap; import org.simantics.district.network.visualisations.model.DynamicVisualisation; import org.simantics.district.network.visualisations.model.SizeBarOptions; import org.simantics.district.network.visualisations.model.SizeBarOptions.SizeBarsLocation; import org.simantics.district.network.visualisations.model.SizeBarOptions.SizeBarsSize; import org.simantics.ui.workbench.IResourceEditorPart; import org.simantics.utils.datastructures.Pair; import org.simantics.utils.ui.workbench.WorkbenchUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class DynamicVisualisationsUI extends Composite { private static final Logger LOGGER = LoggerFactory.getLogger(DynamicVisualisationsUI.class); private Resource diagramResource; private VisualisationListener listener; private DynamicVisualisation visualisation; private Button showSizeButton; private Button sizeTicksButton; private Combo sizeLocationCombo; private Combo sizeSizeCombo; private Button showColorButton; private Button colorTicksButton; private Combo colorLocationCombo; private Combo colorSizeCombo; private Combo templateSelectionCombo; private List>> colorSuppliers; public DynamicVisualisationsUI(Composite parent, int style) { super(parent, style); defaultInitializeUI(); } private void defaultInitializeUI() { GridDataFactory.fillDefaults().grab(true, true).applyTo(this); GridLayoutFactory.fillDefaults().numColumns(1).margins(5, 5).applyTo(this); Composite selectionComposite = new Composite(this, SWT.NONE); GridDataFactory.fillDefaults().grab(true, false).applyTo(selectionComposite); GridLayoutFactory.fillDefaults().numColumns(2).margins(5, 5).applyTo(selectionComposite); Label templateNameLabel = new Label(selectionComposite, SWT.NONE); templateNameLabel.setText("Visualisation template"); templateSelectionCombo = new Combo(selectionComposite, SWT.READ_ONLY); GridDataFactory.fillDefaults().grab(true, false).applyTo(templateSelectionCombo); templateSelectionCombo.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { String item = templateSelectionCombo.getItem(templateSelectionCombo.getSelectionIndex()); for (NamedResource template : visualisations) { if (item.equals(template.getName())) { Simantics.getSession().asyncRequest(new WriteRequest() { @Override public void perform(WriteGraph graph) throws DatabaseException { DistrictNetworkUtil.setActiveVisualisation(graph, diagramResource, template.getResource()); } }); break; } } } }); Composite coloringObjectsComposite = new Composite(this, SWT.NONE); GridDataFactory.fillDefaults().grab(true, false).applyTo(coloringObjectsComposite); GridLayoutFactory.fillDefaults().numColumns(1).applyTo(coloringObjectsComposite); initializeColoringObjects(coloringObjectsComposite); Composite colorBarsComposite = new Composite(this, SWT.NONE); GridDataFactory.fillDefaults().grab(true, false).applyTo(colorBarsComposite); GridLayoutFactory.fillDefaults().numColumns(1).applyTo(colorBarsComposite); initializeColorBars(colorBarsComposite); Composite objectSizesComposite = new Composite(this, SWT.NONE); GridDataFactory.fillDefaults().grab(true, false).applyTo(objectSizesComposite); GridLayoutFactory.fillDefaults().numColumns(1).applyTo(objectSizesComposite); initializeObjectSizes(objectSizesComposite); Composite sizeBarsComposite = new Composite(this, SWT.NONE); GridDataFactory.fillDefaults().grab(true, false).applyTo(sizeBarsComposite); GridLayoutFactory.fillDefaults().numColumns(1).applyTo(sizeBarsComposite); initializeSizeBars(sizeBarsComposite); Button saveVisualisationTemplateButton = new Button(this, SWT.NONE); saveVisualisationTemplateButton.setText("Save"); saveVisualisationTemplateButton.setEnabled(visualisation == null || visualisation.getVisualisationResource() != null); saveVisualisationTemplateButton.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { persistVisualisationTemplate(visualisation.getName(), Optional.of(visualisation.getVisualisationResource())); } }); Button saveVisualisationTemplateAsButton = new Button(this, SWT.NONE); saveVisualisationTemplateAsButton.setText("Save as visualisation template"); saveVisualisationTemplateAsButton.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { showSaveVisualisationTemplateDialog(e.widget.getDisplay().getActiveShell()); } }); } private void showSaveVisualisationTemplateDialog(Shell shell) { InputDialog dialog = new InputDialog(shell, "Save visualisation template", "Give template a name", "", new IInputValidator() { @Override public String isValid(String newText) { if (newText == null || newText.isEmpty()) return "Name cannot be empty"; return null; } }); if (dialog.open() == Dialog.OK) { String name = dialog.getValue(); persistVisualisationTemplate(name, Optional.empty()); } } private void persistVisualisationTemplate(String templateName, Optional existing) { List> colorCollect = colorSuppliers.stream().map(s -> s.get()).filter(Objects::nonNull).collect(Collectors.toList()); String colorLocation = colorLocationCombo.getItem(colorLocationCombo.getSelectionIndex()); String colorSize = colorSizeCombo.getItem(colorSizeCombo.getSelectionIndex()); ColorBarOptions colorBarOptions = new ColorBarOptions() .showColorBars(showColorButton.getSelection()) .showColorBarsTicks(colorTicksButton.getSelection()) .withLocation(ColorBarsLocation.valueOf(colorLocation)) .withSize(ColorBarsSize.valueOf(colorSize)); List> sizeCollect = sizeSuppliers.stream().map(s -> s.get()).filter(Objects::nonNull).collect(Collectors.toList()); String sizeLocation = sizeLocationCombo.getItem(sizeLocationCombo.getSelectionIndex()); String sizeSize = sizeSizeCombo.getItem(sizeSizeCombo.getSelectionIndex()); SizeBarOptions sizeBarOptions = new SizeBarOptions() .showSizeBars(showSizeButton.getSelection()) .showSizeBarsTicks(sizeTicksButton.getSelection()) .withLocation(SizeBarsLocation.valueOf(sizeLocation)) .withSize(SizeBarsSize.valueOf(sizeSize)); Simantics.getSession().asyncRequest(new WriteRequest() { @Override public void perform(WriteGraph graph) throws DatabaseException { DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph); Resource exist; if (existing.isPresent()) { exist = existing.get(); } else { exist = DistrictNetworkUtil.createVisualisation(graph, diagramResource, templateName); } DistrictNetworkUtil.setColorContributions(graph, exist, colorCollect); DistrictNetworkUtil.setColorBarOptions(graph, exist, colorBarOptions); DistrictNetworkUtil.setSizeContributions(graph, exist, sizeCollect); DistrictNetworkUtil.setSizeBarOptions(graph, exist, sizeBarOptions); } }); } private void initializeColoringObjects(Composite parent) { Group group = new Group(parent, SWT.NONE); group.setText("Coloring Objects"); GridDataFactory.fillDefaults().grab(true, false).applyTo(group); GridLayoutFactory.fillDefaults().numColumns(8).margins(5, 5).applyTo(group); { createColoringObjectHeaderRow(group); } colorSuppliers = new ArrayList<>(); { try { Collection result = Simantics.getSession().syncRequest(new UniqueRead>() { @Override public Collection perform(ReadGraph graph) throws DatabaseException { return DynamicVisualisationsContributions.dynamicColoringObjects(graph); } }); for (DynamicColoringObject object : result) { colorSuppliers.add(createColoringObjectRow(group, object)); } } catch (DatabaseException e) { LOGGER.error("Could not create coloring objecst", e); } } { Button applyButton = new Button(group, SWT.NONE); applyButton.setText("Apply"); applyButton.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { List> collect = colorSuppliers.stream().map(s -> s.get()).filter(Objects::nonNull).collect(Collectors.toList()); Simantics.getSession().asyncRequest(new WriteRequest() { @Override public void perform(WriteGraph graph) throws DatabaseException { DistrictNetworkUtil.setColorContributions(graph, visualisation.getVisualisationResource(), collect); } }); } }); } } private void createColoringObjectHeaderRow(Composite parent) { Label label = new Label(parent, SWT.NONE); label.setText("Label"); GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label); label = new Label(parent, SWT.NONE); label.setText("Used"); GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label); label = new Label(parent, SWT.NONE); label.setText("Variable"); GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label); label = new Label(parent, SWT.NONE); label.setText("Min"); GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label); label = new Label(parent, SWT.NONE); label.setText("Max"); GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label); label = new Label(parent, SWT.NONE); label.setText("Unit"); GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label); label = new Label(parent, SWT.NONE); label.setText("ColorMap"); GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label); label = new Label(parent, SWT.NONE); label.setText("Default"); GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label); } private Map coloringRows = new HashMap<>(); private Map sizingRows = new HashMap<>(); private VisualisationsListener visualisationsListener; private Collection visualisations; private List>> sizeSuppliers; private static class ColoringObjectRow { private final Label label; private final Button usedButton; private final Combo variableCombo; private final Text minText; private final Text maxText; private final Label unit; private final Combo colorMapCombo; private final Button defaultButton; public ColoringObjectRow(Label label, Button usedButton, Combo variableCombo, Text minText, Text maxText, Label unit, Combo colorMapCombo, Button defaultButton) { super(); this.label = label; this.usedButton = usedButton; this.variableCombo = variableCombo; this.minText = minText; this.maxText = maxText; this.unit = unit; this.colorMapCombo = colorMapCombo; this.defaultButton = defaultButton; } public void update(DynamicColorContribution colorContribution) { String[] items = variableCombo.getItems(); for (int i = 0; i < items.length; i++) { if (colorContribution.getLabel().equals(items[i])) { variableCombo.select(i); break; } } minText.setText(Double.toString(colorContribution.getDefaultMin())); maxText.setText(Double.toString(colorContribution.getDefaultMax())); unit.setText(colorContribution.getUnit()); // color map only supports single for now colorMapCombo.setItems(colorContribution.getDefaultColorMap().getLabel()); colorMapCombo.select(0); // String[] colorItems = colorMapCombo.getItems(); // for (int i = 0; i < colorItems.length; i++) { // // if (colorContribution.getDefaultColorMap().getLabel().equals(colorItems[i])) { // colorMapCombo.select(i); // break; // } // } usedButton.setSelection(colorContribution.isUsed()); defaultButton.setSelection(colorContribution.isUseDefault()); minText.setEnabled(!colorContribution.isUseDefault()); maxText.setEnabled(!colorContribution.isUseDefault()); colorMapCombo.setEnabled(!colorContribution.isUseDefault()); } } private static class SizingObjectRow { private final Label label; private final Button usedButton; private final Combo variableCombo; private final Text minText; private final Text maxText; private final Label unit; private final Combo sizeMapCombo; private final Button defaultButton; public SizingObjectRow(Label label, Button usedButton, Combo variableCombo, Text minText, Text maxText, Label unit, Combo sizeMapCombo, Button defaultButton) { super(); this.label = label; this.usedButton = usedButton; this.variableCombo = variableCombo; this.minText = minText; this.maxText = maxText; this.unit = unit; this.sizeMapCombo = sizeMapCombo; this.defaultButton = defaultButton; } public void update(DynamicSizeContribution sizeContribution) { String[] items = variableCombo.getItems(); for (int i = 0; i < items.length; i++) { if (sizeContribution.getLabel().equals(items[i])) { variableCombo.select(i); break; } } minText.setText(Double.toString(sizeContribution.getDefaultMin())); maxText.setText(Double.toString(sizeContribution.getDefaultMax())); unit.setText(sizeContribution.getUnit()); // color map only supports single for now sizeMapCombo.setItems(sizeContribution.getDefaultSizeMap().getLabel()); sizeMapCombo.select(0); // String[] colorItems = colorMapCombo.getItems(); // for (int i = 0; i < colorItems.length; i++) { // // if (colorContribution.getDefaultColorMap().getLabel().equals(colorItems[i])) { // colorMapCombo.select(i); // break; // } // } } } private Supplier> createColoringObjectRow(Composite parent, DynamicColoringObject object) { Label label = new Label(parent, SWT.NONE); label.setText(object.getColoringObject().getName()); GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(label); Map colorContributions = object.getColorContributions(); Button usedButton = new Button(parent, SWT.CHECK); GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(usedButton); Combo variableCombo = new Combo(parent, SWT.READ_ONLY); variableCombo.setItems(colorContributions.keySet().toArray(new String[colorContributions.size()])); GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(variableCombo); Text minText = new Text(parent, SWT.BORDER); GridDataFactory.fillDefaults().grab(true, false).hint(150, SWT.DEFAULT).align(SWT.CENTER, SWT.CENTER).applyTo(minText); Text maxText = new Text(parent, SWT.BORDER); GridDataFactory.fillDefaults().grab(true, false).hint(150, SWT.DEFAULT).align(SWT.CENTER, SWT.CENTER).applyTo(maxText); Label unit = new Label(parent, SWT.NONE); unit.setText(""); GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(unit); Combo colorMapCombo = new Combo(parent, SWT.READ_ONLY); GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(colorMapCombo); Button defaultButton = new Button(parent, SWT.CHECK); GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(defaultButton); defaultButton.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { int index = variableCombo.getSelectionIndex(); if (index >= 0) { String key = variableCombo.getItem(index); DynamicColorContribution cont = colorContributions.get(key); minText.setText(Double.toString(cont.getDefaultMin())); minText.setEnabled(!defaultButton.getSelection()); maxText.setText(Double.toString(cont.getDefaultMax())); maxText.setEnabled(!defaultButton.getSelection()); unit.setText(cont.getUnit()); colorMapCombo.setItems(cont.getDefaultColorMap().getLabel()); colorMapCombo.select(0); colorMapCombo.setEnabled(!defaultButton.getSelection()); } } }); variableCombo.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { // handle update for others int index = variableCombo.getSelectionIndex(); if (index >= 0) { String key = variableCombo.getItem(index); DynamicColorContribution cont = colorContributions.get(key); if (minText.getText().isEmpty()) { minText.setText(Double.toString(cont.getDefaultMin())); } if (maxText.getText().isEmpty()) { maxText.setText(Double.toString(cont.getDefaultMax())); } unit.setText(cont.getUnit()); colorMapCombo.setItems(cont.getDefaultColorMap().getLabel()); colorMapCombo.select(0); defaultButton.setSelection(true); } } }); coloringRows.put(object.getColoringObject().getName(), new ColoringObjectRow(label, usedButton, variableCombo, minText, maxText, unit, colorMapCombo, defaultButton)); return new Supplier>() { @Override public Pair get() { int selectionIndex = variableCombo.getSelectionIndex(); if (selectionIndex >= 0) { String key = variableCombo.getItem(selectionIndex); DynamicColorContribution cont = colorContributions.get(key); if (cont != null) { String colorMap = colorMapCombo.getItem(colorMapCombo.getSelectionIndex()); try { Map colorMaps = Simantics.getSession().syncRequest(new UniqueRead>() { @Override public Map perform(ReadGraph graph) throws DatabaseException { return DynamicVisualisationsContributions.dynamicColorMaps(graph); } }); DynamicColorMap dColorMap = colorMaps.get(colorMap); String label = variableCombo.getItem(variableCombo.getSelectionIndex()); DynamicColorContribution dcc = new DynamicColorContribution(label, cont.getModuleName(), cont.getAttributeName(), unit.getText(), cont.getVariableGain(), cont.getVariableBias(), dColorMap, Double.parseDouble(minText.getText()), Double.parseDouble(maxText.getText())); dcc.setUsed(usedButton.getSelection()); dcc.setUseDefault(defaultButton.getSelection()); return Pair.make(object.getColoringObject().getName(), dcc); } catch (DatabaseException e) { LOGGER.error("Could not get DynamicColorContribution", e); } } } return null; } }; } private void createSizingObjectHeaderRow(Composite parent) { Label label = new Label(parent, SWT.NONE); label.setText("Label"); GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label); label = new Label(parent, SWT.NONE); label.setText("Used"); GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label); label = new Label(parent, SWT.NONE); label.setText("Variable"); GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label); label = new Label(parent, SWT.NONE); label.setText("Min"); GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label); label = new Label(parent, SWT.NONE); label.setText("Max"); GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label); label = new Label(parent, SWT.NONE); label.setText("Unit"); GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label); label = new Label(parent, SWT.NONE); label.setText("SizeMap"); GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label); label = new Label(parent, SWT.NONE); label.setText("Default"); GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label); } private Supplier> createSizingObjectRow(Composite parent, DynamicSizingObject object) { Label label = new Label(parent, SWT.NONE); label.setText(object.getSizingObject().getName()); GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(label); Map sizeContributions = object.getSizeContributions(); Button usedButton = new Button(parent, SWT.CHECK); GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(usedButton); Combo variableCombo = new Combo(parent, SWT.READ_ONLY); variableCombo.setItems(sizeContributions.keySet().toArray(new String[sizeContributions.size()])); GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(variableCombo); Text minText = new Text(parent, SWT.BORDER); GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(minText); Text maxText = new Text(parent, SWT.BORDER); GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(maxText); Label unit = new Label(parent, SWT.NONE); unit.setText(""); GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(unit); Combo sizeMapCombo = new Combo(parent, SWT.READ_ONLY); GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(sizeMapCombo); Button defaultButton = new Button(parent, SWT.CHECK); GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(defaultButton); variableCombo.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { // handle update for others String key = variableCombo.getItem(variableCombo.getSelectionIndex()); DynamicSizeContribution cont = sizeContributions.get(key); if (minText.getText().isEmpty()) { minText.setText(Double.toString(cont.getDefaultMin())); } if (maxText.getText().isEmpty()) { maxText.setText(Double.toString(cont.getDefaultMax())); } unit.setText(cont.getUnit()); sizeMapCombo.setItems(cont.getDefaultSizeMap().getLabel()); sizeMapCombo.select(0); defaultButton.setSelection(true); } }); sizingRows.put(object.getSizingObject().getName(), new SizingObjectRow(label, usedButton, variableCombo, minText, maxText, unit, sizeMapCombo, defaultButton)); return new Supplier>() { @Override public Pair get() { int selectionIndex = variableCombo.getSelectionIndex(); if (selectionIndex >= 0) { String key = variableCombo.getItem(selectionIndex); DynamicSizeContribution cont = sizeContributions.get(key); if (cont != null) { String sizeMap = sizeMapCombo.getItem(sizeMapCombo.getSelectionIndex()); try { Map sizeMaps = Simantics.getSession().syncRequest(new UniqueRead>() { @Override public Map perform(ReadGraph graph) throws DatabaseException { return DynamicVisualisationsContributions.dynamicSizeMaps(graph); } }); DynamicSizeMap dColorMap = sizeMaps.get(sizeMap); String label = variableCombo.getItem(variableCombo.getSelectionIndex()); DynamicSizeContribution dsc = new DynamicSizeContribution(label, cont.getModuleName(), cont.getAttributeName(), unit.getText(), cont.getVariableGain(), cont.getVariableBias(), dColorMap, Double.parseDouble(minText.getText()), Double.parseDouble(maxText.getText())); dsc.setUsed(usedButton.getSelection()); dsc.setUseDefault(defaultButton.getSelection()); return Pair.make(object.getSizingObject().getName(), dsc); } catch (DatabaseException e) { LOGGER.error("Could not get DynamicColorContribution", e); } } } return null; } }; } private void initializeColorBars(Composite parent) { Group group = new Group(parent, SWT.NONE); group.setText("Color Bars"); GridDataFactory.fillDefaults().grab(true, false).applyTo(group); GridLayoutFactory.fillDefaults().numColumns(2).margins(5, 5).applyTo(group); createColorBars(group); } private void createColorBars(Composite parent) { showColorButton = new Button(parent, SWT.CHECK); showColorButton.setText("Show"); colorTicksButton = new Button(parent, SWT.CHECK); colorTicksButton.setText("Ticks"); Label label = new Label(parent, SWT.NONE); label.setText("Location"); colorLocationCombo = new Combo(parent, SWT.READ_ONLY); colorLocationCombo.setItems(Stream.of(ColorBarsLocation.values()).map(size -> size.toString()).toArray(String[]::new)); label = new Label(parent, SWT.NONE); label.setText("Size"); colorSizeCombo = new Combo(parent, SWT.READ_ONLY); colorSizeCombo.setItems(Stream.of(ColorBarsSize.values()).map(size -> size.toString()).toArray(String[]::new)); Button applyButton = new Button(parent, SWT.NONE); applyButton.setText("Apply"); applyButton.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { // persist changes IEditorPart activeEditor = WorkbenchUtils.getActiveEditor(); if (activeEditor instanceof IResourceEditorPart) { String colorLocation = colorLocationCombo.getItem(colorLocationCombo.getSelectionIndex()); String colorSize = colorSizeCombo.getItem(colorSizeCombo.getSelectionIndex()); ColorBarOptions options = new ColorBarOptions() .showColorBars(showColorButton.getSelection()) .showColorBarsTicks(colorTicksButton.getSelection()) .withLocation(ColorBarsLocation.valueOf(colorLocation)) .withSize(ColorBarsSize.valueOf(colorSize)); Simantics.getSession().asyncRequest(new WriteRequest() { @Override public void perform(WriteGraph graph) throws DatabaseException { DistrictNetworkUtil.setColorBarOptions(graph, visualisation.getVisualisationResource(), options); } }); } } }); } private void initializeObjectSizes(Composite parent) { Group group = new Group(parent, SWT.NONE); group.setText("Object Sizes"); GridDataFactory.fillDefaults().grab(true, false).applyTo(group); GridLayoutFactory.fillDefaults().numColumns(8).margins(5, 5).applyTo(group); { createSizingObjectHeaderRow(group); createObjectSizes(group); } } private void createObjectSizes(Composite parent) { sizeSuppliers = new ArrayList<>(); try { Collection resultSizing = Simantics.getSession().syncRequest(new UniqueRead>() { @Override public Collection perform(ReadGraph graph) throws DatabaseException { return DynamicVisualisationsContributions.dynamicSizingObjects(graph); } }); for (DynamicSizingObject object : resultSizing) { sizeSuppliers.add(createSizingObjectRow(parent, object)); } } catch (DatabaseException e) { LOGGER.error("Could not create object sizes", e); } { Button applyButton = new Button(parent, SWT.NONE); applyButton.setText("Apply"); applyButton.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { List> collect = sizeSuppliers.stream().map(s -> s.get()).filter(Objects::nonNull).collect(Collectors.toList()); Simantics.getSession().asyncRequest(new WriteRequest() { @Override public void perform(WriteGraph graph) throws DatabaseException { DistrictNetworkUtil.setSizeContributions(graph, visualisation.getVisualisationResource(), collect); } }); } }); } } private void initializeSizeBars(Composite parent) { Group group = new Group(parent, SWT.NONE); group.setText("Size Bars"); GridDataFactory.fillDefaults().grab(true, false).applyTo(group); GridLayoutFactory.fillDefaults().numColumns(2).margins(5, 5).applyTo(group); createSizeBars(group); } private void createSizeBars(Composite parent) { showSizeButton = new Button(parent, SWT.CHECK); showSizeButton.setText("Show"); sizeTicksButton = new Button(parent, SWT.CHECK); sizeTicksButton.setText("Ticks"); Label label = new Label(parent, SWT.NONE); label.setText("Location"); sizeLocationCombo = new Combo(parent, SWT.READ_ONLY); sizeLocationCombo.setItems(Stream.of(SizeBarsLocation.values()).map(size -> size.toString()).toArray(String[]::new)); label = new Label(parent, SWT.NONE); label.setText("Size"); sizeSizeCombo = new Combo(parent, SWT.READ_ONLY); sizeSizeCombo.setItems(Stream.of(SizeBarsSize.values()).map(size -> size.toString()).toArray(String[]::new)); Button applyButton = new Button(parent, SWT.READ_ONLY); applyButton.setText("Apply"); applyButton.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { // persist changes IEditorPart activeEditor = WorkbenchUtils.getActiveEditor(); if (activeEditor instanceof IResourceEditorPart) { String sizeLocation = sizeLocationCombo.getItem(sizeLocationCombo.getSelectionIndex()); String sizeSize = sizeSizeCombo.getItem(sizeSizeCombo.getSelectionIndex()); SizeBarOptions options = new SizeBarOptions() .showSizeBars(showSizeButton.getSelection()) .showSizeBarsTicks(sizeTicksButton.getSelection()) .withLocation(SizeBarsLocation.valueOf(sizeLocation)) .withSize(SizeBarsSize.valueOf(sizeSize)); Simantics.getSession().asyncRequest(new WriteRequest() { @Override public void perform(WriteGraph graph) throws DatabaseException { DistrictNetworkUtil.setSizeBarOptions(graph, visualisation.getVisualisationResource(), options); } }); } } }); } public void setDiagramResource(Resource diagramResource) { if (this.diagramResource != diagramResource) { this.diagramResource = diagramResource; updateListening(); } } private void updateListening() { if (visualisationsListener != null) visualisationsListener.dispose(); visualisationsListener = new VisualisationsListener(this); Simantics.getSession().asyncRequest(new DynamicVisualisationsRequest(diagramResource), visualisationsListener); if (listener != null) listener.dispose(); listener = new VisualisationListener(this); Simantics.getSession().asyncRequest(new ActiveDynamicVisualisationsRequest(diagramResource), listener); } private static class VisualisationsListener implements Listener> { private static final Logger LOGGER = LoggerFactory.getLogger(VisualisationsListener.class); private boolean disposed; private DynamicVisualisationsUI ui; public VisualisationsListener(DynamicVisualisationsUI ui) { this.ui = ui; } @Override public void execute(Collection result) { ui.updateVisualisations(result); } @Override public void exception(Throwable t) { LOGGER.error("Could not listen visualisation", t); } @Override public boolean isDisposed() { return disposed || ui.isDisposed(); } public void dispose() { this.disposed = true; } } private static class VisualisationListener implements Listener { private static final Logger LOGGER = LoggerFactory.getLogger(VisualisationListener.class); private boolean disposed; private DynamicVisualisationsUI ui; public VisualisationListener(DynamicVisualisationsUI ui) { this.ui = ui; } @Override public void execute(DynamicVisualisation result) { ui.updateVisualisation(result); } @Override public void exception(Throwable t) { LOGGER.error("Could not listen visualisation", t); } @Override public boolean isDisposed() { return disposed || ui.isDisposed(); } public void dispose() { this.disposed = true; } } public void updateVisualisation(DynamicVisualisation result) { this.visualisation = result; if (visualisation != null) { Display.getDefault().asyncExec(() -> { if (getParent().isDisposed()) return; String[] items = templateSelectionCombo.getItems(); for (int i = 0; i < items.length; i++) { if (visualisation.getName().equals(items[i])) { templateSelectionCombo.select(i); break; } } Map colorContributions = visualisation.getColorContributions(); for (Entry entry : colorContributions.entrySet()) { ColoringObjectRow coloringObjectRow = coloringRows.get(entry.getKey()); if (coloringObjectRow != null) { coloringObjectRow.update(entry.getValue()); } else { LOGGER.info("No coloring object visualisation row for key {}", entry.getKey()); } } ColorBarOptions colorOptions = visualisation.getColorBarOptions(); showColorButton.setSelection(colorOptions.isShowColorBars()); colorTicksButton.setSelection(colorOptions.isShowColorBarsTicks()); for (int i = 0; i < colorLocationCombo.getItems().length; i++) { String item = colorLocationCombo.getItem(i); if (item.equals(colorOptions.getLocation().toString())) { colorLocationCombo.select(i); break; } } for (int i = 0; i < colorSizeCombo.getItems().length; i++) { String item = colorSizeCombo.getItem(i); if (item.equals(colorOptions.getSize().toString())) { colorSizeCombo.select(i); break; } } Map sizeContributions = visualisation.getSizeContributions(); for (Entry entry : sizeContributions.entrySet()) { SizingObjectRow sizingObjectRow = sizingRows.get(entry.getKey()); if (sizingObjectRow != null) { sizingObjectRow.update(entry.getValue()); } else { LOGGER.info("No sizing object visualisation row for key {}", entry.getKey()); } } SizeBarOptions sizeOptions = visualisation.getSizeBarOptions(); showSizeButton.setSelection(sizeOptions.isShowSizeBars()); sizeTicksButton.setSelection(sizeOptions.isShowSizeBarsTicks()); for (int i = 0; i < sizeLocationCombo.getItems().length; i++) { String item = sizeLocationCombo.getItem(i); if (item.equals(sizeOptions.getLocation().toString())) { sizeLocationCombo.select(i); break; } } for (int i = 0; i < sizeSizeCombo.getItems().length; i++) { String item = sizeSizeCombo.getItem(i); if (item.equals(sizeOptions.getSize().toString())) { sizeSizeCombo.select(i); break; } } }); } } public void updateVisualisations(Collection result) { this.visualisations = result; Display.getDefault().asyncExec(() -> { if (getParent().isDisposed()) return; templateSelectionCombo.setItems(visualisations.stream().map(NamedResource::getName).collect(Collectors.toList()).toArray(new String[visualisations.size()])); }); } }