Search in sources :

Example 1 with FlowKey

use of org.jfree.data.flow.FlowKey in project ES-LEI-2Sem-2022-Grupo-1 by tmrbo-iscte.

the class FlowPlot method draw.

/**
 * Draws the flow plot within the specified area of the supplied graphics
 * target {@code g2}.
 *
 * @param g2  the graphics target ({@code null} not permitted).
 * @param area  the plot area ({@code null} not permitted).
 * @param anchor  the anchor point (ignored).
 * @param parentState  the parent state (ignored).
 * @param info  the plot rendering info.
 */
@Override
public void draw(Graphics2D g2, Rectangle2D area, Point2D anchor, PlotState parentState, PlotRenderingInfo info) {
    Args.nullNotPermitted(g2, "g2");
    Args.nullNotPermitted(area, "area");
    EntityCollection entities = null;
    if (info != null) {
        info.setPlotArea(area);
        entities = info.getOwner().getEntityCollection();
    }
    RectangleInsets insets = getInsets();
    insets.trim(area);
    if (info != null) {
        info.setDataArea(area);
    }
    // use default JFreeChart background handling
    drawBackground(g2, area);
    // we need to ensure there is space to show all the inflows and all
    // the outflows at each node group, so first we calculate the max
    // flow space required - for each node in the group, consider the
    // maximum of the inflow and the outflow
    double flow2d = Double.POSITIVE_INFINITY;
    double nodeMargin2d = this.nodeMargin * area.getHeight();
    int stageCount = this.dataset.getStageCount();
    for (int stage = 0; stage < this.dataset.getStageCount(); stage++) {
        List<Comparable> sources = this.dataset.getSources(stage);
        int nodeCount = sources.size();
        double flowTotal = 0.0;
        for (Comparable source : sources) {
            double inflow = FlowDatasetUtils.calculateInflow(this.dataset, source, stage);
            double outflow = FlowDatasetUtils.calculateOutflow(this.dataset, source, stage);
            flowTotal = flowTotal + Math.max(inflow, outflow);
        }
        if (flowTotal > 0.0) {
            double availableH = area.getHeight() - (nodeCount - 1) * nodeMargin2d;
            flow2d = Math.min(availableH / flowTotal, flow2d);
        }
        if (stage == this.dataset.getStageCount() - 1) {
            // check inflows to the final destination nodes...
            List<Comparable> destinations = this.dataset.getDestinations(stage);
            int destinationCount = destinations.size();
            flowTotal = 0.0;
            for (Comparable destination : destinations) {
                double inflow = FlowDatasetUtils.calculateInflow(this.dataset, destination, stage + 1);
                flowTotal = flowTotal + inflow;
            }
            if (flowTotal > 0.0) {
                double availableH = area.getHeight() - (destinationCount - 1) * nodeMargin2d;
                flow2d = Math.min(availableH / flowTotal, flow2d);
            }
        }
    }
    double stageWidth = (area.getWidth() - ((stageCount + 1) * this.nodeWidth)) / stageCount;
    double flowOffset = area.getWidth() * this.flowMargin;
    Map<NodeKey, Rectangle2D> nodeRects = new HashMap<>();
    boolean hasNodeSelections = FlowDatasetUtils.hasNodeSelections(this.dataset);
    boolean hasFlowSelections = FlowDatasetUtils.hasFlowSelections(this.dataset);
    // in a final pass add the labels
    for (int stage = 0; stage < this.dataset.getStageCount(); stage++) {
        double stageLeft = area.getX() + (stage + 1) * this.nodeWidth + (stage * stageWidth);
        double stageRight = stageLeft + stageWidth;
        // calculate the source node and flow rectangles
        Map<FlowKey, Rectangle2D> sourceFlowRects = new HashMap<>();
        double nodeY = area.getY();
        for (Object s : this.dataset.getSources(stage)) {
            Comparable source = (Comparable) s;
            double inflow = FlowDatasetUtils.calculateInflow(dataset, source, stage);
            double outflow = FlowDatasetUtils.calculateOutflow(dataset, source, stage);
            double nodeHeight = (Math.max(inflow, outflow) * flow2d);
            Rectangle2D nodeRect = new Rectangle2D.Double(stageLeft - nodeWidth, nodeY, nodeWidth, nodeHeight);
            if (entities != null) {
                entities.add(new NodeEntity(new NodeKey<>(stage, source), nodeRect, source.toString()));
            }
            nodeRects.put(new NodeKey<>(stage, source), nodeRect);
            double y = nodeY;
            for (Object d : this.dataset.getDestinations(stage)) {
                Comparable destination = (Comparable) d;
                Number flow = this.dataset.getFlow(stage, source, destination);
                if (flow != null) {
                    double height = flow.doubleValue() * flow2d;
                    Rectangle2D rect = new Rectangle2D.Double(stageLeft - nodeWidth, y, nodeWidth, height);
                    sourceFlowRects.put(new FlowKey<>(stage, source, destination), rect);
                    y = y + height;
                }
            }
            nodeY = nodeY + nodeHeight + nodeMargin2d;
        }
        // calculate the destination rectangles
        Map<FlowKey, Rectangle2D> destFlowRects = new HashMap<>();
        nodeY = area.getY();
        for (Object d : this.dataset.getDestinations(stage)) {
            Comparable destination = (Comparable) d;
            double inflow = FlowDatasetUtils.calculateInflow(dataset, destination, stage + 1);
            double outflow = FlowDatasetUtils.calculateOutflow(dataset, destination, stage + 1);
            double nodeHeight = Math.max(inflow, outflow) * flow2d;
            nodeRects.put(new NodeKey<>(stage + 1, destination), new Rectangle2D.Double(stageRight, nodeY, nodeWidth, nodeHeight));
            double y = nodeY;
            for (Object s : this.dataset.getSources(stage)) {
                Comparable source = (Comparable) s;
                Number flow = this.dataset.getFlow(stage, source, destination);
                if (flow != null) {
                    double height = flow.doubleValue() * flow2d;
                    Rectangle2D rect = new Rectangle2D.Double(stageRight, y, nodeWidth, height);
                    y = y + height;
                    destFlowRects.put(new FlowKey<>(stage, source, destination), rect);
                }
            }
            nodeY = nodeY + nodeHeight + nodeMargin2d;
        }
        for (Object s : this.dataset.getSources(stage)) {
            Comparable source = (Comparable) s;
            NodeKey nodeKey = new NodeKey<>(stage, source);
            Rectangle2D nodeRect = nodeRects.get(nodeKey);
            Color ncol = lookupNodeColor(nodeKey);
            if (hasNodeSelections) {
                if (!Boolean.TRUE.equals(dataset.getNodeProperty(nodeKey, NodeKey.SELECTED_PROPERTY_KEY))) {
                    int g = (ncol.getRed() + ncol.getGreen() + ncol.getBlue()) / 3;
                    ncol = new Color(g, g, g, ncol.getAlpha());
                }
            }
            g2.setPaint(ncol);
            g2.fill(nodeRect);
            for (Object d : this.dataset.getDestinations(stage)) {
                Comparable destination = (Comparable) d;
                FlowKey flowKey = new FlowKey<>(stage, source, destination);
                Rectangle2D sourceRect = sourceFlowRects.get(flowKey);
                if (sourceRect == null) {
                    continue;
                }
                Rectangle2D destRect = destFlowRects.get(flowKey);
                Path2D connect = new Path2D.Double();
                connect.moveTo(sourceRect.getMaxX() + flowOffset, sourceRect.getMinY());
                connect.curveTo(stageLeft + stageWidth / 2.0, sourceRect.getMinY(), stageLeft + stageWidth / 2.0, destRect.getMinY(), destRect.getX() - flowOffset, destRect.getMinY());
                connect.lineTo(destRect.getX() - flowOffset, destRect.getMaxY());
                connect.curveTo(stageLeft + stageWidth / 2.0, destRect.getMaxY(), stageLeft + stageWidth / 2.0, sourceRect.getMaxY(), sourceRect.getMaxX() + flowOffset, sourceRect.getMaxY());
                connect.closePath();
                Color nc = lookupNodeColor(nodeKey);
                if (hasFlowSelections) {
                    if (!Boolean.TRUE.equals(dataset.getFlowProperty(flowKey, FlowKey.SELECTED_PROPERTY_KEY))) {
                        int g = (ncol.getRed() + ncol.getGreen() + ncol.getBlue()) / 3;
                        nc = new Color(g, g, g, ncol.getAlpha());
                    }
                }
                GradientPaint gp = new GradientPaint((float) sourceRect.getMaxX(), 0, nc, (float) destRect.getMinX(), 0, new Color(nc.getRed(), nc.getGreen(), nc.getBlue(), 128));
                Composite saved = g2.getComposite();
                g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.75f));
                g2.setPaint(gp);
                g2.fill(connect);
                if (entities != null) {
                    String toolTip = null;
                    if (this.toolTipGenerator != null) {
                        toolTip = this.toolTipGenerator.generateLabel(this.dataset, flowKey);
                    }
                    entities.add(new FlowEntity(flowKey, connect, toolTip, ""));
                }
                g2.setComposite(saved);
            }
        }
    }
    // now draw the destination nodes
    int lastStage = this.dataset.getStageCount() - 1;
    for (Object d : this.dataset.getDestinations(lastStage)) {
        Comparable destination = (Comparable) d;
        NodeKey nodeKey = new NodeKey<>(lastStage + 1, destination);
        Rectangle2D nodeRect = nodeRects.get(nodeKey);
        if (nodeRect != null) {
            Color ncol = lookupNodeColor(nodeKey);
            if (hasNodeSelections) {
                if (!Boolean.TRUE.equals(dataset.getNodeProperty(nodeKey, NodeKey.SELECTED_PROPERTY_KEY))) {
                    int g = (ncol.getRed() + ncol.getGreen() + ncol.getBlue()) / 3;
                    ncol = new Color(g, g, g, ncol.getAlpha());
                }
            }
            g2.setPaint(ncol);
            g2.fill(nodeRect);
            if (entities != null) {
                entities.add(new NodeEntity(new NodeKey<>(lastStage + 1, destination), nodeRect, destination.toString()));
            }
        }
    }
    // now draw all the labels over top of everything else
    g2.setFont(this.defaultNodeLabelFont);
    g2.setPaint(this.defaultNodeLabelPaint);
    for (NodeKey key : nodeRects.keySet()) {
        Rectangle2D r = nodeRects.get(key);
        if (key.getStage() < this.dataset.getStageCount()) {
            TextUtils.drawAlignedString(key.getNode().toString(), g2, (float) (r.getMaxX() + flowOffset + this.nodeLabelOffsetX), (float) labelY(r), TextAnchor.CENTER_LEFT);
        } else {
            TextUtils.drawAlignedString(key.getNode().toString(), g2, (float) (r.getX() - flowOffset - this.nodeLabelOffsetX), (float) labelY(r), TextAnchor.CENTER_RIGHT);
        }
    }
}
Also used : HashMap(java.util.HashMap) Path2D(java.awt.geom.Path2D) GradientPaint(java.awt.GradientPaint) FlowEntity(org.jfree.chart.entity.FlowEntity) NodeKey(org.jfree.data.flow.NodeKey) FlowKey(org.jfree.data.flow.FlowKey) AlphaComposite(java.awt.AlphaComposite) Composite(java.awt.Composite) Color(java.awt.Color) Rectangle2D(java.awt.geom.Rectangle2D) Paint(java.awt.Paint) GradientPaint(java.awt.GradientPaint) EntityCollection(org.jfree.chart.entity.EntityCollection) RectangleInsets(org.jfree.chart.api.RectangleInsets) NodeEntity(org.jfree.chart.entity.NodeEntity)

