package org.simantics.district.network.ui.nodes; import java.awt.AlphaComposite; import java.awt.Color; import java.awt.Font; import java.awt.Graphics2D; import java.awt.geom.AffineTransform; import java.awt.geom.Rectangle2D; import java.util.List; import java.util.Map; import java.util.Map.Entry; 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.DynamicColorMap.RGBIntensity; import org.simantics.district.network.visualisations.model.DynamicSizeContribution; import org.simantics.district.network.visualisations.model.DynamicSizeMap; 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.scenegraph.g2d.G2DNode; import org.simantics.scenegraph.utils.DPIUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class DynamicVisualisationContributionsNode extends G2DNode { private static final Logger LOGGER = LoggerFactory.getLogger(DynamicVisualisationContributionsNode.class); public static final String ID = "dynamicVisualisationContributionsNode"; private static final long serialVersionUID = 7400966702826774761L; protected boolean enabled = true; private Map dynamicColoringContributions; private Map dynamicSizingContributions; private ColorBarOptions colorBarsOptions = ColorBarOptions.useDefault(); private SizeBarOptions sizeBarsOptions = SizeBarOptions.useDefault(); @Override public void render(Graphics2D g2d) { if (!enabled) return; AffineTransform ot = g2d.getTransform(); Color oldColor = g2d.getColor(); try { g2d.transform(transform); g2d.setTransform(new AffineTransform()); Rectangle2D bounds = g2d.getClipBounds(); if (bounds == null) return; // FIXME renderColors(g2d); renderSizes(g2d); } finally { g2d.setColor(oldColor); g2d.setTransform(ot); } } private double colorBarBoxWidth = 300; private double colorBarBoxHeight = 50; private double colorBarBoxPadding = 20; private void renderColors(Graphics2D g2d) { if (colorBarsOptions == null || !colorBarsOptions.isShowColorBars()) { return; } ColorBarsLocation location = colorBarsOptions.getLocation(); ColorBarsSize size = colorBarsOptions.getSize(); double colorBarBoxLeft = getColorBarBoxLeft(g2d, location, size); double colorBarBoxTopInitial = getColorBarBoxTop(g2d, location, size); double colorBarBoxWidth = getColorBarBoxWidth(size); double colorBarBoxHeight = getColorBarBoxHeight(size); Rectangle2D bounds = g2d.getClipBounds(); if (bounds == null) return; // FIXME int i = 0; if (dynamicColoringContributions != null) { for (Entry object : dynamicColoringContributions.entrySet()) { DynamicColorContribution cc = object.getValue(); if (!cc.isUsed()) continue; double min = cc.getDefaultMin(); double max = cc.getDefaultMax(); String unit = cc.getUnit(); String label = cc.getLabel(); DynamicColorMap map = cc.getDefaultColorMap(); double colorBarBoxTop = (colorBarBoxTopInitial + (colorBarBoxHeight * i)); i++; g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.8f)); g2d.setColor(new Color(0.9f, 0.9f, 0.9f, 0.95f)); Rectangle2D vertical = new Rectangle2D.Double(colorBarBoxLeft, colorBarBoxTop, colorBarBoxWidth, colorBarBoxHeight); g2d.fill(vertical); double colorVerticalLeft = colorBarBoxLeft + 5; double colorVerticalTop = colorBarBoxTop + 15; double colorVerticalHeigth = colorBarBoxHeight - 30; List intensities = map.getIntensities(); double colorVerticalWidth = (colorBarBoxWidth - 10) / intensities.size(); Font rulerFont = new Font("Tahoma", Font.PLAIN, DPIUtil.upscale(9)); g2d.setFont(rulerFont); double interval = (max - min) / intensities.size(); for (int j = 0; j < intensities.size(); j++) { RGBIntensity intensity = intensities.get(j); if (colorBarsOptions.isUseGradients()) { RGBIntensity upperLimitIntensity; if (j + 1 != intensities.size()) upperLimitIntensity = intensities.get(j + 1); else upperLimitIntensity = intensity; double minRed = intensity.getRed(); double minGreen = intensity.getGreen(); double minBlue = intensity.getBlue(); double maxRed = upperLimitIntensity.getRed(); double maxGreen = upperLimitIntensity.getGreen(); double maxBlue = upperLimitIntensity.getBlue(); double redDelta = (maxRed - minRed) / colorVerticalWidth; double greenDelta = (maxGreen - minGreen) / colorVerticalWidth; double blueDelta = (maxBlue - minBlue) / colorVerticalWidth; for (int k = 0; k < colorVerticalWidth; k++) { g2d.setColor(new Color((float)(minRed + (k * redDelta)), (float)(minGreen + (k * greenDelta)), (float)(minBlue + (k * blueDelta)), 1f)); Rectangle2D colorVertical = new Rectangle2D.Double(colorVerticalLeft + k, colorVerticalTop, 1, colorVerticalHeigth); g2d.fill(colorVertical); } } else { g2d.setColor(new Color((float)intensity.getRed(), (float)intensity.getGreen(), (float)intensity.getBlue(), 1f)); Rectangle2D colorVertical = new Rectangle2D.Double(colorVerticalLeft, colorVerticalTop, colorVerticalWidth, colorVerticalHeigth); g2d.fill(colorVertical); } double value = min + j * interval; String str = Double.toString(value); if (str.length() > 4) { str = str.substring(0, 3); } g2d.setColor(Color.BLACK); g2d.drawString(str, (float)(colorVerticalLeft - 8), (float)(colorBarBoxTop + colorBarBoxHeight)); colorVerticalLeft = colorVerticalLeft + colorVerticalWidth; } g2d.setColor(Color.BLACK); String str = Double.toString(max); g2d.drawString(str, (float)(colorVerticalLeft - 8), (float)(colorBarBoxTop + colorBarBoxHeight)); str = object.getKey() + " - " + label + " [" + unit + "]"; g2d.drawString(str, (float)colorBarBoxLeft + 5, (float)colorBarBoxTop + 10); } } } private double getColorBarBoxTop(Graphics2D g2d, ColorBarsLocation location, ColorBarsSize size) { Rectangle2D bounds = g2d.getClipBounds(); if (bounds == null) throw new IllegalStateException(); switch (location) { case NORTH: { return colorBarBoxPadding; } case SOUTH: { return bounds.getMaxY() - colorBarBoxPadding; } case EAST: case WEST: { return (bounds.getMaxY() / 2) - (getColorBarBoxHeight(size) / 2); } default: return 0; } } private double getColorBarBoxLeft(Graphics2D g2d, ColorBarsLocation location, ColorBarsSize size) { Rectangle2D bounds = g2d.getClipBounds(); if (bounds == null) throw new IllegalStateException(); switch (location) { case EAST: { double right = bounds.getMaxX() - colorBarBoxPadding; return right - getColorBarBoxWidth(size); } case WEST: { return colorBarBoxPadding; } case NORTH: case SOUTH: { double left = (bounds.getMaxX() / 2) - (getColorBarBoxWidth(size) / 2); return left; } default: return 0; } } private double getColorBarBoxWidth(ColorBarsSize size) { return size.getSize() * colorBarBoxWidth; } private double getColorBarBoxHeight(ColorBarsSize size) { return size.getSize() * colorBarBoxHeight; } private void renderSizes(Graphics2D g2d) { if (sizeBarsOptions == null || !sizeBarsOptions.isShowSizeBars()) { return; } SizeBarsLocation location = sizeBarsOptions.getLocation(); SizeBarsSize sizeb = sizeBarsOptions.getSize(); double sizeBarBoxLeft = getSizeBarBoxLeft(g2d, location, sizeb); double sizeBarBoxTopInitial = getSizeBarBoxTop(g2d, location, sizeb); double sizeBarBoxWidth = getSizeBarBoxWidth(sizeb); double sizeBarBoxHeight = getSizeBarBoxHeight(sizeb); Rectangle2D bounds = g2d.getClipBounds(); if (bounds == null) return; // FIXME int i = 0; if (dynamicSizingContributions != null) { for (Entry object : dynamicSizingContributions.entrySet()) { DynamicSizeContribution cc = object.getValue(); if (!cc.isUsed()) continue; double min = cc.getDefaultMin(); double max = cc.getDefaultMax(); String unit = cc.getUnit(); String label = cc.getLabel(); DynamicSizeMap map = cc.getDefaultSizeMap(); List sizes = map.getSizes(); double sizeBarBoxTop = (sizeBarBoxTopInitial + (colorBarBoxHeight * i)); i++; g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.8f)); g2d.setColor(new Color(0.9f, 0.9f, 0.9f, 0.95f)); Rectangle2D vertical = new Rectangle2D.Double(sizeBarBoxLeft, sizeBarBoxTop, colorBarBoxWidth, colorBarBoxHeight); g2d.fill(vertical); double sizeVerticalLeft = sizeBarBoxLeft + 5; double sizeVerticalTop = sizeBarBoxTop + 15; double sizeVerticalHeigth = colorBarBoxHeight - 30; double sizeVerticalWidth = (sizeBarBoxWidth - 10) / sizes.size(); Font rulerFont = new Font("Tahoma", Font.PLAIN, DPIUtil.upscale(9)); g2d.setFont(rulerFont); double interval = (max - min) / sizes.size(); for (int j = 0; j < sizes.size(); j++) { Double size = sizes.get(j); g2d.setColor(new Color((float)0, (float)0, (float)0.8, 0.8f)); double sizedWidth = (size / 5) * sizeVerticalHeigth; Rectangle2D rect = new Rectangle2D.Double(sizeVerticalLeft, (sizeVerticalTop), sizedWidth, sizeVerticalHeigth); g2d.fill(rect); double value = min + j * interval; String str = Double.toString(value); if (str.length() > 4) { str = str.substring(0, 3); } g2d.setColor(Color.BLACK); g2d.drawString(str, (float)(sizeVerticalLeft - 8), (float)(sizeBarBoxTop + sizeBarBoxHeight)); sizeVerticalLeft = sizeVerticalLeft + sizeVerticalWidth; } g2d.setColor(Color.BLACK); String str = Double.toString(max); g2d.drawString(str, (int)(sizeBarBoxLeft + sizeBarBoxWidth - 30), (int)(sizeBarBoxTop + sizeBarBoxHeight)); str = object.getKey() + " - " + label + " [" + unit + "]"; g2d.drawString(str, (int)sizeBarBoxLeft + 5, (int)sizeBarBoxTop + 10); } } } private double getSizeBarBoxTop(Graphics2D g2d, SizeBarsLocation location, SizeBarsSize size) { Rectangle2D bounds = g2d.getClipBounds(); if (bounds == null) throw new IllegalStateException(); switch (location) { case NORTH: { return colorBarBoxPadding; } case SOUTH: { return bounds.getMaxY() - colorBarBoxPadding; } case EAST: case WEST: { return (bounds.getMaxY() / 2) - (getSizeBarBoxHeight(size) / 2); } default: return 0; } } private double getSizeBarBoxLeft(Graphics2D g2d, SizeBarsLocation location, SizeBarsSize size) { Rectangle2D bounds = g2d.getClipBounds(); if (bounds == null) throw new IllegalStateException(); switch (location) { case EAST: { double right = bounds.getMaxX() - colorBarBoxPadding; return right - getSizeBarBoxWidth(size); } case WEST: { return colorBarBoxPadding; } case NORTH: case SOUTH: { double left = (bounds.getMaxX() / 2) - (getSizeBarBoxWidth(size) / 2); return left; } default: return 0; } } private double getSizeBarBoxWidth(SizeBarsSize size) { return size.getSize() * colorBarBoxWidth; } private double getSizeBarBoxHeight(SizeBarsSize size) { return size.getSize() * colorBarBoxHeight; } @Override public Rectangle2D getBoundsInLocal() { return null; } public void setEnabled(boolean enabled) { this.enabled = enabled; } public void setDynamicColoringObjects(Map dynamicColoringObjects) { this.dynamicColoringContributions = dynamicColoringObjects; } public void setColorBarOptions(ColorBarOptions colorBarsOptions) { this.colorBarsOptions = colorBarsOptions; } public void setDynamicSizingObjects(Map dynamicSizingObjects) { this.dynamicSizingContributions = dynamicSizingObjects; } public void setSizeBarOptions(SizeBarOptions sizeBarOptions) { this.sizeBarsOptions = sizeBarOptions; } }