DN.SCLMain : L0.SCLModule
L0.SCLModule.definition
"""
- include "Simantics/District/SCLMain"
- """
+include "Simantics/District/SCLMain"
+"""
// ----------------------------------------------------------------------------
L0 = <http://www.simantics.org/Layer0-1.1>
+L0X = <http://www.simantics.org/Layer0X-1.1>
DIA = <http://www.simantics.org/Diagram-2.2>
STR = <http://www.simantics.org/Structural-1.2>
MOD = <http://www.simantics.org/Modeling-1.2>
@L0.assert DN.Vertex.ScaleProperty.bias 0.0
DN.Diagram
+ >-- DN.Diagram.elementColoringGradientHue ==> "Float" <R L0.HasProperty : SEL.GenericParameterType
+ L0.HasLabel "Element Color Hue"
+ L0.HasDescription "HSV/HSB color space hue value used for element coloring in degrees (0-360)"
+ L0X.HasUnit "deg"
+ L0X.RequiresDataType $(Float(unit="deg",range=[0..360]))
+ SEL.HasDisplayValue _ : SEL.DisplayValue
+ L0.Literal.HasInputValidator DN.Functions.hueValidator : L0.Function
+ >-- DN.Diagram.elementColoringGradientSaturation ==> "Float" <R L0.HasProperty : SEL.GenericParameterType
+ L0.HasLabel "Element Color Saturation"
+ L0.HasDescription "HSV/HSB color space saturation value used for element coloring in % (0-100)"
+ L0X.HasUnit "%"
+ L0X.RequiresDataType $(Float(unit="%",range=[0..100]))
+ SEL.HasDisplayValue _ : SEL.DisplayValue
+ L0.Literal.HasInputValidator DN.Functions.saturationValidator : L0.Function
+ >-- DN.Diagram.elementColoringFunction --> L0.String ==> "Resource -> <ReadGraph> Double" <R L0.HasProperty : SEL.GenericParameterType
+ L0.HasLabel "Element Color Brightness Function"
+ L0.HasDescription "Defines HSV/HSB color space brightness function whose value is cut off to fit [0,1]. Together with hue and saturation this defines the element color."
+ SEL.HasDisplayValue _ : SEL.DisplayValue
+ L0.Literal.HasInputValidator DN.Functions.brightnessValidator : L0.Function
>-- DN.Diagram.edgeThicknessGain ==> "Double" <R L0.HasProperty : SEL.GenericParameterType
L0.HasLabel "Edge Thickness Gain"
>-- DN.Diagram.edgeThicknessBias ==> "Double" <R L0.HasProperty : SEL.GenericParameterType
L0.HasLabel "Node Scale Bias"
>-- DN.Diagram.nodeScaleProperty --> DN.Vertex.ScaleProperty <R L0.HasProperty : DN.VertexScalePropertyParameterType
L0.HasLabel "Node Scale Property"
+ @L0.assert DN.Diagram.elementColoringGradientHue
+ 0.0 : L0.Float
+ L0.HasDataType $(Float(unit="deg",range=[0..360]))
+ @L0.assert DN.Diagram.elementColoringGradientSaturation
+ 100.0 : L0.Float
+ L0.HasDataType $(Float(unit="%",range=[0..100]))
+ @MOD.sclAssertion DN.Diagram.elementColoringFunction "\r -> 1.0" "Resource -> <ReadGraph> Double"
@L0.assert DN.Diagram.edgeThicknessGain 1.0
@L0.assert DN.Diagram.edgeThicknessBias 0.0
@L0.assert DN.Diagram.edgeThicknessProperty DN.Edge.ThicknessProperty.Diameter
// ----------------------------------------------------------------------------
// Built-in enumerated ScaleProperty & ThicknessProperty instances
+DN.Functions.constantOne : L0.Function
+ L0.HasValueType "Resource -> <ReadGraph> Maybe Double"
+
DN.Edge.ThicknessProperty.OnlyGainAndBias: DN.Edge.ThicknessProperty
L0.HasLabel "Only Gain and Bias"
DN.Edge.ThicknessProperty.value
- DN.Functions.constantOne : L0.Function
- L0.HasValueType "Resource -> <ReadGraph> Maybe Double"
+ DN.Functions.constantOne
DN.Edge.ThicknessProperty.Diameter : DN.Edge.ThicknessProperty
L0.HasLabel "Diameter"
DN.Vertex.ScaleProperty.OnlyGainAndBias: DN.Vertex.ScaleProperty
L0.HasLabel "Only Gain and Bias"
DN.Vertex.ScaleProperty.value
- DN.Functions.constantOne : L0.Function
- L0.HasValueType "Resource -> <ReadGraph> Maybe Double"
+ DN.Functions.constantOne
DN.Vertex.ScaleProperty.NominalSupplyPressure : DN.Vertex.ScaleProperty
L0.HasLabel "Nominal Supply Pressure"
DN.Groups.EdgeGroup : DIA.TypeGroup
DIA.TypeGroup.HasType DN.Edge
+DN.ElementColoringStyle : DIA.Style
DN.VertexSizeStyle : DIA.Style
DN.EdgeThicknessStyle : DIA.Style
DN.HideStyle : DIA.Style
-import "Simantics/DB"
-import "Simantics/Variables"
-
-districtNetworkProfileStyle :: String -> Resource -> <ReadGraph> (String, String, String)
-districtNetworkProfileStyle relation element = do
- rel = possibleResource relation
- result = match rel with
- Just rel -> do
- match possibleRelatedValue element rel with
- Just res -> res
- Nothing -> ""
- Nothing -> ""
- ("", result, "")
\ No newline at end of file
+include "Simantics/DB"
+include "Simantics/Variables"
+include "Simantics/Ontologies"
+include "Simantics/District"
+include "http://www.simantics.org/DistrictNetwork-1.0" as DN
public final Resource Diagram_edgeThicknessGain_Inverse;
public final Resource Diagram_edgeThicknessProperty;
public final Resource Diagram_edgeThicknessProperty_Inverse;
+ public final Resource Diagram_elementColoringFunction;
+ public final Resource Diagram_elementColoringFunction_Inverse;
+ public final Resource Diagram_elementColoringGradientHue;
+ public final Resource Diagram_elementColoringGradientHue_Inverse;
+ public final Resource Diagram_elementColoringGradientSaturation;
+ public final Resource Diagram_elementColoringGradientSaturation_Inverse;
public final Resource Diagram_nodeScaleBias;
public final Resource Diagram_nodeScaleBias_Inverse;
public final Resource Diagram_nodeScaleGain;
public final Resource Edge_ThicknessProperty_value;
public final Resource Edge_ThicknessProperty_value_Inverse;
public final Resource Element;
+ public final Resource ElementColoringStyle;
public final Resource Functions;
+ public final Resource Functions_brightnessValidator;
public final Resource Functions_compositeInstantiator;
public final Resource Functions_constantOne;
public final Resource Functions_convertToValue;
public final Resource Functions_hasDiameterValue;
public final Resource Functions_hasElevation;
public final Resource Functions_hasNominalSupplyPressure;
+ public final Resource Functions_hueValidator;
public final Resource Functions_mappingModifier;
public final Resource Functions_nodeScalePropertyEnumerationValues;
public final Resource Functions_nodeScalePropertyModifier;
+ public final Resource Functions_saturationValidator;
public final Resource Groups;
public final Resource Groups_EdgeGroup;
public final Resource Groups_VertexGroup;
public static final String Diagram_edgeThicknessGain_Inverse = "http://www.simantics.org/DistrictNetwork-1.0/Diagram/edgeThicknessGain/Inverse";
public static final String Diagram_edgeThicknessProperty = "http://www.simantics.org/DistrictNetwork-1.0/Diagram/edgeThicknessProperty";
public static final String Diagram_edgeThicknessProperty_Inverse = "http://www.simantics.org/DistrictNetwork-1.0/Diagram/edgeThicknessProperty/Inverse";
+ public static final String Diagram_elementColoringFunction = "http://www.simantics.org/DistrictNetwork-1.0/Diagram/elementColoringFunction";
+ public static final String Diagram_elementColoringFunction_Inverse = "http://www.simantics.org/DistrictNetwork-1.0/Diagram/elementColoringFunction/Inverse";
+ public static final String Diagram_elementColoringGradientHue = "http://www.simantics.org/DistrictNetwork-1.0/Diagram/elementColoringGradientHue";
+ public static final String Diagram_elementColoringGradientHue_Inverse = "http://www.simantics.org/DistrictNetwork-1.0/Diagram/elementColoringGradientHue/Inverse";
+ public static final String Diagram_elementColoringGradientSaturation = "http://www.simantics.org/DistrictNetwork-1.0/Diagram/elementColoringGradientSaturation";
+ public static final String Diagram_elementColoringGradientSaturation_Inverse = "http://www.simantics.org/DistrictNetwork-1.0/Diagram/elementColoringGradientSaturation/Inverse";
public static final String Diagram_nodeScaleBias = "http://www.simantics.org/DistrictNetwork-1.0/Diagram/nodeScaleBias";
public static final String Diagram_nodeScaleBias_Inverse = "http://www.simantics.org/DistrictNetwork-1.0/Diagram/nodeScaleBias/Inverse";
public static final String Diagram_nodeScaleGain = "http://www.simantics.org/DistrictNetwork-1.0/Diagram/nodeScaleGain";
public static final String Edge_ThicknessProperty_value = "http://www.simantics.org/DistrictNetwork-1.0/Edge/ThicknessProperty/value";
public static final String Edge_ThicknessProperty_value_Inverse = "http://www.simantics.org/DistrictNetwork-1.0/Edge/ThicknessProperty/value/Inverse";
public static final String Element = "http://www.simantics.org/DistrictNetwork-1.0/Element";
+ public static final String ElementColoringStyle = "http://www.simantics.org/DistrictNetwork-1.0/ElementColoringStyle";
public static final String Functions = "http://www.simantics.org/DistrictNetwork-1.0/Functions";
+ public static final String Functions_brightnessValidator = "http://www.simantics.org/DistrictNetwork-1.0/Functions/brightnessValidator";
public static final String Functions_compositeInstantiator = "http://www.simantics.org/DistrictNetwork-1.0/Functions/compositeInstantiator";
public static final String Functions_constantOne = "http://www.simantics.org/DistrictNetwork-1.0/Functions/constantOne";
public static final String Functions_convertToValue = "http://www.simantics.org/DistrictNetwork-1.0/Functions/convertToValue";
public static final String Functions_hasDiameterValue = "http://www.simantics.org/DistrictNetwork-1.0/Functions/hasDiameterValue";
public static final String Functions_hasElevation = "http://www.simantics.org/DistrictNetwork-1.0/Functions/hasElevation";
public static final String Functions_hasNominalSupplyPressure = "http://www.simantics.org/DistrictNetwork-1.0/Functions/hasNominalSupplyPressure";
+ public static final String Functions_hueValidator = "http://www.simantics.org/DistrictNetwork-1.0/Functions/hueValidator";
public static final String Functions_mappingModifier = "http://www.simantics.org/DistrictNetwork-1.0/Functions/mappingModifier";
public static final String Functions_nodeScalePropertyEnumerationValues = "http://www.simantics.org/DistrictNetwork-1.0/Functions/nodeScalePropertyEnumerationValues";
public static final String Functions_nodeScalePropertyModifier = "http://www.simantics.org/DistrictNetwork-1.0/Functions/nodeScalePropertyModifier";
+ public static final String Functions_saturationValidator = "http://www.simantics.org/DistrictNetwork-1.0/Functions/saturationValidator";
public static final String Groups = "http://www.simantics.org/DistrictNetwork-1.0/Groups";
public static final String Groups_EdgeGroup = "http://www.simantics.org/DistrictNetwork-1.0/Groups/EdgeGroup";
public static final String Groups_VertexGroup = "http://www.simantics.org/DistrictNetwork-1.0/Groups/VertexGroup";
Diagram_edgeThicknessGain_Inverse = getResourceOrNull(graph, URIs.Diagram_edgeThicknessGain_Inverse);
Diagram_edgeThicknessProperty = getResourceOrNull(graph, URIs.Diagram_edgeThicknessProperty);
Diagram_edgeThicknessProperty_Inverse = getResourceOrNull(graph, URIs.Diagram_edgeThicknessProperty_Inverse);
+ Diagram_elementColoringFunction = getResourceOrNull(graph, URIs.Diagram_elementColoringFunction);
+ Diagram_elementColoringFunction_Inverse = getResourceOrNull(graph, URIs.Diagram_elementColoringFunction_Inverse);
+ Diagram_elementColoringGradientHue = getResourceOrNull(graph, URIs.Diagram_elementColoringGradientHue);
+ Diagram_elementColoringGradientHue_Inverse = getResourceOrNull(graph, URIs.Diagram_elementColoringGradientHue_Inverse);
+ Diagram_elementColoringGradientSaturation = getResourceOrNull(graph, URIs.Diagram_elementColoringGradientSaturation);
+ Diagram_elementColoringGradientSaturation_Inverse = getResourceOrNull(graph, URIs.Diagram_elementColoringGradientSaturation_Inverse);
Diagram_nodeScaleBias = getResourceOrNull(graph, URIs.Diagram_nodeScaleBias);
Diagram_nodeScaleBias_Inverse = getResourceOrNull(graph, URIs.Diagram_nodeScaleBias_Inverse);
Diagram_nodeScaleGain = getResourceOrNull(graph, URIs.Diagram_nodeScaleGain);
Edge_ThicknessProperty_value = getResourceOrNull(graph, URIs.Edge_ThicknessProperty_value);
Edge_ThicknessProperty_value_Inverse = getResourceOrNull(graph, URIs.Edge_ThicknessProperty_value_Inverse);
Element = getResourceOrNull(graph, URIs.Element);
+ ElementColoringStyle = getResourceOrNull(graph, URIs.ElementColoringStyle);
Functions = getResourceOrNull(graph, URIs.Functions);
+ Functions_brightnessValidator = getResourceOrNull(graph, URIs.Functions_brightnessValidator);
Functions_compositeInstantiator = getResourceOrNull(graph, URIs.Functions_compositeInstantiator);
Functions_constantOne = getResourceOrNull(graph, URIs.Functions_constantOne);
Functions_convertToValue = getResourceOrNull(graph, URIs.Functions_convertToValue);
Functions_hasDiameterValue = getResourceOrNull(graph, URIs.Functions_hasDiameterValue);
Functions_hasElevation = getResourceOrNull(graph, URIs.Functions_hasElevation);
Functions_hasNominalSupplyPressure = getResourceOrNull(graph, URIs.Functions_hasNominalSupplyPressure);
+ Functions_hueValidator = getResourceOrNull(graph, URIs.Functions_hueValidator);
Functions_mappingModifier = getResourceOrNull(graph, URIs.Functions_mappingModifier);
Functions_nodeScalePropertyEnumerationValues = getResourceOrNull(graph, URIs.Functions_nodeScalePropertyEnumerationValues);
Functions_nodeScalePropertyModifier = getResourceOrNull(graph, URIs.Functions_nodeScalePropertyModifier);
+ Functions_saturationValidator = getResourceOrNull(graph, URIs.Functions_saturationValidator);
Groups = getResourceOrNull(graph, URIs.Groups);
Groups_EdgeGroup = getResourceOrNull(graph, URIs.Groups_EdgeGroup);
Groups_VertexGroup = getResourceOrNull(graph, URIs.Groups_VertexGroup);
package org.simantics.district.network.ui.function;
+import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import org.simantics.db.exception.RuntimeDatabaseException;
import org.simantics.db.exception.ServiceException;
import org.simantics.db.layer0.QueryIndexUtils;
+import org.simantics.db.layer0.util.Layer0Utils;
import org.simantics.db.layer0.variable.Variable;
import org.simantics.db.layer0.variable.Variables;
import org.simantics.db.layer0.variable.Variables.Role;
import org.simantics.modeling.adapters.NewCompositeActionFactory;
import org.simantics.modeling.typicals.TypicalUtil;
import org.simantics.operation.Layer0X;
+import org.simantics.scl.compiler.commands.CommandSession;
+import org.simantics.scl.compiler.commands.CommandSessionImportEntry;
+import org.simantics.scl.compiler.errors.CompilationError;
+import org.simantics.scl.osgi.SCLOsgi;
import org.simantics.scl.reflection.annotations.SCLValue;
import org.simantics.scl.runtime.SCLContext;
import org.simantics.scl.runtime.function.Function1;
import org.simantics.scl.runtime.function.FunctionImpl1;
+import org.simantics.scl.runtime.reporting.SCLReportingHandler;
import org.simantics.ui.workbench.action.DefaultActions;
import org.simantics.utils.ui.SWTUtils;
import org.slf4j.Logger;
public Double apply(Resource edge) {
return ONE;
}
+ @Override
+ public String toString() {
+ return "1";
+ }
};
@SCLValue(type = "ReadGraph -> Resource -> Variable -> b")
};
}
+ private static class RangeValidator implements Function1<String, String> {
+ private double min;
+ private double max;
+ public RangeValidator(double min, double max) {
+ this.min = min;
+ this.max = max;
+ }
+ @Override
+ public String apply(String s) {
+ try {
+ double d = Double.parseDouble(s);
+ if (d < min)
+ return "Value must be greater than or equal to " + min;
+ if (d > max)
+ return "Value must be less than or equal to " + max;
+ return null;
+ } catch (NumberFormatException e) {
+ return "Specified value is not a number";
+ }
+ }
+ }
+
+ @SCLValue(type = "ReadGraph -> Resource -> Variable -> b")
+ public static Object hueValidator(ReadGraph graph, Resource r, Variable context) throws DatabaseException {
+ return new RangeValidator(0, 360);
+ }
+
+ @SCLValue(type = "ReadGraph -> Resource -> Variable -> b")
+ public static Object saturationValidator(ReadGraph graph, Resource r, Variable context) throws DatabaseException {
+ return new RangeValidator(0, 100);
+ }
+
+ @SCLValue(type = "ReadGraph -> Resource -> Variable -> b")
+ public static Object brightnessValidator(ReadGraph graph, Resource r, Variable context) throws DatabaseException {
+ String importEntry = null;
+ Resource root = Variables.getPossibleIndexRoot(graph, context);
+ if (root != null) {
+ Resource sclmain = Layer0Utils.getPossibleChild(graph, root, "SCLMain");
+ if (sclmain != null) {
+ importEntry = graph.getPossibleURI(sclmain);
+ }
+ }
+ return new BrightnessExpressionValidator(
+ importEntry != null
+ ? Arrays.asList(importEntry)
+ : Collections.emptyList());
+ }
+
+ private static class BrightnessExpressionValidator implements Function1<String, String> {
+ private CommandSession session;
+
+ public BrightnessExpressionValidator(List<String> importEntries) {
+ this.session = new CommandSession(SCLOsgi.MODULE_REPOSITORY, SCLReportingHandler.DEFAULT);
+ this.session.setImportEntries(imports(importEntries));
+ }
+
+ private ArrayList<CommandSessionImportEntry> imports(List<String> entries) {
+ ArrayList<CommandSessionImportEntry> result = new ArrayList<>();
+ entries.stream().map(CommandSessionImportEntry::new).forEach(result::add);
+ if (entries.isEmpty())
+ result.add(new CommandSessionImportEntry("Simantics/District/SCLMain"));
+ return result;
+ }
+
+ @Override
+ public String apply(String s) {
+ s = s.trim();
+ if (!s.startsWith("="))
+ return "Expression expected, must start with '='";
+ CompilationError[] errors = session.validate(s.substring(1));
+ if(errors.length == 0)
+ return null;
+ return errors[0].description;
+ }
+ }
+
}
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
-import java.awt.Stroke;
import java.awt.geom.AffineTransform;
import java.awt.geom.Line2D;
import java.awt.geom.Path2D;
private static final long serialVersionUID = 8049769475036519806L;
- private static final Stroke SELECTION_STROKE = new BasicStroke(1f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER);
- private static final Color SELECTION_COLOR = new Color(255, 0, 255, 96);
+ private static final BasicStroke STROKE = new BasicStroke(4, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND);
+ private static final Color SELECTION_COLOR = new Color(255, 0, 255, 96);
private DistrictNetworkEdge edge;
private Rectangle2D bounds;
- private Line2D path;
+ private transient Line2D path;
- private static final BasicStroke STROKE = new BasicStroke(4, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND);
private boolean scaleStroke = true;
-
private Color color;
-
private Double stroke;
+ private transient Color dynamicColor = null;
@Override
public void init() {
Color oldColor = g2d.getColor();
BasicStroke oldStroke = (BasicStroke) g2d.getStroke();
- g2d.setColor(color);
BasicStroke bs = null;
if (scaleStroke) {
double scale = GeometryUtils.getScale(g2d.getTransform());
g2d.draw(path);
}
+ g2d.setColor(dynamicColor != null ? dynamicColor : color);
g2d.setStroke(bs);
g2d.draw(path);
this.stroke = stroke;
}
+ @PropertySetter(value = "dynamicColor")
+ public void setDynamicColor(Color color) {
+ this.dynamicColor = color;
+ }
+
}
package org.simantics.district.network.ui.nodes;
+import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import org.simantics.district.network.ModelledCRS;
import org.simantics.district.network.ui.adapters.DistrictNetworkVertex;
+import org.simantics.scenegraph.ISelectionPainterNode;
import org.simantics.scenegraph.g2d.G2DNode;
import org.simantics.scenegraph.utils.GeometryUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import org.simantics.scenegraph.utils.NodeUtil;
-public class DistrictNetworkVertexNode extends G2DNode {
+public class DistrictNetworkVertexNode extends G2DNode implements ISelectionPainterNode {
- private static final Logger LOGGER = LoggerFactory.getLogger(DistrictNetworkVertexNode.class);
+ //private static final Logger LOGGER = LoggerFactory.getLogger(DistrictNetworkVertexNode.class);
private static final long serialVersionUID = -2641639101400236719L;
- private DistrictNetworkVertex vertex;
+
+ private static final BasicStroke STROKE = new BasicStroke(4, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND);
+ private static final Color SELECTION_COLOR = new Color(255, 0, 255, 96);
private static final double left = -0.25;
private static final double top = -0.25;
private static final Rectangle2D NORMAL = new Rectangle2D.Double(left, top, width, height);
private static final Rectangle2D HOVERED = new Rectangle2D.Double(left * 3, top * 3, width * 3, height * 3);
+ private DistrictNetworkVertex vertex;
+
private boolean scaleStroke = true;
private boolean hover;
private Color color;
+ private transient Color dynamicColor;
private Rectangle2D bounds;
}
Color oldColor = g2d.getColor();
- g2d.setColor(color);
double scaleRecip = 1;
if (scaleStroke) {
} else {
toDraw = new Rectangle2D.Double(res.getX() - (NORMAL.getWidth() / 2 * scaleRecip), res.getY() - (NORMAL.getHeight() / 2 * scaleRecip), NORMAL.getWidth() * scaleRecip, NORMAL.getHeight() * scaleRecip);
}
+
+ if (NodeUtil.isSelected(this, 1)) {
+ g2d.setColor(SELECTION_COLOR);
+ BasicStroke ss = GeometryUtils.scaleStroke(STROKE, (float) scaleRecip*2);
+ g2d.setStroke(ss);
+ g2d.draw(toDraw);
+ }
+
// render
+ g2d.setColor(dynamicColor != null ? dynamicColor : color);
g2d.fill(toDraw);
// Reset settings
updateBounds();
}
+ @PropertySetter(value = "dynamicColor")
+ public void setDynamicColor(Color color) {
+ this.dynamicColor = color;
+ }
+
}
</type>
</target>
<target interface="org.simantics.scenegraph.profile.Style">
+ <resource uri="http://www.simantics.org/DistrictNetwork-1.0/ElementColoringStyle"
+ class="org.simantics.district.network.profile.DNElementColorStyle">
+ </resource>
<resource uri="http://www.simantics.org/DistrictNetwork-1.0/VertexSizeStyle"
class="org.simantics.district.network.profile.VertexSizeStyle">
</resource>
import "Simantics/DB"
import "Simantics/Ontologies"
+import "Simantics/Variables"
+import "http://www.simantics.org/DistrictNetwork-1.0" as DN
import "Map" as Map
import "MSet" as MSet
createVertex :: Resource -> Vector Double -> Resource -> <WriteGraph, Proc> Resource
createEdge :: Resource -> Resource -> <WriteGraph, Proc> Resource
+"""
+Tries to look for the Variable representing the configuration component
+mapped to the specified district network diagram element.
+
+The variable returned is by default the active experiment context variable
+but if that is not available then a configuration context variable is returned.
+"""
+possibleMappedComponentVariable :: Resource -> <ReadGraph> Maybe Variable
+possibleMappedComponentVariable r = match possibleObject r DN.MappedComponent with
+ Nothing -> Nothing
+ Just me -> match possibleObject me MOD.ElementToComponent with
+ Nothing -> Nothing
+ Just mc -> do
+ mcv = resourceVariable mc
+ match possibleActiveVariable mcv with
+ Nothing -> Just mcv
+ a -> a
+
+"""
+"""
+possibleMappedComponentPropertyValue :: String -> Resource -> <ReadGraph> Maybe Double
+possibleMappedComponentPropertyValue propName r = match possibleMappedComponentVariable r with
+ Nothing -> Nothing
+ Just mv -> possiblePropertyValue mv propName
+
+"""
+"""
+mappedComponentPropertyValue :: Double -> String -> Resource -> <ReadGraph> Double
+mappedComponentPropertyValue def propName r = match possibleMappedComponentVariable r with
+ Nothing -> def
+ Just mv -> match possiblePropertyValue mv propName with
+ Nothing -> def
+ Just v -> v
--- /dev/null
+package org.simantics.district.network.profile;
+
+import java.awt.Color;
+
+/**
+ * @author Tuukka Lehtonen
+ */
+@FunctionalInterface
+public interface ColorGradient {
+
+ /**
+ * Applies this function to the given argument.
+ *
+ * @param t the function argument
+ * @return the function result
+ */
+ Color get(double t);
+
+}
\ No newline at end of file
--- /dev/null
+package org.simantics.district.network.profile;
+
+import java.awt.Color;
+
+/**
+ * @author Tuukka Lehtonen
+ * @since 1.35.0
+ */
+public class Colors {
+
+ private static class Cache implements ColorGradient {
+ private final ColorGradient proxy;
+ private final int discretization;
+ private final Color[] cache;
+
+ public Cache(ColorGradient proxy, int discretization) {
+ this.proxy = proxy;
+ this.discretization = discretization;
+ this.cache = new Color[discretization+1];
+ }
+
+ private int discretize(double t) {
+ return (int) (saturate(t) * discretization);
+ }
+
+ @Override
+ public Color get(double t) {
+ int d = discretize(t);
+ Color cached = cache[d];
+ if (cached != null)
+ return cached;
+ cached = cache[d] = proxy.get(t);
+ return cached;
+ }
+ }
+
+ public static final ColorGradient cached(ColorGradient cg) {
+ return new Cache(cg, 512);
+ }
+
+ public static final ColorGradient hsvGradient(float hue, float saturation) {
+ return t -> {
+ return Color.getHSBColor(hue, saturation, saturate((float) t));
+ };
+ }
+
+ private static float saturate(float t) {
+ return Math.max(0f, Math.min(t, 1f));
+ }
+
+ private static double saturate(double t) {
+ return Math.max(0, Math.min(t, 1));
+ }
+
+}
--- /dev/null
+package org.simantics.district.network.profile;
+
+import java.awt.Color;
+
+import org.simantics.Simantics;
+import org.simantics.db.ReadGraph;
+import org.simantics.db.Resource;
+import org.simantics.db.common.procedure.adapter.TransientCacheAsyncListener;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.diagram.profile.StyleBase;
+import org.simantics.scenegraph.INode;
+import org.simantics.scenegraph.g2d.nodes.SingleElementNode;
+import org.simantics.scenegraph.profile.EvaluationContext;
+import org.simantics.scenegraph.profile.common.ProfileVariables;
+
+/**
+ * @author Tuukka Lehtonen
+ * @since 1.35.0
+ */
+public class DNElementColorStyle extends StyleBase<Color> {
+
+ private static final boolean DEBUG = false;
+
+ @Override
+ public Color calculateStyle(ReadGraph graph, Resource runtimeDiagram, Resource entry, Resource groupItem) throws DatabaseException {
+ DiagramSettings ds = graph.syncRequest(new DiagramSettingsRequest(runtimeDiagram), TransientCacheAsyncListener.instance());
+ if (ds.elementColoringFunction.isPresent()) {
+ if (DEBUG)
+ System.out.print("elementColoringFunction: " + ds.elementColoringFunction + "(" + groupItem + "): ");
+ Double t = Simantics.applySCLRead(graph, ds.elementColoringFunction.get(), groupItem);
+ if (DEBUG)
+ System.out.print(t);
+ if (t != null) {
+ Color result = ds.coloringGradient.get(t);
+ //System.out.println("color(" + t + "): " + result);
+ return result;
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public void applyStyleForNode(EvaluationContext observer, INode node, Color color) {
+ SingleElementNode n = (SingleElementNode) node;
+ for (INode nn : n.getNodes())
+ ProfileVariables.claimNodeProperty(nn, "dynamicColor", color, observer);
+ }
+
+ @Override
+ protected void cleanupStyleForNode(EvaluationContext evaluationContext, INode node) {
+ SingleElementNode n = (SingleElementNode) node;
+ for (INode nn : n.getNodes())
+ ProfileVariables.claimNodeProperty(nn, "dynamicColor", null, evaluationContext);
+ }
+
+}
public final Optional<Function1<Resource, Double>> edgeThicknessProperty;
public final double edgeThicknessGain;
public final double edgeThicknessBias;
+ public final Optional<Function1<Resource, Double>> elementColoringFunction;
+ public final float elementColoringGradientHue;
+ public final float elementColoringGradientSaturation;
+ public final transient ColorGradient coloringGradient;
- public DiagramSettings(Function1<Resource, Double> vertexScaleProperty, double vertexScaleGain, double vertexScaleBias, Function1<Resource, Double> edgeThicknessProperty, double edgeThicknessGain, double edgeThicknessBias) {
+ public DiagramSettings(
+ Function1<Resource, Double> vertexScaleProperty, double vertexScaleGain, double vertexScaleBias,
+ Function1<Resource, Double> edgeThicknessProperty, double edgeThicknessGain, double edgeThicknessBias,
+ Function1<Resource, Double> elementColoringFunction,
+ float elementColoringGradientHue,
+ float elementColoringGradientSaturation
+ ) {
this.vertexScaleProperty = Optional.ofNullable(vertexScaleProperty);
this.vertexScaleGain = vertexScaleGain;
this.vertexScaleBias = vertexScaleBias;
this.edgeThicknessProperty = Optional.ofNullable(edgeThicknessProperty);
this.edgeThicknessGain = edgeThicknessGain;
this.edgeThicknessBias = edgeThicknessBias;
+ this.elementColoringFunction = Optional.ofNullable(elementColoringFunction);
+ this.elementColoringGradientHue = elementColoringGradientHue;
+ this.elementColoringGradientSaturation = elementColoringGradientSaturation;
+ this.coloringGradient = Colors.cached(
+ Colors.hsvGradient(
+ elementColoringGradientHue,
+ elementColoringGradientSaturation)
+ );
}
@Override
result = prime * result + (int) (temp ^ (temp >>> 32));
temp = Double.doubleToLongBits(vertexScaleBias);
result = prime * result + (int) (temp ^ (temp >>> 32));
+ result = prime * result + elementColoringFunction.hashCode();
+ result = prime * result + Float.floatToIntBits(elementColoringGradientHue);
+ result = prime * result + Float.floatToIntBits(elementColoringGradientSaturation);
return result;
}
return false;
if (Double.doubleToLongBits(vertexScaleBias) != Double.doubleToLongBits(other.vertexScaleBias))
return false;
+ if (!elementColoringFunction.equals(other.elementColoringFunction))
+ return false;
+ if (Float.floatToIntBits(elementColoringGradientHue) != Float.floatToIntBits(other.elementColoringGradientHue))
+ return false;
+ if (Float.floatToIntBits(elementColoringGradientSaturation) != Float.floatToIntBits(other.elementColoringGradientSaturation))
+ return false;
return true;
}
@Override
public String toString() {
- return String.format("DiagramSettings[%s * %f + %f - %s * %f + %f]", vertexScaleProperty.toString(),
- vertexScaleGain, vertexScaleBias, edgeThicknessProperty, edgeThicknessGain, edgeThicknessBias);
+ return String.format("DiagramSettings[%s * %f + %f - %s * %f + %f - coloringFunction: %s, hue: %f, saturation: %f]",
+ vertexScaleProperty.toString(), vertexScaleGain, vertexScaleBias,
+ edgeThicknessProperty, edgeThicknessGain, edgeThicknessBias,
+ elementColoringFunction.toString(),
+ elementColoringGradientHue, elementColoringGradientSaturation
+ );
}
}
super(runtimeDiagram);
}
- @Override
+ @SuppressWarnings("unchecked")
+ @Override
public DiagramSettings perform(ReadGraph graph) throws DatabaseException {
DiagramResource DIA = DiagramResource.getInstance(graph);
DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph);
+ Function1<Resource, Double> elementColoringFunction = null;
+ float elementColoringGradientHue = 0;
+ float elementColoringGradientSaturation = 1;
Function1<Resource, Double> edgeThicknessProperty = null;
Function1<Resource, Double> nodeScaleProperty = null;
double edgeThicknessGain = 1;
Resource diagram = graph.getPossibleObject(resource, DIA.RuntimeDiagram_HasConfiguration);
if (diagram != null) {
+ Variable dv = Variables.getPossibleVariable(graph, diagram);
+ if (dv != null) {
+ Object obj = dv.getPossiblePropertyValue(graph, DN.Diagram_elementColoringFunction);
+ if (obj instanceof Function1<?,?>) {
+ elementColoringFunction = (Function1<Resource, Double>) obj;
+ }
+ }
+ elementColoringGradientHue =
+ limit(0, 360, safeFloatProperty(graph, diagram, DN.Diagram_elementColoringGradientHue, 0.0f))
+ / 360.0f;
+ elementColoringGradientSaturation =
+ limit(0, 100, safeFloatProperty(graph, diagram, DN.Diagram_elementColoringGradientSaturation, 0.0f))
+ / 100.0f;
+
Resource etp = graph.getPossibleObject(diagram, DN.Diagram_edgeThicknessProperty);
//System.out.println("etp: " + NameUtils.getURIOrSafeNameInternal(graph, etp));
if (etp != null) {
DiagramSettings ds = new DiagramSettings(
nodeScaleProperty, nodeScaleGain, nodeScaleBias,
- edgeThicknessProperty, edgeThicknessGain, edgeThicknessBias);
+ edgeThicknessProperty, edgeThicknessGain, edgeThicknessBias,
+ elementColoringFunction,
+ elementColoringGradientHue,
+ elementColoringGradientSaturation);
//System.out.println("new diagram settings: " + ds);
return ds;
}
+ private static float safeFloatProperty(ReadGraph graph, Resource r, Resource property, float defaultValue) throws DatabaseException {
+ Float d = graph.getPossibleRelatedValue(r, property, Bindings.FLOAT);
+ return d != null ? d : defaultValue;
+ }
+
private static double safeDoubleProperty(ReadGraph graph, Resource r, Resource property, double defaultValue) throws DatabaseException {
Double d = graph.getPossibleRelatedValue(r, property, Bindings.DOUBLE);
return d != null ? d : defaultValue;
}
+ private static float limit(float min, float max, float value) {
+ return Math.max(min, Math.min(value, max));
+ }
+
+ @SuppressWarnings("unused")
+ private static double limit(double min, double max, double value) {
+ return Math.max(min, Math.min(value, max));
+ }
+
}