package org.simantics.district.network.profile; import java.awt.Color; import java.util.Map; import org.simantics.databoard.Bindings; 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.db.layer0.variable.Variable; import org.simantics.db.layer0.variable.Variables; import org.simantics.district.network.ontology.DistrictNetworkResource; import org.simantics.district.network.visualisations.DynamicVisualisationsContributions.DynamicColoringObject; import org.simantics.district.network.visualisations.model.DynamicColorContribution; import org.simantics.district.network.visualisations.model.DynamicColorMap; import org.simantics.district.network.visualisations.model.DynamicVisualisation; import org.simantics.layer0.Layer0; import org.simantics.modeling.ModelingResources; 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; import org.simantics.scl.runtime.SCLContext; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * @author Tuukka Lehtonen * @since 1.35.0 */ public class DNElementColorStyle extends ThrottledStyleBase { private static final Logger LOGGER = LoggerFactory.getLogger(DNElementColorStyle.class); private static final boolean DEBUG = false; @Override public Color calculateThrottledStyle(ReadGraph graph, Resource runtimeDiagram, Resource entry, Resource groupItem) throws DatabaseException { DynamicVisualisation dv = graph.syncRequest(new RuntimeDynamicVisualisationsRequest(runtimeDiagram), TransientCacheAsyncListener.instance()); // Prevent PendingVariableExceptions from coming through boolean wasSynchronous = graph.setSynchronous(true); try { if (dv != null) { Layer0 L0 = Layer0.getInstance(graph); DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph); ModelingResources MOD = ModelingResources.getInstance(graph); Resource mapping = graph.getSingleObject(groupItem, DN.HasMapping); Map colorContributions = dv.getColorContributions(); String mappingName = graph.getRelatedValue(mapping, L0.HasName); DynamicColorContribution dcc = colorContributions.get(mappingName); if (dcc != null && dcc.isUsed()) { Resource mappedComponent = graph.getPossibleObject(groupItem, DN.MappedComponent); if (mappedComponent != null) { Resource component = graph.getSingleObject(mappedComponent, MOD.ElementToComponent); Variable variable = Variables.getVariable(graph, component); Variable possibleActiveVariable = Variables.possibleActiveVariable(graph, variable); if (possibleActiveVariable != null) { Variable module = possibleActiveVariable.getPossibleChild(graph, dcc.getModuleName()); if (module != null) { Variable attribute = module.getPossibleProperty(graph, dcc.getAttributeName()); if (attribute != null) { Double possibleValue = attribute.getPossibleValue(graph, Bindings.DOUBLE); if (possibleValue != null) { double minValue; double maxValue; if (dcc.isUseDefault()) { DynamicColoringObject dynamicColoringObject = dv.getDefaultColorContributions().get(mappingName); // This is required if ontology module needs to be compiled Object currentGraph = SCLContext.getCurrent().get("graph"); try { SCLContext.getCurrent().put("graph", graph); DynamicColorContribution ddcc = dynamicColoringObject.getColorContributions().get(dcc.getLabel()); minValue = ddcc.getDefaultMin(); maxValue = ddcc.getDefaultMax(); } finally { SCLContext.getCurrent().put("graph", currentGraph); } } else { minValue = dcc.getDefaultMin(); maxValue = dcc.getDefaultMax(); } // here we do the adjusting according to spec in #15038 double adjustedValue = possibleValue.doubleValue() * dcc.getVariableGain() + dcc.getVariableBias(); DynamicColorMap defaultColorMap = dcc.getDefaultColorMap(); Color color = defaultColorMap.getColor(adjustedValue, dv.getColorBarOptions().isUseGradients(), minValue, maxValue); return color; } else { LOGGER.warn("No value for {}", attribute.getURI(graph)); } } else { LOGGER.warn("Wrong attribute name {} for {} !!", dcc.getAttributeName(), module.getURI(graph)); } } else { LOGGER.warn("Wrong modulename {} for {} !!", dcc.getModuleName(), possibleActiveVariable.getURI(graph)); } } else { LOGGER.debug("No active experiment for {}", variable.getURI(graph)); } } else { LOGGER.debug("No mapped component for {} to calculate dynamic color style", groupItem); } } } } finally { graph.setSynchronous(wasSynchronous); } return null; } @Override public void applyThrottledStyleForNode(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); } }