Example 2 with FlowKey

use of org.jfree.data.flow.FlowKey in project ES-LEI-2Sem-2022-Grupo-1 by tmrbo-iscte.

the class FlowEntityTest method testEquals.

/**
 * Confirm that the equals method can distinguish all the required fields.
 */
@Test
public void testEquals() {
    FlowEntity f1 = new FlowEntity(new FlowKey<>(0, "A", "B"), new Rectangle(0, 1, 2, 3), "tt", "uu");
    FlowEntity f2 = new FlowEntity(new FlowKey<>(0, "A", "B"), new Rectangle(0, 1, 2, 3), "tt", "uu");
    assertEquals(f1, f2);
    assertEquals(f2, f1);
    f1 = new FlowEntity(new FlowKey<>(0, "A", "C"), new Rectangle(0, 1, 2, 3), "tt", "uu");
    assertNotEquals(f1, f2);
    f2 = new FlowEntity(new FlowKey<>(0, "A", "C"), new Rectangle(0, 1, 2, 3), "tt", "uu");
    assertEquals(f1, f2);
    f1 = new FlowEntity(new FlowKey<>(0, "A", "C"), new Rectangle(4, 1, 2, 3), "tt", "uu");
    assertNotEquals(f1, f2);
    f2 = new FlowEntity(new FlowKey<>(0, "A", "C"), new Rectangle(4, 1, 2, 3), "tt", "uu");
    assertEquals(f1, f2);
    f1 = new FlowEntity(new FlowKey<>(0, "A", "C"), new Rectangle(4, 1, 2, 3), "TT", "uu");
    assertNotEquals(f1, f2);
    f2 = new FlowEntity(new FlowKey<>(0, "A", "C"), new Rectangle(4, 1, 2, 3), "TT", "uu");
    assertEquals(f1, f2);
    f1 = new FlowEntity(new FlowKey<>(0, "A", "C"), new Rectangle(4, 1, 2, 3), "TT", "UU");
    assertNotEquals(f1, f2);
    f2 = new FlowEntity(new FlowKey<>(0, "A", "C"), new Rectangle(4, 1, 2, 3), "TT", "UU");
    assertEquals(f1, f2);
}
Also used : FlowKey(org.jfree.data.flow.FlowKey) Rectangle(java.awt.Rectangle) Test(org.junit.jupiter.api.Test)

Aggregations

FlowKey (org.jfree.data.flow.FlowKey)2 AlphaComposite (java.awt.AlphaComposite)1 Color (java.awt.Color)1 Composite (java.awt.Composite)1 GradientPaint (java.awt.GradientPaint)1 Paint (java.awt.Paint)1 Rectangle (java.awt.Rectangle)1 Path2D (java.awt.geom.Path2D)1 Rectangle2D (java.awt.geom.Rectangle2D)1 HashMap (java.util.HashMap)1 RectangleInsets (org.jfree.chart.api.RectangleInsets)1 EntityCollection (org.jfree.chart.entity.EntityCollection)1 FlowEntity (org.jfree.chart.entity.FlowEntity)1 NodeEntity (org.jfree.chart.entity.NodeEntity)1 NodeKey (org.jfree.data.flow.NodeKey)1 Test (org.junit.jupiter.api.Test)1