Commit 6bededc4 authored by Nico Mack's avatar Nico Mack

Added support for Leader lines to ArcGraph

parent f8b6b714
......@@ -46,6 +46,7 @@ public class HtmlTemplate implements VariableBased {
public HtmlTemplate(String template) {
this.parameters = new HashMap<>();
this.chunks = new ArrayList<>();
this.template = template;
this.identifiers = Interpolator.extractVariableIdentifiers(this.template);
}
......
......@@ -51,9 +51,9 @@ public class Leader {
private Line2D.Double landingLine;
private String labelText;
private LineMetrics labelMetrics;
private Point labelPosition;
private Shape labelShape;
private Point labelPosition;
// ***************************************************************************
// * Constants *
......@@ -119,7 +119,7 @@ public class Leader {
// ---------------------------------------------------------------------------
public void updateLeader(float leaderAngle, String label) {
public void updateLeader(float leaderAngle) {
float inner = (float) radialOffset;
float outer = (float) (radialOffset + leaderLineLength);
......@@ -146,9 +146,15 @@ public class Leader {
}
if (shape != null) {
end.x += (flipped) ? -shape.getBounds2D().getWidth() : 0;
AffineTransform labelTransform = AffineTransform.getTranslateInstance(end.x, end.y);
labelShape = labelTransform.createTransformedShape(shape);
labelPosition = new Point(end.x, end.y, 0, ScreenCoordinates.class);
}
}
labelPosition = end.clone();
// ---------------------------------------------------------------------------
public void setLabel(String label) {
labelText = label;
if (this.labelFont != null) {
......@@ -160,31 +166,26 @@ public class Leader {
public void paint(Graphics2D canvas) {
AffineTransform transform = canvas.getTransform();
Graphics2D localCanvas = (Graphics2D) canvas.create();
localCanvas.setTransform(transform);
localCanvas.setPaint(this.strokeColour);
localCanvas.setStroke(this.lineStroke);
localCanvas.draw(this.leaderLine);
localCanvas.draw(this.landingLine);
if (this.shape != null) {
transform.translate(labelPosition.x, labelPosition.y);
localCanvas.setTransform(transform);
localCanvas.draw(this.shape);
if (this.labelShape != null) {
localCanvas.draw(labelShape);
if (this.fillColour != null) {
localCanvas.setPaint(this.fillColour);
localCanvas.fill(this.shape);
localCanvas.fill(labelShape);
}
}
if ((this.labelColour != null) && (this.labelText != null)) {
localCanvas.setPaint(labelColour);
localCanvas.setFont(labelFont);
localCanvas.translate(labelPosition.x, labelPosition.y);
localCanvas.drawString(labelText, 5, (labelMetrics.getAscent() / 2));
}
......
package lu.list.itis.dkd.tui.widget.corona;
import lu.list.itis.dkd.tui.cps.variable.NumericalVariable;
import lu.list.itis.dkd.tui.utility.AngleUtils;
import lu.list.itis.dkd.tui.utility.ColorPair;
import lu.list.itis.dkd.tui.utility.Leader;
import lu.list.itis.dkd.tui.utility.Point;
import lu.list.itis.dkd.tui.widget.corona.builder.ArcGraphBuilder;
import lu.list.itis.dkd.tui.utility.VariableFormat;
import lu.list.itis.dkd.tui.widget.corona.builder.BaseArcGraphBuilder;
import org.pushingpixels.trident.Timeline;
import org.pushingpixels.trident.Timeline.RepeatBehavior;
......@@ -35,30 +38,36 @@ import java.awt.geom.Rectangle2D;
// ***************************************************************************
public class ArcGraph extends ValueCorona {
private String title;
private double innerRadius;
private double outerRadius;
private int startAngle;
private int arcSpan;
private boolean relative;
private boolean cappedDisplay;
private boolean blinkOnOutOfRange;
private double reference;
private ColorPair fillColour;
private ColorPair strokeColour;
private ColorPair labelColour;
private ColorPair textColour;
private ColorPair faceColour;
private ColorPair bezelColour;
private Shape labelShape;
private Font textFont;
private Stroke borderStroke;
private int strokeWidth;
private int rampingTime;
// protected String title;
protected double innerRadius;
protected double outerRadius;
protected int startAngle;
protected int arcSpan;
protected boolean relative;
protected boolean cappedDisplay;
protected boolean blinkOnOutOfRange;
protected double reference;
protected ColorPair fillColour;
protected ColorPair strokeColour;
protected ColorPair labelColour;
protected ColorPair textColour;
protected ColorPair leaderColour;
protected ColorPair faceColour;
protected ColorPair bezelColour;
protected Shape labelShape;
protected String labelFormat;
protected Font textFont;
protected Stroke borderStroke;
protected int strokeWidth;
protected int leaderLineLength;
protected int landingLineLength;
protected VariableFormat variableFormat;
protected int rampingTime;
private Area outer;
private Area inner;
......@@ -66,6 +75,7 @@ public class ArcGraph extends ValueCorona {
private Area face;
private String label;
private LineMetrics labelMetrics;
private Leader leader;
protected Timeline blinkingTimeline;
protected Timeline balisticTimeline;
......@@ -81,10 +91,10 @@ public class ArcGraph extends ValueCorona {
// ***************************************************************************
// ---------------------------------------------------------------------------
public ArcGraph(ArcGraphBuilder builder) {
public ArcGraph(BaseArcGraphBuilder<?> builder) {
super(builder);
this.title = builder.title;
// this.title = builder.title;
this.startAngle = builder.startAngle;
this.arcSpan = builder.arcSpan;
......@@ -99,11 +109,15 @@ public class ArcGraph extends ValueCorona {
this.strokeColour = builder.strokeColour;
this.labelColour = builder.labelColour;
this.textColour = builder.textColour;
this.leaderColour = builder.leaderColour;
this.faceColour = builder.faceColour;
this.bezelColour = builder.bezelColour;
this.labelShape = builder.labelShape;
this.labelFormat = builder.labelFormat;
this.textFont = builder.textFont;
this.strokeWidth = builder.strokeWidth;
this.leaderLineLength = builder.leaderLineLength;
this.landingLineLength = builder.landingLineLength;
this.rampingTime = builder.rampingTime;
this.buildFromProperties();
......@@ -134,11 +148,15 @@ public class ArcGraph extends ValueCorona {
this.strokeColour = original.strokeColour;
this.labelColour = original.labelColour;
this.textColour = original.textColour;
this.leaderColour = original.leaderColour;
this.faceColour = original.faceColour;
this.bezelColour = original.bezelColour;
this.labelShape = original.labelShape;
this.labelFormat = original.labelFormat;
this.textFont = original.textFont;
this.strokeWidth = original.strokeWidth;
this.leaderLineLength = original.leaderLineLength;
this.landingLineLength = original.landingLineLength;
this.rampingTime = original.rampingTime;
this.buildFromProperties();
......@@ -163,6 +181,13 @@ public class ArcGraph extends ValueCorona {
diameter = 2 * outerRadius;
outer = new Area(new Ellipse2D.Double(-outerRadius, -outerRadius, diameter, diameter));
// Java Arc3D start angle and extend are expressed in counter clockwise rotation. Since
// TULIP follows the clockwise TUIO convention, we need to convert both startAngle and
// extend.
startAngle = ((int) AngleUtils.THREE_SIXTY - startAngle);
arcSpan = -arcSpan;
Shape sector = new Arc2D.Double(-outerRadius, -outerRadius, diameter, diameter, startAngle, arcSpan, Arc2D.PIE);
face = new Area(sector);
face.subtract(inner);
......@@ -177,8 +202,20 @@ public class ArcGraph extends ValueCorona {
labelShape = originTranslator.createTransformedShape(labelShape);
}
if ((this.labelFormat != null) && (!this.labelFormat.isEmpty())) {
this.variableFormat = new VariableFormat(this.labelFormat);
} else {
this.variableFormat = new VariableFormat("d f u"); //$NON-NLS-1$
}
borderStroke = (strokeWidth > 0) ? new BasicStroke(strokeWidth) : null;
if (leaderLineLength > 0) {
leader = new Leader(innerRadius, leaderLineLength, landingLineLength);
leader.setLabelShape(labelShape);
leader.setFont(textFont);
}
this.setInformation((relative) ? this.reference : this.variable.getValue());
}
......@@ -249,6 +286,8 @@ public class ArcGraph extends ValueCorona {
faceColour.setSwitched(selectIt);
if (bezelColour != null)
bezelColour.setSwitched(selectIt);
if (leaderColour != null)
leaderColour.setSwitched(selectIt);
}
}
......@@ -279,6 +318,12 @@ public class ArcGraph extends ValueCorona {
extend = arcSpan * normalizedValue;
}
if (leader != null) {
float leaderAngle = (float) -Math.toRadians(start + extend);
leader.updateLeader(leaderAngle);
}
if (blinkOnOutOfRange && reachedEndOfScale()) {
this.startBlinking();
} else {
......@@ -332,26 +377,44 @@ public class ArcGraph extends ValueCorona {
localCanvas.draw(arc);
}
if (this.opacity < 1.0f)
if (this.opacity < 1.0f) {
localCanvas.setComposite(AlphaComposite.SrcOver.derive(1.0f));
if ((labelShape != null) || (label.length() > 0)) {
Point labelOffset = this.getOffsetFromCenter();
translation.translate(labelOffset.x, labelOffset.y);
localCanvas.setTransform(translation);
}
if (labelShape != null) {
localCanvas.setPaint(labelColour.getColor());
localCanvas.fill(labelShape);
}
// Depending on whether we specified a leader or not, we're either
// painting the leader or the stationary graph label, but never both.
if ((leaderColour != null) && (this.leader != null)) {
// Paint the leader...
this.leader.setStrokeColour(leaderColour.getColor());
if (labelColour != null)
this.leader.setFillColour(labelColour.getColor());
if (textColour != null)
this.leader.setLabelColour(textColour.getColor());
this.leader.paint(localCanvas);
} else {
// Paint the stationary graph label
if ((labelShape != null) || (label.length() > 0)) {
Point labelOffset = this.getOffsetFromCenter();
translation.translate(labelOffset.x, labelOffset.y);
localCanvas.setTransform(translation);
}
if (textColour != null) {
localCanvas.setPaint(textColour.getColor());
localCanvas.setFont(textFont);
localCanvas.drawString(label, 5, (labelMetrics.getAscent() / 2));
if (labelShape != null) {
localCanvas.setPaint(labelColour.getColor());
localCanvas.fill(labelShape);
}
if (textColour != null) {
localCanvas.setPaint(textColour.getColor());
localCanvas.setFont(textFont);
localCanvas.drawString(label, 5, (labelMetrics.getAscent() / 2));
}
}
localCanvas.dispose();
}
......@@ -375,11 +438,15 @@ public class ArcGraph extends ValueCorona {
}
if (textFont != null) {
StringBuilder labelBuilder = new StringBuilder(this.title).append(" "); //$NON-NLS-1$
labelBuilder.append(this.variable.toString(this.cappedDisplay, true));
// StringBuilder labelBuilder = new StringBuilder(this.title).append(" "); //$NON-NLS-1$
// labelBuilder.append(this.variable.toString(this.cappedDisplay, true));
this.label = labelBuilder.toString();
this.label = this.variableFormat.format(this.variable);
this.labelMetrics = textFont.getLineMetrics(this.label, new FontRenderContext(null, true, true));
if (leader != null) {
leader.setLabel(label);
}
}
}
}
......
......@@ -77,7 +77,6 @@ public class ArcRangeGraph extends ValueRangeCorona {
protected Timeline blinkingTimeline;
protected Timeline balisticTimeline;
private float opacity;
private double shownLowerValue;
private double shownUpperValue;
......@@ -209,10 +208,10 @@ public class ArcRangeGraph extends ValueRangeCorona {
borderStroke = (strokeWidth > 0) ? new BasicStroke(strokeWidth) : null;
ValueRange range;
ValueRange<?> range;
range = (relative) ? new ValueRange(this.reference, this.reference)
: new ValueRange(this.lowerBoundVariable.getValue(), this.upperBoundVariable.getValue());
range = (relative) ? new ValueRange<>(this.reference, this.reference)
: new ValueRange<>(this.lowerBoundVariable.getValue(), this.upperBoundVariable.getValue());
lowerLeader = new Leader(innerRadius, leaderLineLength, landingLineLength);
lowerLeader.setLabelShape(labelShape);
......@@ -252,13 +251,15 @@ public class ArcRangeGraph extends ValueRangeCorona {
float lowerLeaderAngle = (float) -Math.toRadians(lowerAngle);
float upperLeaderAngle = (float) -Math.toRadians(upperAngle);
this.lowerLeader.updateLeader(lowerLeaderAngle, lowerValueLabel);
this.upperLeader.updateLeader(upperLeaderAngle, upperValueLabel);
this.lowerLeader.updateLeader(lowerLeaderAngle);
this.lowerLeader.setLabel(lowerValueLabel);
this.upperLeader.updateLeader(upperLeaderAngle);
this.upperLeader.setLabel(upperValueLabel);
}
// ---------------------------------------------------------------------------
private synchronized void updateArcFromValues(double lower, double upper) {
private synchronized void updateArcFromValues() {
if ((lowerBoundVariable == null) || (upperBoundVariable == null)) {
return;
......@@ -360,12 +361,6 @@ public class ArcRangeGraph extends ValueRangeCorona {
// ---------------------------------------------------------------------------
public void setOpacity(float newOpacity) {
this.opacity = newOpacity;
}
// ---------------------------------------------------------------------------
public void setLowerBound(double lower) {
shownLowerValue = lower;
}
......@@ -374,7 +369,7 @@ public class ArcRangeGraph extends ValueRangeCorona {
public void setUpperBound(double upper) {
shownUpperValue = upper;
this.updateArcFromValues(shownLowerValue, upper);
this.updateArcFromValues();
}
// ---------------------------------------------------------------------------
......@@ -455,7 +450,7 @@ public class ArcRangeGraph extends ValueRangeCorona {
// ---------------------------------------------------------------------------
@Override
public void setInformation(ValueRange information) {
public void setInformation(ValueRange<?> information) {
if ((lowerBoundVariable == null) || (upperBoundVariable == null)) {
return;
......
......@@ -29,7 +29,7 @@ import java.util.Map;
// * Class Definition and Members *
// ***************************************************************************
public class ValueRangeCorona extends SelectableCorona implements InformationReceiver<ValueRange>, VariableBased {
public class ValueRangeCorona extends SelectableCorona implements InformationReceiver<ValueRange<?>>, VariableBased {
protected NumericalVariable lowerBoundVariable;
protected NumericalVariable upperBoundVariable;
......@@ -101,7 +101,7 @@ public class ValueRangeCorona extends SelectableCorona implements InformationRec
// ---------------------------------------------------------------------------
@Override
public void setInformation(ValueRange information) {
public void setInformation(ValueRange<?> information) {
if (information != null) {
if (information.getLowerValue() != null)
this.lowerBoundVariable.setValue(this.lowerBoundVariable.valueFromString(information.getLowerValue().toString()));
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment