1
0
mirror of https://github.com/octoleo/plantuml.git synced 2024-05-30 15:10:48 +00:00

Add some Gantt improvement

This commit is contained in:
Arnaud Roques 2021-04-07 20:02:23 +02:00
parent 623df3e323
commit f69cfcd011
41 changed files with 629 additions and 366 deletions

View File

@ -273,10 +273,23 @@ milestone {
} }
ganttDiagram { ganttDiagram {
arrow {
LineThickness 1.5
}
note { note {
FontSize 9 FontSize 9
Shadowing 0.0 Shadowing 0.0
} }
separator {
FontSize 11
FontStyle plain
BackGroundColor transparent
Margin 5
Padding 5
}
timeline {
BackgroundColor transparent
}
} }

View File

@ -69,28 +69,28 @@ public class PSystemDonors extends PlainDiagram {
private static final int COLS = 6; private static final int COLS = 6;
private static final int FREE_LINES = 6; private static final int FREE_LINES = 6;
public static final String DONORS = "6neD0AmFkBap0wp4H6CjU-RENbb-8cPf4i7oFA4uiOZJNK3y0UwT7lSRwI-YAxltJJEYrckJSaPHV13q" public static final String DONORS = "6sWD0AmFkBap0wp4H6CjU-RENbb-8cPf4i7oFA4uiOZJNK3y0UwT7lSRwI-YAxltJJEYrckJSaPHV13q"
+ "W7UtXVQXzBy-27EYV0Z-tGWU80D4ITH6ZIpt9Djjcof3Il3lEr_v9UWTth51ehbAgiMHwq-_8GFlEsFp" + "W7UtXVQXzBy-27EYV0Z-tGWU80D4ITH6jIptfDXjcof3Il3lEr_v9UWTth51eZbAgyMHwq-_8GFlEsFp"
+ "x3GsNZsQe2y2FmRsrPzVStLjuA5OdYSeWP8k4zg9ecxlNzf8nq_W_vEaQXTjwOuqQQIX0ZigyDXNVjMr" + "x3GsNZsQe2y2FmRsrVzTJelBGo7Cqcm5Hc3KQOHRtMF_7mLLrwXs9rN3JZ-cKxagXgkYAh7PzgQ8LjBS"
+ "yr6ZoQeOCKMAhnNIyEcD2GqvwNs2RD2Wy4Fz4Dvihh2KSIOGHniYT7szjcFRYE4NIdpOvGwnm93074Wv" + "CIlKjVDHeyb5CMafKjoja8RRw4neoCdi4sI31eqVweVmPdE5fOmpWJZQ4A7hwxqT-quilr3YWyWHOe7X"
+ "qXTHzDnGK70BOAYRnMniIUN8anHGP4CBUVE7UbBnI3bpEbmKF1u0WSypg42aDMhGXBFvmu2A8zcYmn9N" + "WJcGSbWMKUBSKD1m262ecqKrjgHopnCZAFpGGjxyeP5KF5BEd0uN3QS7GE3s32gGz44Dcd1sw6v0nP5i"
+ "dHatbkPnM9xIHjBmD6BXOK4he8OW_uCkyBHOuwEfirqDZgIU9hbtMudwiztRkJOh-aRN9WdhQ-kbMMnS" + "qM69gwwC6qlpTLYUoXv9myt4mic2La0DGVu7NU3fiSP7KsVR38wadYPvdROIzMVYxRJD1NsZQvE4zRMr"
+ "KSeIgQvjV8xscaS0xfPQEUBBw2EK0pJxpQkAh7wqGFm8T5zDs98_otwma0bXRSC-KDUv-l2OHJWcGwQ9" + "QQQFAqLP8jMrZS_HNlC8mDrIAw_uCkQ8vm3DVlEg8giVBP0VWUwh2LloPzdlB2GXh6tO1-ewLnyULOHZ"
+ "TVnkjhsclT35TZOWOGLOfFVahpDDS50BNOay0ZoXLSnbdGyKqjBg_QB7mzfzmZN54lU6HEzzXANqtw_w" + "CcIQMCVlPjjhsIzq1IORaB02BEdlXgyhJN2mXQvS7W6Uq2gcMUS3XRIqUh_eyMNjFk6QOebxuwBtCS9I"
+ "C3CK1-X0cLdGJHCidT6qQY-s889wX8uEk2aaLyAvkox7xkCYVUGd0DvKUa0E6pkD4CylKsaw2g4QqdLD" + "-kzNVPWPYWDqeCmiw9e5Yt8rhTgBBOXWZz2f0JU5P2ESLzVbkFguI1_v2O2ta16GmuRG2F7yaahNKGZL"
+ "cXN0v6cbBGfUInYKQnDqCwe4GsMrskDqTQOl6nFtIHyyRpKO8t5CPwelB7UlYhGmB5QDPcspTe3c55pX" + "aQbhqbm0p9zMsgBXieH1kNP1DwDAB5HMgprELsVwiZ5td_J1yrQ3COfZEgcniDozAjB3i5WrchDtQqTf"
+ "upYlUizShWAqjl0UyS4z_yY0dkcLWKYH8VTj6_wHfLc5nIpMN3UhqbtL3suUkld0NIoQnOmoUSXKQ1nA" + "Ji4p-JZEgzvpC5S1hYsyHtnmppyo46TwPI1ISiXZtuT_PEbMOJ6BDjVDgdHNzOE3Xsu-S3UBPZ6ZJ1wo"
+ "H4lzIkId9SFV76HLVwqkzWusf-kC46567DnUcbnJasCARjDPZeCDGcIenIjESSBv1NjOLf8jR0gLPwmU" + "B1WSJqHB_KhafoN3tq78PlbhTR5Fi3bTfuO8CxBWzjBacfeSqt2OpdAix2A4HorUSIeeN4ImbwKbsSAc"
+ "XOJyZlaa8bNwGcd0hk6km3EIHq4UpdjWrR9wRIh91LIHpGH1QS6gbYgEzBL01iQQzCoqHcn_Mc31MDfZ" + "K7d6wb58oE-OJo9IMHPA0zQMkmBFf7iKvE6y1rOjgrjJIIwWYcmcY4aBLhLKSQIl1J9mhQ9dfdLY-zC2"
+ "T2mx5BrYegtA3JAcm4mJwXS6aIWrr4lfPKuI4VYVFtUf9yrraECxO_Xa74Jsa4I0AkJkZ1DLJztjw3QC" + "2-hI7cFY38VYAoRQgjoGWIamCqJuXK4afW-afVIIaqG4_kVFNUgbrphuyPqnV38EaZqa4L15ndJgYMgc"
+ "zH9_lrxApKVmvrzxjCcfqUxvQOBGEeWAG0ylu5Bk5thmDF3Ns30JS8WLLFGYuSfLIuy32GisuvrTrBbb" + "xdOC6yPwYRzVB-Nc8_ZphptQvDHez_mCGRGE4W8mmWkubFk54JmD_7Ksz08EiKA8DXAkNBNqB92mO3FU"
+ "HkCc9ikDoKMlo0zL_5lS2XVJ8JRek0YcE5eigTBBpMfGSRPlVjVX8eUEVuagGoAvhDKo6GaUXLcScsDV" + "kObwS9jHlOd9ScDoqIloGnN_DfMeS38swBY8fJXQBAdIoyrgK0Ljt_okmqqEYh-BAaCYkUpDpcGaR1Ig"
+ "RHYQjd834bH7RG9hT_rsckMkCUSha9g6oq2-tP1JgHQXXMfgMjuN0gl5sD_Rj9zoMlmd0_quhRNZgXuQ" + "E3V7RcqOch4P0tXG7RK9jDtrsscMLuqvNv5K6Pu6vDiDEPNg4LfOKzFoiH1OBSRjlQNzbDFZFnde5zGw"
+ "3d9qVRk9XczRsDiPFOdX8cP3XFwLEISSUFZ6Zxoe5ah3qhOPTgvWXVm6NiOB2OViu0EJMbwbh793Zhw5" + "-zYhXuQ3N5tVRgBXMnUadp6I62vITaJGMsfEBF3mJGHvKIsKZgLjC-pimGhv3RoC5n8EsS47abfUfQno"
+ "x1tLA3y1H3N1WGmiLkYQn48fnmCfae8vPyjeXfI3Fk2idW2Sec1_Vsz1E2tH_8ncxUqPXMGksznDPX3n" + "GmxTGlQEQfIVAAA6i40kB5ReAcAXbEE154d1dDKoaI7be2_OrnE0KnGSx-yj29UTQ7v6i_RsZ48obsxk"
+ "S7u6YPfCsUgH0_jYvhBDAt8xQf4EE_Rj-8xpxO-ecmSHo84e9i5hTQ4FD_QQfM5JVAxJu3ukS_DcyWku" + "9XL4DfoVHMAJagqUER2VbhbiyuhSZbgamuvzExxZVFiZwkQB2382CIq9NgiBVNTZbraQDjEUwpGuZilS"
+ "5EqyPM1hc6n1bh8Pg7WIWDX1faBvrVwh-OWjvnJvztvZAWmquNdYDBhnN0is8rjjH4eQq7AHXT_wViTD" + "F9Zy0dP5EqyPs1ecMv2bR0OgdWGWTiYWmenNyglvY6lE1VBl_KOf33JXUU8qkl5S2rQHhJOY9GrekSaI"
+ "JWvCd1BPydFDONPw64xHwHK0"; + "klRzZfkS72YSM6nmOOcvqSC4YawlKsq_QRCiWqeKBXLVsCEiPbEgV6JOGNFPQkVLzWG0";
/* /*
* Special thanks to our sponsors and donors: * Special thanks to our sponsors and donors:

View File

@ -51,21 +51,21 @@ class USymbolPerson extends USymbol {
return SkinParameter.PERSON; return SkinParameter.PERSON;
} }
private void drawRect(UGraphic ug, double width, double height, boolean shadowing, double roundCorner, private void drawHeadAndBody(UGraphic ug, boolean shadowing, Dimension2D dimBody, double headSize) {
double diagonalCorner) { final UEllipse head = new UEllipse(headSize, headSize);
final UEllipse head = new UEllipse(headSize(), headSize()); final URectangle body = new URectangle(dimBody).rounded(headSize);
final URectangle body = new URectangle(width, height - headSize()).rounded(headSize());
if (shadowing) { if (shadowing) {
body.setDeltaShadow(3.0); body.setDeltaShadow(3.0);
head.setDeltaShadow(1.0); head.setDeltaShadow(1.0);
} }
final double posx = (width - headSize()) / 2; final double posx = (dimBody.getWidth() - headSize) / 2;
ug.apply(UTranslate.dx(posx)).draw(head); ug.apply(UTranslate.dx(posx)).draw(head);
ug.apply(UTranslate.dy(headSize())).draw(body); ug.apply(UTranslate.dy(headSize)).draw(body);
} }
private double headSize() { private double headSize(Dimension2D dimBody) {
return 20; final double surface = dimBody.getWidth() * dimBody.getHeight();
return Math.sqrt(surface) * .42;
} }
private Margin getMargin() { private Margin getMargin() {
@ -78,21 +78,26 @@ class USymbolPerson extends USymbol {
return new AbstractTextBlock() { return new AbstractTextBlock() {
public void drawU(UGraphic ug) { public void drawU(UGraphic ug) {
final Dimension2D dim = calculateDimension(ug.getStringBounder()); final Dimension2D dimFull = calculateDimension(ug.getStringBounder());
ug = UGraphicStencil.create(ug, dim); final Dimension2D dimBody = bodyDimension(ug.getStringBounder());
ug = UGraphicStencil.create(ug, dimFull);
ug = symbolContext.apply(ug); ug = symbolContext.apply(ug);
drawRect(ug, dim.getWidth(), dim.getHeight(), symbolContext.isShadowing(), final double headSize = headSize(dimBody);
symbolContext.getRoundCorner(), symbolContext.getDiagonalCorner()); drawHeadAndBody(ug, symbolContext.isShadowing(), dimBody, headSize);
final Margin margin = getMargin();
final TextBlock tb = TextBlockUtils.mergeTB(stereotype, label, stereoAlignment); final TextBlock tb = TextBlockUtils.mergeTB(stereotype, label, stereoAlignment);
tb.drawU(ug.apply(new UTranslate(margin.getX1(), margin.getY1() + headSize()))); final Margin margin = getMargin();
tb.drawU(ug.apply(new UTranslate(margin.getX1(), margin.getY1() + headSize)));
} }
public Dimension2D calculateDimension(StringBounder stringBounder) { public Dimension2D calculateDimension(StringBounder stringBounder) {
final Dimension2D body = bodyDimension(stringBounder);
return Dimension2DDouble.delta(body, 0, headSize(body));
}
private Dimension2D bodyDimension(StringBounder stringBounder) {
final Dimension2D dimLabel = label.calculateDimension(stringBounder); final Dimension2D dimLabel = label.calculateDimension(stringBounder);
final Dimension2D dimStereo = stereotype.calculateDimension(stringBounder); final Dimension2D dimStereo = stereotype.calculateDimension(stringBounder);
return Dimension2DDouble.delta(getMargin().addDimension(Dimension2DDouble.mergeTB(dimStereo, dimLabel)), return getMargin().addDimension(Dimension2DDouble.mergeTB(dimStereo, dimLabel));
0, headSize());
} }
}; };
} }
@ -101,39 +106,7 @@ class USymbolPerson extends USymbol {
public TextBlock asBig(final TextBlock title, final HorizontalAlignment labelAlignment, final TextBlock stereotype, public TextBlock asBig(final TextBlock title, final HorizontalAlignment labelAlignment, final TextBlock stereotype,
final double width, final double height, final SymbolContext symbolContext, final double width, final double height, final SymbolContext symbolContext,
final HorizontalAlignment stereoAlignment) { final HorizontalAlignment stereoAlignment) {
return new AbstractTextBlock() { throw new UnsupportedOperationException();
public void drawU(UGraphic ug) {
final Dimension2D dim = calculateDimension(ug.getStringBounder());
ug = symbolContext.apply(ug);
drawRect(ug, dim.getWidth(), dim.getHeight(), symbolContext.isShadowing(),
symbolContext.getRoundCorner(), 0);
final Dimension2D dimStereo = stereotype.calculateDimension(ug.getStringBounder());
final double posStereoX;
final double posStereoY;
if (stereoAlignment == HorizontalAlignment.RIGHT) {
posStereoX = width - dimStereo.getWidth() - getMargin().getX1() / 2;
posStereoY = getMargin().getY1() / 2;
} else {
posStereoX = (width - dimStereo.getWidth()) / 2;
posStereoY = 2;
}
stereotype.drawU(ug.apply(new UTranslate(posStereoX, posStereoY)));
final Dimension2D dimTitle = title.calculateDimension(ug.getStringBounder());
final double posTitle;
if (labelAlignment == HorizontalAlignment.LEFT) {
posTitle = 3;
} else if (labelAlignment == HorizontalAlignment.RIGHT) {
posTitle = width - dimTitle.getWidth() - 3;
} else {
posTitle = (width - dimTitle.getWidth()) / 2;
}
title.drawU(ug.apply(new UTranslate(posTitle, 2 + dimStereo.getHeight())));
}
public Dimension2D calculateDimension(StringBounder stringBounder) {
return new Dimension2DDouble(width, height);
}
};
} }
} }

View File

@ -35,6 +35,8 @@
*/ */
package net.sourceforge.plantuml.oregon; package net.sourceforge.plantuml.oregon;
import static net.sourceforge.plantuml.graphic.GraphicStrings.createGreenOnBlackMonospaced;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -44,8 +46,7 @@ import net.sourceforge.plantuml.PlainDiagram;
import net.sourceforge.plantuml.StringUtils; import net.sourceforge.plantuml.StringUtils;
import net.sourceforge.plantuml.core.DiagramDescription; import net.sourceforge.plantuml.core.DiagramDescription;
import net.sourceforge.plantuml.graphic.UDrawable; import net.sourceforge.plantuml.graphic.UDrawable;
import net.sourceforge.plantuml.ugraphic.ImageBuilder;
import static net.sourceforge.plantuml.graphic.GraphicStrings.createGreenOnBlackMonospaced;
public class PSystemOregon extends PlainDiagram { public class PSystemOregon extends PlainDiagram {
@ -65,6 +66,11 @@ public class PSystemOregon extends PlainDiagram {
} }
} }
@Override
public ImageBuilder createImageBuilder(FileFormatOption fileFormatOption) throws IOException {
return super.createImageBuilder(fileFormatOption).blackBackcolor();
}
public PSystemOregon() { public PSystemOregon() {
this.inputs = new ArrayList<String>(); this.inputs = new ArrayList<String>();
} }

View File

@ -36,18 +36,20 @@
package net.sourceforge.plantuml.project; package net.sourceforge.plantuml.project;
import net.sourceforge.plantuml.Direction; import net.sourceforge.plantuml.Direction;
import net.sourceforge.plantuml.cucadiagram.LinkType; import net.sourceforge.plantuml.graphic.StringBounder;
import net.sourceforge.plantuml.graphic.UDrawable; import net.sourceforge.plantuml.graphic.UDrawable;
import net.sourceforge.plantuml.project.core.Task; import net.sourceforge.plantuml.project.core.Task;
import net.sourceforge.plantuml.project.core.TaskAttribute; import net.sourceforge.plantuml.project.core.TaskAttribute;
import net.sourceforge.plantuml.project.core.TaskInstant; import net.sourceforge.plantuml.project.core.TaskInstant;
import net.sourceforge.plantuml.project.draw.TaskDraw; import net.sourceforge.plantuml.project.draw.TaskDraw;
import net.sourceforge.plantuml.project.timescale.TimeScale; import net.sourceforge.plantuml.project.timescale.TimeScale;
import net.sourceforge.plantuml.style.PName;
import net.sourceforge.plantuml.style.Style;
import net.sourceforge.plantuml.ugraphic.UGraphic; import net.sourceforge.plantuml.ugraphic.UGraphic;
import net.sourceforge.plantuml.ugraphic.ULine; import net.sourceforge.plantuml.ugraphic.ULine;
import net.sourceforge.plantuml.ugraphic.UStroke; import net.sourceforge.plantuml.ugraphic.UStroke;
import net.sourceforge.plantuml.ugraphic.UTranslate; import net.sourceforge.plantuml.ugraphic.UTranslate;
import net.sourceforge.plantuml.ugraphic.color.HColor; import net.sourceforge.plantuml.ugraphic.color.HColorSet;
public class GanttArrow implements UDrawable { public class GanttArrow implements UDrawable {
@ -56,15 +58,16 @@ public class GanttArrow implements UDrawable {
private final TaskInstant source; private final TaskInstant source;
private final Direction atEnd; private final Direction atEnd;
private final TaskInstant dest; private final TaskInstant dest;
private final HColor color;
private final LinkType style; private final HColorSet colorSet;
private final Style style;
private final ToTaskDraw toTaskDraw; private final ToTaskDraw toTaskDraw;
public GanttArrow(TimeScale timeScale, TaskInstant source, TaskInstant dest, HColor color, LinkType style, public GanttArrow(HColorSet colorSet, Style style, TimeScale timeScale, TaskInstant source, TaskInstant dest,
ToTaskDraw toTaskDraw) { ToTaskDraw toTaskDraw) {
this.toTaskDraw = toTaskDraw; this.toTaskDraw = toTaskDraw;
this.style = style; this.style = style;
this.color = color; this.colorSet = colorSet;
this.timeScale = timeScale; this.timeScale = timeScale;
this.source = source; this.source = source;
this.dest = dest; this.dest = dest;
@ -94,17 +97,19 @@ public class GanttArrow implements UDrawable {
} }
public void drawU(UGraphic ug) { public void drawU(UGraphic ug) {
// ug = ug.apply(color.bg()).apply(color).apply(new UStroke(1.5)); ug = style.applyStrokeAndLineColor(ug, colorSet);
ug = ug.apply(color.bg()).apply(color).apply(style.getStroke3(new UStroke(1.5))); // ug = ug.apply(color.bg()).apply(color).apply(style.getStroke3(new
// UStroke(1.5)));
double x1 = getX(source.withDelta(0), atStart); double x1 = getX(source.withDelta(0), atStart);
double y1 = getSource().getY(atStart); final StringBounder stringBounder = ug.getStringBounder();
double y1 = getSource().getY(stringBounder, atStart);
final double x2 = getX(dest, atEnd.getInv()); final double x2 = getX(dest, atEnd.getInv());
final double y2 = getDestination().getY(atEnd); final double y2 = getDestination().getY(stringBounder, atEnd);
if (atStart == Direction.DOWN && y2 < y1) { if (atStart == Direction.DOWN && y2 < y1) {
y1 = getSource().getY(atStart.getInv()); y1 = getSource().getY(stringBounder, atStart.getInv());
} }
if (this.atStart == Direction.DOWN && this.atEnd == Direction.RIGHT) { if (this.atStart == Direction.DOWN && this.atEnd == Direction.RIGHT) {
@ -115,7 +120,7 @@ public class GanttArrow implements UDrawable {
drawLine(ug, x1, y1, x1, y2, x2, y2); drawLine(ug, x1, y1, x1, y2, x2, y2);
} else { } else {
x1 = getX(source.withDelta(0), Direction.RIGHT); x1 = getX(source.withDelta(0), Direction.RIGHT);
y1 = getSource().getY(Direction.RIGHT); y1 = getSource().getY(stringBounder, Direction.RIGHT);
drawLine(ug, x1, y1, x1 + 6, y1, x1 + 6, y1 + 8, x2 - 8, y1 + 8, x2 - 8, y2, x2, y2); drawLine(ug, x1, y1, x1 + 6, y1, x1 + 6, y1 + 8, x2 - 8, y1 + 8, x2 - 8, y2, x2, y2);
} }
} else if (this.atStart == Direction.RIGHT && this.atEnd == Direction.LEFT) { } else if (this.atStart == Direction.RIGHT && this.atEnd == Direction.LEFT) {
@ -130,7 +135,7 @@ public class GanttArrow implements UDrawable {
throw new IllegalArgumentException(); throw new IllegalArgumentException();
} }
ug = ug.apply(new UStroke(1.5)); ug = ug.apply(new UStroke(1.5)).apply(style.value(PName.LineColor).asColor(colorSet).bg());
ug.apply(new UTranslate(x2, y2)).draw(Arrows.asTo(atEnd)); ug.apply(new UTranslate(x2, y2)).draw(Arrows.asTo(atEnd));
} }

View File

@ -44,20 +44,35 @@ import net.sourceforge.plantuml.project.core.TaskAttribute;
import net.sourceforge.plantuml.project.core.TaskInstant; import net.sourceforge.plantuml.project.core.TaskInstant;
import net.sourceforge.plantuml.project.time.Day; import net.sourceforge.plantuml.project.time.Day;
import net.sourceforge.plantuml.project.timescale.TimeScale; import net.sourceforge.plantuml.project.timescale.TimeScale;
import net.sourceforge.plantuml.style.PName;
import net.sourceforge.plantuml.style.SName;
import net.sourceforge.plantuml.style.Style;
import net.sourceforge.plantuml.style.StyleBuilder;
import net.sourceforge.plantuml.style.StyleSignature;
import net.sourceforge.plantuml.ugraphic.color.HColor; import net.sourceforge.plantuml.ugraphic.color.HColor;
import net.sourceforge.plantuml.ugraphic.color.HColorSet;
public class GanttConstraint extends WithLinkType { public class GanttConstraint extends WithLinkType {
private final TaskInstant source; private final TaskInstant source;
private final TaskInstant dest; private final TaskInstant dest;
private final StyleBuilder styleBuilder;
private final HColorSet colorSet;
public GanttConstraint(TaskInstant source, TaskInstant dest, HColor forcedColor) { public GanttConstraint(HColorSet colorSet, StyleBuilder styleBuilder, TaskInstant source, TaskInstant dest,
HColor forcedColor) {
this.styleBuilder = styleBuilder;
this.colorSet = colorSet;
this.source = source; this.source = source;
this.dest = dest; this.dest = dest;
this.type = new LinkType(LinkDecor.NONE, LinkDecor.NONE); this.type = new LinkType(LinkDecor.NONE, LinkDecor.NONE);
this.setSpecificColor(forcedColor); this.setSpecificColor(forcedColor);
} }
public GanttConstraint(HColorSet colorSet, StyleBuilder styleBuilder, TaskInstant source, TaskInstant dest) {
this(colorSet, styleBuilder, source, dest, null);
}
public boolean isOn(Task task) { public boolean isOn(Task task) {
return source.getMoment() == task || dest.getMoment() == task; return source.getMoment() == task || dest.getMoment() == task;
} }
@ -73,20 +88,20 @@ public class GanttConstraint extends WithLinkType {
return false; return false;
} }
public GanttConstraint(TaskInstant source, TaskInstant dest) {
this(source, dest, null);
}
@Override @Override
public String toString() { public String toString() {
return source.toString() + " --> " + dest.toString(); return source.toString() + " --> " + dest.toString();
} }
public UDrawable getUDrawable(TimeScale timeScale, HColor color, ToTaskDraw toTaskDraw) { final public StyleSignature getStyleSignature() {
if (getSpecificColor() == null) { return StyleSignature.of(SName.root, SName.element, SName.ganttDiagram, SName.arrow);
return new GanttArrow(timeScale, source, dest, color, getType(), toTaskDraw); }
}
return new GanttArrow(timeScale, source, dest, getSpecificColor(), getType(), toTaskDraw); public UDrawable getUDrawable(TimeScale timeScale, ToTaskDraw toTaskDraw) {
Style style = styleBuilder.getMergedStyle(getStyleSignature()).eventuallyOverride(PName.LineColor,
getSpecificColor());
style = style.eventuallyOverride(getType().getStroke3(style.getStroke()));
return new GanttArrow(colorSet, style, timeScale, source, dest, toTaskDraw);
} }
public boolean isHidden(Day min, Day max) { public boolean isHidden(Day min, Day max) {

View File

@ -86,6 +86,7 @@ import net.sourceforge.plantuml.project.draw.TimeHeaderYearly;
import net.sourceforge.plantuml.project.lang.CenterBorderColor; import net.sourceforge.plantuml.project.lang.CenterBorderColor;
import net.sourceforge.plantuml.project.time.Day; import net.sourceforge.plantuml.project.time.Day;
import net.sourceforge.plantuml.project.time.DayOfWeek; import net.sourceforge.plantuml.project.time.DayOfWeek;
import net.sourceforge.plantuml.project.time.WeekNumberStrategy;
import net.sourceforge.plantuml.project.timescale.TimeScale; import net.sourceforge.plantuml.project.timescale.TimeScale;
import net.sourceforge.plantuml.style.ClockwiseTopRightBottomLeft; import net.sourceforge.plantuml.style.ClockwiseTopRightBottomLeft;
import net.sourceforge.plantuml.style.PName; import net.sourceforge.plantuml.style.PName;
@ -95,6 +96,7 @@ import net.sourceforge.plantuml.style.StyleSignature;
import net.sourceforge.plantuml.svek.TextBlockBackcolored; import net.sourceforge.plantuml.svek.TextBlockBackcolored;
import net.sourceforge.plantuml.ugraphic.MinMax; import net.sourceforge.plantuml.ugraphic.MinMax;
import net.sourceforge.plantuml.ugraphic.UGraphic; import net.sourceforge.plantuml.ugraphic.UGraphic;
import net.sourceforge.plantuml.ugraphic.URectangle;
import net.sourceforge.plantuml.ugraphic.UTranslate; import net.sourceforge.plantuml.ugraphic.UTranslate;
import net.sourceforge.plantuml.ugraphic.color.HColor; import net.sourceforge.plantuml.ugraphic.color.HColor;
import net.sourceforge.plantuml.ugraphic.color.HColorSet; import net.sourceforge.plantuml.ugraphic.color.HColorSet;
@ -115,8 +117,12 @@ public class GanttDiagram extends TitledDiagram implements ToTaskDraw, WithSprit
private final Map<DayOfWeek, HColor> colorDaysOfWeek = new HashMap<DayOfWeek, HColor>(); private final Map<DayOfWeek, HColor> colorDaysOfWeek = new HashMap<DayOfWeek, HColor>();
private final Map<Day, String> nameDays = new HashMap<Day, String>(); private final Map<Day, String> nameDays = new HashMap<Day, String>();
// Let's follow ISO-8601 rules
private WeekNumberStrategy weekNumberStrategy = new WeekNumberStrategy(DayOfWeek.MONDAY, 4);
private PrintScale printScale = PrintScale.DAILY; private PrintScale printScale = PrintScale.DAILY;
private Integer compress; private double factorScale = 1.0;
private Day today; private Day today;
private double totalHeightWithoutFooter; private double totalHeightWithoutFooter;
private Day min = Day.create(0); private Day min = Day.create(0);
@ -125,12 +131,14 @@ public class GanttDiagram extends TitledDiagram implements ToTaskDraw, WithSprit
private Day printStart; private Day printStart;
private Day printEnd; private Day printEnd;
private HColor linksColor = null;
public DiagramDescription getDescription() { public DiagramDescription getDescription() {
return new DiagramDescription("(Project)"); return new DiagramDescription("(Project)");
} }
public void setWeekNumberStrategy(DayOfWeek firstDayOfWeek, int minimalDaysInFirstWeek) {
this.weekNumberStrategy = new WeekNumberStrategy(firstDayOfWeek, minimalDaysInFirstWeek);
}
public GanttDiagram() { public GanttDiagram() {
super(UmlDiagramType.GANTT); super(UmlDiagramType.GANTT);
} }
@ -167,24 +175,19 @@ public class GanttDiagram extends TitledDiagram implements ToTaskDraw, WithSprit
protected ImageData exportDiagramNow(OutputStream os, int index, FileFormatOption fileFormatOption) protected ImageData exportDiagramNow(OutputStream os, int index, FileFormatOption fileFormatOption)
throws IOException { throws IOException {
final StringBounder stringBounder = fileFormatOption.getDefaultStringBounder(getSkinParam()); final StringBounder stringBounder = fileFormatOption.getDefaultStringBounder(getSkinParam());
return createImageBuilder(fileFormatOption) return createImageBuilder(fileFormatOption).drawable(getTextBlock(stringBounder)).write(os);
.drawable(getTextBlock(stringBounder))
.write(os);
} }
public void setPrintScale(PrintScale printScale) { public void setPrintScale(PrintScale printScale) {
this.printScale = printScale; this.printScale = printScale;
} }
public void setCompress(int compress) { public void setFactorScale(double factorScale) {
this.compress = compress; this.factorScale = factorScale;
} }
private int getCompress() { private double getFactorScale() {
if (this.compress != null) { return this.printScale.getDefaultScale() * this.factorScale;
return this.compress;
}
return printScale.getCompress();
} }
private boolean isHidden(Task task) { private boolean isHidden(Task task) {
@ -212,7 +215,22 @@ public class GanttDiagram extends TitledDiagram implements ToTaskDraw, WithSprit
return new TextBlockBackcolored() { return new TextBlockBackcolored() {
public void drawU(UGraphic ug) { public void drawU(UGraphic ug) {
final Style timelineStyle = StyleSignature
.of(SName.root, SName.element, SName.ganttDiagram, SName.timeline)
.getMergedStyle(getCurrentStyleBuilder());
final HColor back = timelineStyle.value(PName.BackGroundColor).asColor(getIHtmlColorSet());
if (HColorUtils.isTransparent(back) == false) {
final URectangle rect1 = new URectangle(calculateDimension(ug.getStringBounder()).getWidth(),
timeHeader.getTimeHeaderHeight());
final URectangle rect2 = new URectangle(calculateDimension(ug.getStringBounder()).getWidth(),
timeHeader.getTimeFooterHeight());
ug.apply(back.bg()).draw(rect1);
ug.apply(back.bg()).apply(UTranslate.dy(totalHeightWithoutFooter)).draw(rect2);
}
timeHeader.drawTimeHeader(ug, totalHeightWithoutFooter); timeHeader.drawTimeHeader(ug, totalHeightWithoutFooter);
drawConstraints(ug, timeHeader.getTimeScale()); drawConstraints(ug, timeHeader.getTimeScale());
drawTasksRect(ug); drawTasksRect(ug);
drawTasksTitle(ug); drawTasksTitle(ug);
@ -246,17 +264,17 @@ public class GanttDiagram extends TitledDiagram implements ToTaskDraw, WithSprit
if (openClose.getCalendar() == null) { if (openClose.getCalendar() == null) {
return new TimeHeaderSimple(min, max); return new TimeHeaderSimple(min, max);
} else if (printScale == PrintScale.WEEKLY) { } else if (printScale == PrintScale.WEEKLY) {
return new TimeHeaderWeekly(openClose.getCalendar(), min, max, openClose, colorDays, colorDaysOfWeek, return new TimeHeaderWeekly(getFactorScale(), openClose.getCalendar(), min, max, openClose, colorDays,
getCompress()); colorDaysOfWeek, weekNumberStrategy);
} else if (printScale == PrintScale.MONTHLY) { } else if (printScale == PrintScale.MONTHLY) {
return new TimeHeaderMonthly(openClose.getCalendar(), min, max, openClose, colorDays, colorDaysOfWeek, return new TimeHeaderMonthly(getFactorScale(), openClose.getCalendar(), min, max, openClose, colorDays,
getCompress()); colorDaysOfWeek);
} else if (printScale == PrintScale.QUARTERLY) { } else if (printScale == PrintScale.QUARTERLY) {
return new TimeHeaderQuarterly(openClose.getCalendar(), min, max, openClose, colorDays, colorDaysOfWeek, return new TimeHeaderQuarterly(getFactorScale(), openClose.getCalendar(), min, max, openClose, colorDays,
getCompress()); colorDaysOfWeek);
} else if (printScale == PrintScale.YEARLY) { } else if (printScale == PrintScale.YEARLY) {
return new TimeHeaderYearly(openClose.getCalendar(), min, max, openClose, colorDays, colorDaysOfWeek, return new TimeHeaderYearly(getFactorScale(), openClose.getCalendar(), min, max, openClose, colorDays,
getCompress()); colorDaysOfWeek);
} else { } else {
return new TimeHeaderDaily(openClose.getCalendar(), min, max, openClose, colorDays, colorDaysOfWeek, return new TimeHeaderDaily(openClose.getCalendar(), min, max, openClose, colorDays, colorDaysOfWeek,
nameDays, printStart, printEnd); nameDays, printStart, printEnd);
@ -276,7 +294,7 @@ public class GanttDiagram extends TitledDiagram implements ToTaskDraw, WithSprit
continue; continue;
} }
final TaskDraw draw = draws.get(task); final TaskDraw draw = draws.get(task);
final UTranslate move = UTranslate.dy(draw.getY()); final UTranslate move = UTranslate.dy(draw.getY(ug.getStringBounder()));
draw.drawU(ug.apply(move)); draw.drawU(ug.apply(move));
} }
} }
@ -286,19 +304,11 @@ public class GanttDiagram extends TitledDiagram implements ToTaskDraw, WithSprit
if (printStart != null && constraint.isHidden(min, max)) { if (printStart != null && constraint.isHidden(min, max)) {
continue; continue;
} }
constraint.getUDrawable(timeScale, getLinkColor(), this).drawU(ug); constraint.getUDrawable(timeScale, this).drawU(ug);
} }
} }
private HColor getLinkColor() {
if (linksColor == null) {
final Style styleArrow = getDefaultStyleDefinitionArrow().getMergedStyle(getCurrentStyleBuilder());
return styleArrow.value(PName.LineColor).asColor(colorSet);
}
return linksColor;
}
public StyleSignature getDefaultStyleDefinitionArrow() { public StyleSignature getDefaultStyleDefinitionArrow() {
return StyleSignature.of(SName.root, SName.element, SName.ganttDiagram, SName.arrow); return StyleSignature.of(SName.root, SName.element, SName.ganttDiagram, SName.arrow);
} }
@ -309,7 +319,7 @@ public class GanttDiagram extends TitledDiagram implements ToTaskDraw, WithSprit
continue; continue;
} }
final TaskDraw draw = draws.get(task); final TaskDraw draw = draws.get(task);
final UTranslate move = UTranslate.dy(draw.getY()); final UTranslate move = UTranslate.dy(draw.getY(ug1.getStringBounder()));
draw.drawTitle(ug1.apply(move)); draw.drawTitle(ug1.apply(move));
} }
} }
@ -339,22 +349,24 @@ public class GanttDiagram extends TitledDiagram implements ToTaskDraw, WithSprit
for (Task task : tasks.values()) { for (Task task : tasks.values()) {
final TaskDraw draw; final TaskDraw draw;
if (task instanceof TaskSeparator) { if (task instanceof TaskSeparator) {
draw = new TaskDrawSeparator(((TaskSeparator) task).getName(), timeScale, y, min, max); draw = new TaskDrawSeparator(((TaskSeparator) task).getName(), timeScale, y, min, max,
task.getStyleBuilder(), getSkinParam().getIHtmlColorSet());
} else { } else {
final TaskImpl tmp = (TaskImpl) task; final TaskImpl tmp = (TaskImpl) task;
if (tmp.isDiamond()) { if (tmp.isDiamond()) {
draw = new TaskDrawDiamond(timeScale, y, tmp.getPrettyDisplay(), getStart(tmp), getSkinParam(), draw = new TaskDrawDiamond(timeScale, y, tmp.getPrettyDisplay(), getStart(tmp), getSkinParam(),
task, this); task, this, task.getStyleBuilder(), getSkinParam().getIHtmlColorSet());
} else { } else {
final boolean oddStart = printStart != null && min.compareTo(getStart(tmp)) == 0; final boolean oddStart = printStart != null && min.compareTo(getStart(tmp)) == 0;
final boolean oddEnd = printStart != null && max.compareTo(getEnd(tmp)) == 0; final boolean oddEnd = printStart != null && max.compareTo(getEnd(tmp)) == 0;
draw = new TaskDrawRegular(timeScale, y, tmp.getPrettyDisplay(), getStart(tmp), getEnd(tmp), draw = new TaskDrawRegular(timeScale, y, tmp.getPrettyDisplay(), getStart(tmp), getEnd(tmp),
oddStart, oddEnd, getSkinParam(), task, this, getConstraints(task)); oddStart, oddEnd, getSkinParam(), task, this, getConstraints(task), task.getStyleBuilder(),
getSkinParam().getIHtmlColorSet());
} }
draw.setColorsAndCompletion(tmp.getColors(), tmp.getCompletion(), tmp.getUrl(), tmp.getNote()); draw.setColorsAndCompletion(tmp.getColors(), tmp.getCompletion(), tmp.getUrl(), tmp.getNote());
} }
if (task.getRow() == null) { if (task.getRow() == null) {
y += draw.getHeightTask(); y += draw.getHeightTask(stringBounder);
} }
draws.put(task, draw); draws.put(task, draw);
} }
@ -385,7 +397,7 @@ public class GanttDiagram extends TitledDiagram implements ToTaskDraw, WithSprit
private double lastY(StringBounder stringBounder) { private double lastY(StringBounder stringBounder) {
double result = 0; double result = 0;
for (TaskDraw td : draws.values()) { for (TaskDraw td : draws.values()) {
result = Math.max(result, td.getY() + td.getHeightMax(stringBounder)); result = Math.max(result, td.getY(stringBounder) + td.getHeightMax(stringBounder));
} }
return result; return result;
} }
@ -393,7 +405,7 @@ public class GanttDiagram extends TitledDiagram implements ToTaskDraw, WithSprit
private boolean magicPushOnce(StringBounder stringBounder) { private boolean magicPushOnce(StringBounder stringBounder) {
final List<FingerPrint> notes = new ArrayList<FingerPrint>(); final List<FingerPrint> notes = new ArrayList<FingerPrint>();
for (TaskDraw td : draws.values()) { for (TaskDraw td : draws.values()) {
final FingerPrint taskPrint = td.getFingerPrint(); final FingerPrint taskPrint = td.getFingerPrint(stringBounder);
for (FingerPrint note : notes) { for (FingerPrint note : notes) {
final double deltaY = note.overlap(taskPrint); final double deltaY = note.overlap(taskPrint);
if (deltaY > 0) { if (deltaY > 0) {
@ -504,7 +516,8 @@ public class GanttDiagram extends TitledDiagram implements ToTaskDraw, WithSprit
public GanttConstraint forceTaskOrder(Task task1, Task task2) { public GanttConstraint forceTaskOrder(Task task1, Task task2) {
final TaskInstant end1 = new TaskInstant(task1, TaskAttribute.END); final TaskInstant end1 = new TaskInstant(task1, TaskAttribute.END);
task2.setStart(end1.getInstantPrecise()); task2.setStart(end1.getInstantPrecise());
final GanttConstraint result = new GanttConstraint(end1, new TaskInstant(task2, TaskAttribute.START)); final GanttConstraint result = new GanttConstraint(this.getIHtmlColorSet(),
getSkinParam().getCurrentStyleBuilder(), end1, new TaskInstant(task2, TaskAttribute.START));
addContraint(result); addContraint(result);
return result; return result;
} }
@ -528,7 +541,7 @@ public class GanttDiagram extends TitledDiagram implements ToTaskDraw, WithSprit
if (linkedToPrevious) { if (linkedToPrevious) {
previous = getLastCreatedTask(); previous = getLastCreatedTask();
} }
result = new TaskImpl(code, openClose); result = new TaskImpl(getSkinParam().getCurrentStyleBuilder(), code, openClose);
tasks.put(code, result); tasks.put(code, result);
if (byShortName != null) { if (byShortName != null) {
byShortName.put(shortName, result); byShortName.put(shortName, result);
@ -551,7 +564,7 @@ public class GanttDiagram extends TitledDiagram implements ToTaskDraw, WithSprit
} }
public void addSeparator(String comment) { public void addSeparator(String comment) {
TaskSeparator separator = new TaskSeparator(comment, tasks.size()); TaskSeparator separator = new TaskSeparator(getSkinParam().getCurrentStyleBuilder(), comment, tasks.size());
tasks.put(separator.getCode(), separator); tasks.put(separator.getCode(), separator);
} }
@ -699,10 +712,6 @@ public class GanttDiagram extends TitledDiagram implements ToTaskDraw, WithSprit
this.printEnd = end; this.printEnd = end;
} }
public void setLinksColor(HColor color) {
this.linksColor = color;
}
public TaskDraw getTaskDraw(Task task) { public TaskDraw getTaskDraw(Task task) {
return draws.get(task); return draws.get(task);
} }
@ -733,4 +742,5 @@ public class GanttDiagram extends TitledDiagram implements ToTaskDraw, WithSprit
public ClockwiseTopRightBottomLeft getDefaultMargins() { public ClockwiseTopRightBottomLeft getDefaultMargins() {
return ClockwiseTopRightBottomLeft.none(); return ClockwiseTopRightBottomLeft.none();
} }
} }

View File

@ -53,6 +53,7 @@ import net.sourceforge.plantuml.project.command.CommandPage;
import net.sourceforge.plantuml.project.command.CommandPrintBetween; import net.sourceforge.plantuml.project.command.CommandPrintBetween;
import net.sourceforge.plantuml.project.command.CommandPrintScale; import net.sourceforge.plantuml.project.command.CommandPrintScale;
import net.sourceforge.plantuml.project.command.CommandSeparator; import net.sourceforge.plantuml.project.command.CommandSeparator;
import net.sourceforge.plantuml.project.command.CommandWeekNumberStrategy;
import net.sourceforge.plantuml.project.command.NaturalCommand; import net.sourceforge.plantuml.project.command.NaturalCommand;
import net.sourceforge.plantuml.project.lang.SentenceAnd; import net.sourceforge.plantuml.project.lang.SentenceAnd;
import net.sourceforge.plantuml.project.lang.SentenceAndAnd; import net.sourceforge.plantuml.project.lang.SentenceAndAnd;
@ -61,7 +62,6 @@ import net.sourceforge.plantuml.project.lang.Subject;
import net.sourceforge.plantuml.project.lang.SubjectDayAsDate; import net.sourceforge.plantuml.project.lang.SubjectDayAsDate;
import net.sourceforge.plantuml.project.lang.SubjectDayOfWeek; import net.sourceforge.plantuml.project.lang.SubjectDayOfWeek;
import net.sourceforge.plantuml.project.lang.SubjectDaysAsDates; import net.sourceforge.plantuml.project.lang.SubjectDaysAsDates;
import net.sourceforge.plantuml.project.lang.SubjectLinks;
import net.sourceforge.plantuml.project.lang.SubjectProject; import net.sourceforge.plantuml.project.lang.SubjectProject;
import net.sourceforge.plantuml.project.lang.SubjectResource; import net.sourceforge.plantuml.project.lang.SubjectResource;
import net.sourceforge.plantuml.project.lang.SubjectTask; import net.sourceforge.plantuml.project.lang.SubjectTask;
@ -73,8 +73,7 @@ public class GanttDiagramFactory extends PSystemCommandFactory {
static private final List<Subject> subjects() { static private final List<Subject> subjects() {
return Arrays.<Subject>asList(new SubjectTask(), new SubjectProject(), new SubjectDayOfWeek(), return Arrays.<Subject>asList(new SubjectTask(), new SubjectProject(), new SubjectDayOfWeek(),
new SubjectDayAsDate(), new SubjectDaysAsDates(), new SubjectResource(), new SubjectToday(), new SubjectDayAsDate(), new SubjectDaysAsDates(), new SubjectResource(), new SubjectToday());
new SubjectLinks());
} }
public GanttDiagramFactory(DiagramType type) { public GanttDiagramFactory(DiagramType type) {
@ -99,6 +98,7 @@ public class GanttDiagramFactory extends PSystemCommandFactory {
cmds.add(new CommandGanttArrow2()); cmds.add(new CommandGanttArrow2());
cmds.add(new CommandColorTask()); cmds.add(new CommandColorTask());
cmds.add(new CommandSeparator()); cmds.add(new CommandSeparator());
cmds.add(new CommandWeekNumberStrategy());
cmds.add(new CommandPrintScale()); cmds.add(new CommandPrintScale());
cmds.add(new CommandPrintBetween()); cmds.add(new CommandPrintBetween());

View File

@ -43,7 +43,6 @@ import net.sourceforge.plantuml.command.regex.RegexConcat;
import net.sourceforge.plantuml.command.regex.RegexLeaf; import net.sourceforge.plantuml.command.regex.RegexLeaf;
import net.sourceforge.plantuml.command.regex.RegexOptional; import net.sourceforge.plantuml.command.regex.RegexOptional;
import net.sourceforge.plantuml.command.regex.RegexOr; import net.sourceforge.plantuml.command.regex.RegexOr;
import net.sourceforge.plantuml.command.regex.RegexPartialMatch;
import net.sourceforge.plantuml.command.regex.RegexResult; import net.sourceforge.plantuml.command.regex.RegexResult;
import net.sourceforge.plantuml.project.GanttDiagram; import net.sourceforge.plantuml.project.GanttDiagram;
import net.sourceforge.plantuml.project.core.PrintScale; import net.sourceforge.plantuml.project.core.PrintScale;
@ -68,9 +67,9 @@ public class CommandPrintScale extends SingleLineCommand2<GanttDiagram> {
new RegexLeaf("weekly")), // new RegexLeaf("weekly")), //
new RegexOptional(new RegexConcat( // new RegexOptional(new RegexConcat( //
RegexLeaf.spaceOneOrMore(), // RegexLeaf.spaceOneOrMore(), //
new RegexLeaf("compress"), // new RegexLeaf("zoom"), //
RegexLeaf.spaceOneOrMore(), // RegexLeaf.spaceOneOrMore(), //
new RegexLeaf("COMPRESS", "(\\d+)"))), // new RegexLeaf("ZOOM", "([.\\d]+)"))), //
RegexLeaf.end()); // RegexLeaf.end()); //
} }
@ -80,9 +79,9 @@ public class CommandPrintScale extends SingleLineCommand2<GanttDiagram> {
final PrintScale scale = PrintScale.fromString(scaleString); final PrintScale scale = PrintScale.fromString(scaleString);
diagram.setPrintScale(scale); diagram.setPrintScale(scale);
final RegexPartialMatch compress = arg.get("COMPRESS"); final String zoom = arg.get("ZOOM", 0);
if (compress.size() > 0 && compress.get(0) != null) { if (zoom != null) {
diagram.setCompress(Integer.parseInt(compress.get(0))); diagram.setFactorScale(Double.parseDouble(zoom));
} }
return CommandExecutionResult.ok(); return CommandExecutionResult.ok();
} }

View File

@ -0,0 +1,78 @@
/* ========================================================================
* PlantUML : a free UML diagram generator
* ========================================================================
*
* (C) Copyright 2009-2020, Arnaud Roques
*
* Project Info: http://plantuml.com
*
* If you like this project or if you find it useful, you can support us at:
*
* http://plantuml.com/patreon (only 1$ per month!)
* http://plantuml.com/paypal
*
* This file is part of PlantUML.
*
* PlantUML is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* PlantUML distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
* License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
* USA.
*
*
* Original Author: Arnaud Roques
*
*
*/
package net.sourceforge.plantuml.project.command;
import net.sourceforge.plantuml.LineLocation;
import net.sourceforge.plantuml.command.CommandExecutionResult;
import net.sourceforge.plantuml.command.SingleLineCommand2;
import net.sourceforge.plantuml.command.regex.IRegex;
import net.sourceforge.plantuml.command.regex.RegexConcat;
import net.sourceforge.plantuml.command.regex.RegexLeaf;
import net.sourceforge.plantuml.command.regex.RegexResult;
import net.sourceforge.plantuml.project.GanttDiagram;
import net.sourceforge.plantuml.project.time.DayOfWeek;
public class CommandWeekNumberStrategy extends SingleLineCommand2<GanttDiagram> {
public CommandWeekNumberStrategy() {
super(getRegexConcat());
}
static IRegex getRegexConcat() {
return RegexConcat.build(CommandWeekNumberStrategy.class.getName(), RegexLeaf.start(), //
new RegexLeaf("weeks?"), //
RegexLeaf.spaceOneOrMore(), //
new RegexLeaf("starts?"), //
new RegexLeaf("[^0-9]*?"), //
RegexLeaf.spaceOneOrMore(), //
new RegexLeaf("WEEKDAY", "(" + DayOfWeek.getRegexString() + ")"), //
RegexLeaf.spaceOneOrMore(), //
new RegexLeaf("[^0-9]*?"), //
new RegexLeaf("NUM", "([0-9]+)"), //
new RegexLeaf("[^0-9]*?"), //
RegexLeaf.end());
}
@Override
protected CommandExecutionResult executeArg(GanttDiagram diagram, LineLocation location, RegexResult arg) {
final DayOfWeek weekDay = DayOfWeek.fromString(arg.get("WEEKDAY", 0));
final String num = arg.get("NUM", 0);
diagram.setWeekNumberStrategy(weekDay, Integer.parseInt(num));
return CommandExecutionResult.ok();
}
}

View File

@ -35,12 +35,17 @@
*/ */
package net.sourceforge.plantuml.project.core; package net.sourceforge.plantuml.project.core;
import net.sourceforge.plantuml.style.StyleBuilder;
public abstract class AbstractTask implements Task { public abstract class AbstractTask implements Task {
protected final TaskCode code; private final TaskCode code;
private final StyleBuilder styleBuilder;
private Task row; private Task row;
protected AbstractTask(TaskCode code) { protected AbstractTask(StyleBuilder styleBuilder, TaskCode code) {
this.styleBuilder = styleBuilder;
this.code = code; this.code = code;
} }
@ -52,4 +57,12 @@ public abstract class AbstractTask implements Task {
return row; return row;
} }
public final TaskCode getCode() {
return code;
}
public final StyleBuilder getStyleBuilder() {
return styleBuilder;
}
} }

View File

@ -36,16 +36,16 @@
package net.sourceforge.plantuml.project.core; package net.sourceforge.plantuml.project.core;
public enum PrintScale { public enum PrintScale {
DAILY(1), WEEKLY(4), MONTHLY(15), QUARTERLY(40), YEARLY(150); DAILY(1), WEEKLY(4), MONTHLY(15), QUARTERLY(40), YEARLY(60);
private final int compress; private final double defaultScale;
private PrintScale(int compress) { private PrintScale(int compress) {
this.compress = compress; this.defaultScale = 1.0 / compress;
} }
public int getCompress() { public final double getDefaultScale() {
return compress; return defaultScale;
} }
static public PrintScale fromString(String value) { static public PrintScale fromString(String value) {
@ -63,4 +63,5 @@ public enum PrintScale {
} }
return DAILY; return DAILY;
} }
} }

View File

@ -41,6 +41,7 @@ import net.sourceforge.plantuml.project.Load;
import net.sourceforge.plantuml.project.lang.CenterBorderColor; import net.sourceforge.plantuml.project.lang.CenterBorderColor;
import net.sourceforge.plantuml.project.time.Day; import net.sourceforge.plantuml.project.time.Day;
import net.sourceforge.plantuml.project.time.DayOfWeek; import net.sourceforge.plantuml.project.time.DayOfWeek;
import net.sourceforge.plantuml.style.StyleBuilder;
public interface Task extends Moment { public interface Task extends Moment {
@ -76,4 +77,6 @@ public interface Task extends Moment {
public void setNote(Display note); public void setNote(Display note);
public StyleBuilder getStyleBuilder();
} }

View File

@ -56,6 +56,7 @@ import net.sourceforge.plantuml.project.solver.Solver;
import net.sourceforge.plantuml.project.solver.SolverImpl; import net.sourceforge.plantuml.project.solver.SolverImpl;
import net.sourceforge.plantuml.project.time.Day; import net.sourceforge.plantuml.project.time.Day;
import net.sourceforge.plantuml.project.time.DayOfWeek; import net.sourceforge.plantuml.project.time.DayOfWeek;
import net.sourceforge.plantuml.style.StyleBuilder;
public class TaskImpl extends AbstractTask implements Task, LoadPlanable { public class TaskImpl extends AbstractTask implements Task, LoadPlanable {
@ -76,8 +77,8 @@ public class TaskImpl extends AbstractTask implements Task, LoadPlanable {
this.url = url; this.url = url;
} }
public TaskImpl(TaskCode code, OpenClose openClose) { public TaskImpl(StyleBuilder styleBuilder, TaskCode code, OpenClose openClose) {
super(code); super(styleBuilder, code);
this.defaultPlan = openClose; this.defaultPlan = openClose;
this.solver = new SolverImpl(this); this.solver = new SolverImpl(this);
if (openClose.getCalendar() == null) { if (openClose.getCalendar() == null) {
@ -153,7 +154,7 @@ public class TaskImpl extends AbstractTask implements Task, LoadPlanable {
public String getPrettyDisplay() { public String getPrettyDisplay() {
if (resources.size() > 0) { if (resources.size() > 0) {
final StringBuilder result = new StringBuilder(code.getSimpleDisplay()); final StringBuilder result = new StringBuilder(getCode().getSimpleDisplay());
result.append(" "); result.append(" ");
for (Iterator<Map.Entry<Resource, Integer>> it = resources.entrySet().iterator(); it.hasNext();) { for (Iterator<Map.Entry<Resource, Integer>> it = resources.entrySet().iterator(); it.hasNext();) {
final Map.Entry<Resource, Integer> ent = it.next(); final Map.Entry<Resource, Integer> ent = it.next();
@ -170,22 +171,18 @@ public class TaskImpl extends AbstractTask implements Task, LoadPlanable {
} }
return result.toString(); return result.toString();
} }
return code.getSimpleDisplay(); return getCode().getSimpleDisplay();
} }
@Override @Override
public String toString() { public String toString() {
return code.toString(); return getCode().toString();
} }
public String debug() { public String debug() {
return "" + getStart() + " ---> " + getEnd() + " [" + getLoad() + "]"; return "" + getStart() + " ---> " + getEnd() + " [" + getLoad() + "]";
} }
public TaskCode getCode() {
return code;
}
public Day getStart() { public Day getStart() {
Day result = (Day) solver.getData(TaskAttribute.START); Day result = (Day) solver.getData(TaskAttribute.START);
while (getLoadAt(result) == 0) { while (getLoadAt(result) == 0) {

View File

@ -41,20 +41,17 @@ import net.sourceforge.plantuml.project.Load;
import net.sourceforge.plantuml.project.lang.CenterBorderColor; import net.sourceforge.plantuml.project.lang.CenterBorderColor;
import net.sourceforge.plantuml.project.time.Day; import net.sourceforge.plantuml.project.time.Day;
import net.sourceforge.plantuml.project.time.DayOfWeek; import net.sourceforge.plantuml.project.time.DayOfWeek;
import net.sourceforge.plantuml.style.StyleBuilder;
public class TaskSeparator extends AbstractTask implements Task { public class TaskSeparator extends AbstractTask implements Task {
private final String comment; private final String comment;
public TaskSeparator(String comment, int id) { public TaskSeparator(StyleBuilder styleBuilder, String comment, int id) {
super(new TaskCode("##" + id)); super(styleBuilder, new TaskCode("##" + id));
this.comment = comment; this.comment = comment;
} }
public TaskCode getCode() {
return code;
}
public Day getStart() { public Day getStart() {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }

View File

@ -40,6 +40,7 @@ import net.sourceforge.plantuml.ISkinParam;
import net.sourceforge.plantuml.Url; import net.sourceforge.plantuml.Url;
import net.sourceforge.plantuml.cucadiagram.Display; import net.sourceforge.plantuml.cucadiagram.Display;
import net.sourceforge.plantuml.graphic.FontConfiguration; import net.sourceforge.plantuml.graphic.FontConfiguration;
import net.sourceforge.plantuml.graphic.StringBounder;
import net.sourceforge.plantuml.project.ToTaskDraw; import net.sourceforge.plantuml.project.ToTaskDraw;
import net.sourceforge.plantuml.project.core.Task; import net.sourceforge.plantuml.project.core.Task;
import net.sourceforge.plantuml.project.lang.CenterBorderColor; import net.sourceforge.plantuml.project.lang.CenterBorderColor;
@ -47,7 +48,10 @@ import net.sourceforge.plantuml.project.time.Day;
import net.sourceforge.plantuml.project.timescale.TimeScale; import net.sourceforge.plantuml.project.timescale.TimeScale;
import net.sourceforge.plantuml.style.PName; import net.sourceforge.plantuml.style.PName;
import net.sourceforge.plantuml.style.Style; import net.sourceforge.plantuml.style.Style;
import net.sourceforge.plantuml.style.StyleBuilder;
import net.sourceforge.plantuml.style.StyleSignature;
import net.sourceforge.plantuml.ugraphic.color.HColor; import net.sourceforge.plantuml.ugraphic.color.HColor;
import net.sourceforge.plantuml.ugraphic.color.HColorSet;
public abstract class AbstractTaskDraw implements TaskDraw { public abstract class AbstractTaskDraw implements TaskDraw {
@ -59,7 +63,8 @@ public abstract class AbstractTaskDraw implements TaskDraw {
private double y; private double y;
protected final String prettyDisplay; protected final String prettyDisplay;
protected final Day start; protected final Day start;
protected final ISkinParam skinParam; private final StyleBuilder styleBuilder;
private final HColorSet colorSet;
private final Task task; private final Task task;
private final ToTaskDraw toTaskDraw; private final ToTaskDraw toTaskDraw;
@ -78,35 +83,40 @@ public abstract class AbstractTaskDraw implements TaskDraw {
} }
public AbstractTaskDraw(TimeScale timeScale, double y, String prettyDisplay, Day start, ISkinParam skinParam, public AbstractTaskDraw(TimeScale timeScale, double y, String prettyDisplay, Day start, ISkinParam skinParam,
Task task, ToTaskDraw toTaskDraw) { Task task, ToTaskDraw toTaskDraw, StyleBuilder styleBuilder, HColorSet colorSet) {
this.y = y; this.y = y;
this.colorSet = colorSet;
this.styleBuilder = styleBuilder;
this.toTaskDraw = toTaskDraw; this.toTaskDraw = toTaskDraw;
this.start = start; this.start = start;
this.prettyDisplay = prettyDisplay; this.prettyDisplay = prettyDisplay;
this.timeScale = timeScale; this.timeScale = timeScale;
this.skinParam = skinParam;
this.task = task; this.task = task;
} }
abstract StyleSignature getStyleSignature();
final protected HColor getLineColor() { final protected HColor getLineColor() {
return getStyle().value(PName.LineColor).asColor(skinParam.getIHtmlColorSet()); return getStyle().value(PName.LineColor).asColor(colorSet);
} }
final protected HColor getBackgroundColor() { final protected HColor getBackgroundColor() {
return getStyle().value(PName.BackGroundColor).asColor(skinParam.getIHtmlColorSet()); return getStyle().value(PName.BackGroundColor).asColor(colorSet);
} }
final protected FontConfiguration getFontConfiguration() { final protected FontConfiguration getFontConfiguration() {
return getStyle().getFontConfiguration(skinParam.getIHtmlColorSet()); return getStyle().getFontConfiguration(colorSet);
} }
abstract protected Style getStyle(); final protected Style getStyle() {
return getStyleSignature().getMergedStyle(styleBuilder);
final protected double getShapeHeight() {
return getHeightTask() - 2 * margin;
} }
final public double getHeightTask() { final protected double getShapeHeight(StringBounder stringBounder) {
return getHeightTask(stringBounder) - 2 * margin;
}
final public double getHeightTask(StringBounder stringBounder) {
return getFontConfiguration().getFont().getSize2D() + 5; return getFontConfiguration().getFont().getSize2D() + 5;
} }
@ -114,11 +124,11 @@ public abstract class AbstractTaskDraw implements TaskDraw {
return toTaskDraw.getTaskDraw(task.getRow()); return toTaskDraw.getTaskDraw(task.getRow());
} }
final public double getY() { final public double getY(StringBounder stringBounder) {
if (task.getRow() == null) { if (task.getRow() == null) {
return y; return y;
} }
return getTrueRow().getY(); return getTrueRow().getY(stringBounder);
} }
public void pushMe(double deltaY) { public void pushMe(double deltaY) {
@ -131,14 +141,22 @@ public abstract class AbstractTaskDraw implements TaskDraw {
return task; return task;
} }
public final double getY(Direction direction) { public final double getY(StringBounder stringBounder, Direction direction) {
if (direction == Direction.UP) { if (direction == Direction.UP) {
return getY(); return getY(stringBounder);
} }
if (direction == Direction.DOWN) { if (direction == Direction.DOWN) {
return getY() + getHeightTask(); return getY(stringBounder) + getHeightTask(stringBounder);
} }
return getY() + getHeightTask() / 2; return getY(stringBounder) + getHeightTask(stringBounder) / 2;
}
protected final StyleBuilder getStyleBuilder() {
return styleBuilder;
}
protected final HColorSet getColorSet() {
return colorSet;
} }
} }

View File

@ -50,21 +50,21 @@ public interface TaskDraw extends UDrawable {
public void setColorsAndCompletion(CenterBorderColor colors, int completion, Url url, Display note); public void setColorsAndCompletion(CenterBorderColor colors, int completion, Url url, Display note);
public double getY(); public double getY(StringBounder stringBounder);
public double getY(Direction direction); public double getY(StringBounder stringBounder, Direction direction);
public void pushMe(double deltaY); public void pushMe(double deltaY);
public void drawTitle(UGraphic ug); public void drawTitle(UGraphic ug);
public double getHeightTask(); public double getHeightTask(StringBounder stringBounder);
public double getHeightMax(StringBounder stringBounder); public double getHeightMax(StringBounder stringBounder);
public Task getTask(); public Task getTask();
public FingerPrint getFingerPrint(); public FingerPrint getFingerPrint(StringBounder stringBounder);
public FingerPrint getFingerPrintNote(StringBounder stringBounder); public FingerPrint getFingerPrintNote(StringBounder stringBounder);

View File

@ -46,29 +46,28 @@ import net.sourceforge.plantuml.project.core.Task;
import net.sourceforge.plantuml.project.time.Day; import net.sourceforge.plantuml.project.time.Day;
import net.sourceforge.plantuml.project.timescale.TimeScale; import net.sourceforge.plantuml.project.timescale.TimeScale;
import net.sourceforge.plantuml.style.SName; import net.sourceforge.plantuml.style.SName;
import net.sourceforge.plantuml.style.Style; import net.sourceforge.plantuml.style.StyleBuilder;
import net.sourceforge.plantuml.style.StyleSignature; import net.sourceforge.plantuml.style.StyleSignature;
import net.sourceforge.plantuml.ugraphic.UGraphic; import net.sourceforge.plantuml.ugraphic.UGraphic;
import net.sourceforge.plantuml.ugraphic.UPolygon; import net.sourceforge.plantuml.ugraphic.UPolygon;
import net.sourceforge.plantuml.ugraphic.UShape; import net.sourceforge.plantuml.ugraphic.UShape;
import net.sourceforge.plantuml.ugraphic.UTranslate; import net.sourceforge.plantuml.ugraphic.UTranslate;
import net.sourceforge.plantuml.ugraphic.color.HColorSet;
public class TaskDrawDiamond extends AbstractTaskDraw { public class TaskDrawDiamond extends AbstractTaskDraw {
public TaskDrawDiamond(TimeScale timeScale, double y, String prettyDisplay, Day start, ISkinParam skinParam, public TaskDrawDiamond(TimeScale timeScale, double y, String prettyDisplay, Day start, ISkinParam skinParam,
Task task, ToTaskDraw toTaskDraw) { Task task, ToTaskDraw toTaskDraw, StyleBuilder styleBuilder, HColorSet colorSet) {
super(timeScale, y, prettyDisplay, start, skinParam, task, toTaskDraw); super(timeScale, y, prettyDisplay, start, skinParam, task, toTaskDraw, styleBuilder, colorSet);
} }
@Override @Override
protected Style getStyle() { StyleSignature getStyleSignature() {
final Style style = StyleSignature.of(SName.root, SName.element, SName.ganttDiagram, SName.milestone) return StyleSignature.of(SName.root, SName.element, SName.ganttDiagram, SName.milestone);
.getMergedStyle(skinParam.getCurrentStyleBuilder());
return style;
} }
public double getHeightMax(StringBounder stringBounder) { public double getHeightMax(StringBounder stringBounder) {
return getHeightTask(); return getHeightTask(stringBounder);
} }
// final UFont font = UFont.serif(11); // final UFont font = UFont.serif(11);
@ -77,9 +76,10 @@ public class TaskDrawDiamond extends AbstractTaskDraw {
final public void drawTitle(UGraphic ug) { final public void drawTitle(UGraphic ug) {
final TextBlock title = Display.getWithNewlines(prettyDisplay).create(getFontConfiguration(), final TextBlock title = Display.getWithNewlines(prettyDisplay).create(getFontConfiguration(),
HorizontalAlignment.LEFT, new SpriteContainerEmpty()); HorizontalAlignment.LEFT, new SpriteContainerEmpty());
final double titleHeight = title.calculateDimension(ug.getStringBounder()).getHeight(); final StringBounder stringBounder = ug.getStringBounder();
final double h = (margin + getShapeHeight() - titleHeight) / 2; final double titleHeight = title.calculateDimension(stringBounder).getHeight();
final double endingPosition = timeScale.getStartingPosition(start) + getHeightTask(); final double h = (margin + getShapeHeight(stringBounder) - titleHeight) / 2;
final double endingPosition = timeScale.getStartingPosition(start) + getHeightTask(stringBounder);
title.drawU(ug.apply(new UTranslate(endingPosition, h))); title.drawU(ug.apply(new UTranslate(endingPosition, h)));
} }
@ -98,21 +98,21 @@ public class TaskDrawDiamond extends AbstractTaskDraw {
} }
private void drawShape(UGraphic ug) { private void drawShape(UGraphic ug) {
ug.draw(getDiamond()); ug.draw(getDiamond(ug.getStringBounder()));
} }
public FingerPrint getFingerPrintNote(StringBounder stringBounder) { public FingerPrint getFingerPrintNote(StringBounder stringBounder) {
return null; return null;
} }
public FingerPrint getFingerPrint() { public FingerPrint getFingerPrint(StringBounder stringBounder) {
final double h = getHeightTask(); final double h = getHeightTask(stringBounder);
final double startPos = timeScale.getStartingPosition(start); final double startPos = timeScale.getStartingPosition(start);
return new FingerPrint(startPos, getY(), startPos + h, getY() + h); return new FingerPrint(startPos, getY(stringBounder), startPos + h, getY(stringBounder) + h);
} }
private UShape getDiamond() { private UShape getDiamond(StringBounder stringBounder) {
final double h = getHeightTask() - 2 * margin; final double h = getHeightTask(stringBounder) - 2 * margin;
final UPolygon result = new UPolygon(); final UPolygon result = new UPolygon();
result.addPoint(h / 2, 0); result.addPoint(h / 2, 0);
result.addPoint(h, h / 2); result.addPoint(h, h / 2);

View File

@ -60,6 +60,7 @@ import net.sourceforge.plantuml.project.timescale.TimeScale;
import net.sourceforge.plantuml.style.PName; import net.sourceforge.plantuml.style.PName;
import net.sourceforge.plantuml.style.SName; import net.sourceforge.plantuml.style.SName;
import net.sourceforge.plantuml.style.Style; import net.sourceforge.plantuml.style.Style;
import net.sourceforge.plantuml.style.StyleBuilder;
import net.sourceforge.plantuml.style.StyleSignature; import net.sourceforge.plantuml.style.StyleSignature;
import net.sourceforge.plantuml.svek.image.Opale; import net.sourceforge.plantuml.svek.image.Opale;
import net.sourceforge.plantuml.ugraphic.UGraphic; import net.sourceforge.plantuml.ugraphic.UGraphic;
@ -69,6 +70,7 @@ import net.sourceforge.plantuml.ugraphic.UStroke;
import net.sourceforge.plantuml.ugraphic.UTranslate; import net.sourceforge.plantuml.ugraphic.UTranslate;
import net.sourceforge.plantuml.ugraphic.color.HColor; import net.sourceforge.plantuml.ugraphic.color.HColor;
import net.sourceforge.plantuml.ugraphic.color.HColorNone; import net.sourceforge.plantuml.ugraphic.color.HColorNone;
import net.sourceforge.plantuml.ugraphic.color.HColorSet;
import net.sourceforge.plantuml.ugraphic.color.HColorUtils; import net.sourceforge.plantuml.ugraphic.color.HColorUtils;
public class TaskDrawRegular extends AbstractTaskDraw { public class TaskDrawRegular extends AbstractTaskDraw {
@ -78,13 +80,15 @@ public class TaskDrawRegular extends AbstractTaskDraw {
private final boolean oddEnd; private final boolean oddEnd;
private final Collection<Day> paused; private final Collection<Day> paused;
private final Collection<GanttConstraint> constraints; private final Collection<GanttConstraint> constraints;
private final ISkinParam skinParam;
private final double margin = 2; private final double margin = 2;
public TaskDrawRegular(TimeScale timeScale, double y, String prettyDisplay, Day start, Day end, boolean oddStart, public TaskDrawRegular(TimeScale timeScale, double y, String prettyDisplay, Day start, Day end, boolean oddStart,
boolean oddEnd, ISkinParam skinParam, Task task, ToTaskDraw toTaskDraw, boolean oddEnd, ISkinParam skinParam, Task task, ToTaskDraw toTaskDraw,
Collection<GanttConstraint> constraints) { Collection<GanttConstraint> constraints, StyleBuilder styleBuilder, HColorSet colorSet) {
super(timeScale, y, prettyDisplay, start, skinParam, task, toTaskDraw); super(timeScale, y, prettyDisplay, start, skinParam, task, toTaskDraw, styleBuilder, colorSet);
this.skinParam = skinParam;
this.constraints = constraints; this.constraints = constraints;
this.end = end; this.end = end;
this.oddStart = oddStart; this.oddStart = oddStart;
@ -102,8 +106,9 @@ public class TaskDrawRegular extends AbstractTaskDraw {
public void drawTitle(UGraphic ug) { public void drawTitle(UGraphic ug) {
final TextBlock title = Display.getWithNewlines(prettyDisplay).create(getFontConfiguration(), final TextBlock title = Display.getWithNewlines(prettyDisplay).create(getFontConfiguration(),
HorizontalAlignment.LEFT, new SpriteContainerEmpty()); HorizontalAlignment.LEFT, new SpriteContainerEmpty());
final Dimension2D dim = title.calculateDimension(ug.getStringBounder()); final StringBounder stringBounder = ug.getStringBounder();
final double h = (margin + getShapeHeight() - dim.getHeight()) / 2; final Dimension2D dim = title.calculateDimension(stringBounder);
final double h = (margin + getShapeHeight(stringBounder) - dim.getHeight()) / 2;
final double pos1 = timeScale.getStartingPosition(start) + 6; final double pos1 = timeScale.getStartingPosition(start) + 6;
final double pos2 = timeScale.getEndingPosition(end) - 6; final double pos2 = timeScale.getEndingPosition(end) - 6;
final double pos; final double pos;
@ -130,26 +135,21 @@ public class TaskDrawRegular extends AbstractTaskDraw {
return false; return false;
} }
// final UFont font = UFont.serif(11);
// return new FontConfiguration(font, HColorUtils.BLACK, HColorUtils.BLACK, false);
@Override @Override
protected Style getStyle() { StyleSignature getStyleSignature() {
final Style style = StyleSignature.of(SName.root, SName.element, SName.ganttDiagram, SName.task) return StyleSignature.of(SName.root, SName.element, SName.ganttDiagram, SName.task);
.getMergedStyle(skinParam.getCurrentStyleBuilder());
return style;
} }
public void drawU(UGraphic ug) { public void drawU(UGraphic ug) {
final double startPos = timeScale.getStartingPosition(start); final double startPos = timeScale.getStartingPosition(start);
drawNote(ug.apply((new UTranslate(startPos + margin, getYNotePosition())))); drawNote(ug.apply((new UTranslate(startPos + margin, getYNotePosition(ug.getStringBounder())))));
ug = applyColors(ug).apply(new UTranslate(margin, margin)); ug = applyColors(ug).apply(new UTranslate(margin, margin));
drawShape(ug); drawShape(ug);
} }
private double getYNotePosition() { private double getYNotePosition(StringBounder stringBounder) {
return getShapeHeight() + margin * 3; return getShapeHeight(stringBounder) + margin * 3;
} }
private void drawNote(UGraphic ug) { private void drawNote(UGraphic ug) {
@ -162,34 +162,34 @@ public class TaskDrawRegular extends AbstractTaskDraw {
public double getHeightMax(StringBounder stringBounder) { public double getHeightMax(StringBounder stringBounder) {
if (note == null) { if (note == null) {
return getHeightTask(); return getHeightTask(stringBounder);
} }
return getYNotePosition() + getOpaleNote().calculateDimension(stringBounder).getHeight(); return getYNotePosition(stringBounder) + getOpaleNote().calculateDimension(stringBounder).getHeight();
} }
private Opale getOpaleNote() { private Opale getOpaleNote() {
final Style style = StyleSignature.of(SName.root, SName.element, SName.ganttDiagram, SName.note) final Style style = StyleSignature.of(SName.root, SName.element, SName.ganttDiagram, SName.note)
.getMergedStyle(skinParam.getCurrentStyleBuilder()); .getMergedStyle(getStyleBuilder());
FontConfiguration fc = new FontConfiguration(skinParam, style);
final Sheet sheet = Parser final FontConfiguration fc = style.getFontConfiguration(getColorSet());
.build(fc, skinParam.getDefaultTextAlignment(HorizontalAlignment.LEFT), skinParam, CreoleMode.FULL)
.createSheet(note);
final SheetBlock1 sheet1 = new SheetBlock1(sheet, LineBreakStrategy.NONE, skinParam.getPadding());
final HColor noteBackgroundColor = style.value(PName.BackGroundColor).asColor(skinParam.getIHtmlColorSet()); final HorizontalAlignment horizontalAlignment = style.value(PName.HorizontalAlignment).asHorizontalAlignment();
final HColor borderColor = style.value(PName.LineColor).asColor(skinParam.getIHtmlColorSet()); final Sheet sheet = Parser.build(fc, horizontalAlignment, skinParam, CreoleMode.FULL).createSheet(note);
final double padding = style.value(PName.Padding).asDouble();
final SheetBlock1 sheet1 = new SheetBlock1(sheet, LineBreakStrategy.NONE, padding);
final HColor noteBackgroundColor = style.value(PName.BackGroundColor).asColor(getColorSet());
final HColor borderColor = style.value(PName.LineColor).asColor(getColorSet());
final double shadowing = style.value(PName.Shadowing).asDouble(); final double shadowing = style.value(PName.Shadowing).asDouble();
Opale opale = new Opale(shadowing, borderColor, noteBackgroundColor, sheet1, false); return new Opale(shadowing, borderColor, noteBackgroundColor, sheet1, false);
return opale;
} }
public FingerPrint getFingerPrint() { public FingerPrint getFingerPrint(StringBounder stringBounder) {
final double h = getHeightTask(); final double h = getHeightTask(stringBounder);
final double startPos = timeScale.getStartingPosition(start); final double startPos = timeScale.getStartingPosition(start);
final double endPos = timeScale.getEndingPosition(end); final double endPos = timeScale.getEndingPosition(end);
return new FingerPrint(startPos, getY(), endPos - startPos, h); return new FingerPrint(startPos, getY(stringBounder), endPos - startPos, h);
} }
public FingerPrint getFingerPrintNote(StringBounder stringBounder) { public FingerPrint getFingerPrintNote(StringBounder stringBounder) {
@ -199,7 +199,8 @@ public class TaskDrawRegular extends AbstractTaskDraw {
final Dimension2D dim = getOpaleNote().calculateDimension(stringBounder); final Dimension2D dim = getOpaleNote().calculateDimension(stringBounder);
final double startPos = timeScale.getStartingPosition(start); final double startPos = timeScale.getStartingPosition(start);
// final double endPos = timeScale.getEndingPosition(end); // final double endPos = timeScale.getEndingPosition(end);
return new FingerPrint(startPos, getY() + getYNotePosition(), dim.getWidth(), dim.getHeight()); return new FingerPrint(startPos, getY(stringBounder) + getYNotePosition(stringBounder), dim.getWidth(),
dim.getHeight());
} }
private UGraphic applyColors(UGraphic ug) { private UGraphic applyColors(UGraphic ug) {
@ -220,23 +221,24 @@ public class TaskDrawRegular extends AbstractTaskDraw {
if (url != null) { if (url != null) {
ug.startUrl(url); ug.startUrl(url);
} }
final StringBounder stringBounder = ug.getStringBounder();
if (oddStart && !oddEnd) { if (oddStart && !oddEnd) {
ug.apply(UTranslate.dx(startPos)).draw(PathUtils.UtoRight(fullLength, getShapeHeight())); ug.apply(UTranslate.dx(startPos)).draw(PathUtils.UtoRight(fullLength, getShapeHeight(stringBounder)));
} else if (!oddStart && oddEnd) { } else if (!oddStart && oddEnd) {
ug.apply(UTranslate.dx(startPos)).draw(PathUtils.UtoLeft(fullLength, getShapeHeight())); ug.apply(UTranslate.dx(startPos)).draw(PathUtils.UtoLeft(fullLength, getShapeHeight(stringBounder)));
} else { } else {
final URectangle full = new URectangle(fullLength, getShapeHeight()).rounded(8); final URectangle full = new URectangle(fullLength, getShapeHeight(stringBounder)).rounded(8);
if (completion == 100) { if (completion == 100) {
ug.apply(UTranslate.dx(startPos)).draw(full); ug.apply(UTranslate.dx(startPos)).draw(full);
} else { } else {
final double partialLength = fullLength * completion / 100.; final double partialLength = fullLength * completion / 100.;
ug.apply(UTranslate.dx(startPos)).apply(HColorUtils.WHITE).apply(HColorUtils.WHITE.bg()).draw(full); ug.apply(UTranslate.dx(startPos)).apply(HColorUtils.WHITE).apply(HColorUtils.WHITE.bg()).draw(full);
if (partialLength > 2) { if (partialLength > 2) {
final URectangle partial = new URectangle(partialLength, getShapeHeight()).rounded(8); final URectangle partial = new URectangle(partialLength, getShapeHeight(stringBounder)).rounded(8);
ug.apply(UTranslate.dx(startPos)).apply(new HColorNone()).draw(partial); ug.apply(UTranslate.dx(startPos)).apply(new HColorNone()).draw(partial);
} }
if (partialLength > 10 && partialLength < fullLength - 10) { if (partialLength > 10 && partialLength < fullLength - 10) {
final URectangle patch = new URectangle(8, getShapeHeight()); final URectangle patch = new URectangle(8, getShapeHeight(stringBounder));
ug.apply(UTranslate.dx(startPos)).apply(new HColorNone()).apply(UTranslate.dx(partialLength - 8)) ug.apply(UTranslate.dx(startPos)).apply(new HColorNone()).apply(UTranslate.dx(partialLength - 8))
.draw(patch); .draw(patch);
} }
@ -264,13 +266,14 @@ public class TaskDrawRegular extends AbstractTaskDraw {
private void drawPause(UGraphic ug, Day start1, Day end) { private void drawPause(UGraphic ug, Day start1, Day end) {
final double x1 = timeScale.getStartingPosition(start1); final double x1 = timeScale.getStartingPosition(start1);
final double x2 = timeScale.getEndingPosition(end); final double x2 = timeScale.getEndingPosition(end);
final URectangle small = new URectangle(x2 - x1 - 1, getShapeHeight() + 1); final StringBounder stringBounder = ug.getStringBounder();
final URectangle small = new URectangle(x2 - x1 - 1, getShapeHeight(stringBounder) + 1);
final ULine line = ULine.hline(x2 - x1 - 1); final ULine line = ULine.hline(x2 - x1 - 1);
ug = ug.apply(UTranslate.dx(x1 - 1)); ug = ug.apply(UTranslate.dx(x1 - 1));
ug.apply(HColorUtils.WHITE).apply(HColorUtils.WHITE.bg()).draw(small); ug.apply(HColorUtils.WHITE).apply(HColorUtils.WHITE.bg()).draw(small);
final UGraphic ugLine = ug.apply(new UStroke(2, 3, 1)); final UGraphic ugLine = ug.apply(new UStroke(2, 3, 1));
ugLine.draw(line); ugLine.draw(line);
ugLine.apply(UTranslate.dy(getShapeHeight())).draw(line); ugLine.apply(UTranslate.dy(getShapeHeight(stringBounder))).draw(line);
} }
} }

View File

@ -48,10 +48,18 @@ import net.sourceforge.plantuml.project.core.Task;
import net.sourceforge.plantuml.project.lang.CenterBorderColor; import net.sourceforge.plantuml.project.lang.CenterBorderColor;
import net.sourceforge.plantuml.project.time.Day; import net.sourceforge.plantuml.project.time.Day;
import net.sourceforge.plantuml.project.timescale.TimeScale; import net.sourceforge.plantuml.project.timescale.TimeScale;
import net.sourceforge.plantuml.ugraphic.UFont; import net.sourceforge.plantuml.style.ClockwiseTopRightBottomLeft;
import net.sourceforge.plantuml.style.PName;
import net.sourceforge.plantuml.style.SName;
import net.sourceforge.plantuml.style.Style;
import net.sourceforge.plantuml.style.StyleBuilder;
import net.sourceforge.plantuml.style.StyleSignature;
import net.sourceforge.plantuml.ugraphic.UGraphic; import net.sourceforge.plantuml.ugraphic.UGraphic;
import net.sourceforge.plantuml.ugraphic.ULine; import net.sourceforge.plantuml.ugraphic.ULine;
import net.sourceforge.plantuml.ugraphic.URectangle;
import net.sourceforge.plantuml.ugraphic.UTranslate; import net.sourceforge.plantuml.ugraphic.UTranslate;
import net.sourceforge.plantuml.ugraphic.color.HColor;
import net.sourceforge.plantuml.ugraphic.color.HColorSet;
import net.sourceforge.plantuml.ugraphic.color.HColorUtils; import net.sourceforge.plantuml.ugraphic.color.HColorUtils;
public class TaskDrawSeparator implements TaskDraw { public class TaskDrawSeparator implements TaskDraw {
@ -61,8 +69,13 @@ public class TaskDrawSeparator implements TaskDraw {
private final Day min; private final Day min;
private final Day max; private final Day max;
private final String name; private final String name;
private final StyleBuilder styleBuilder;
private final HColorSet colorSet;
public TaskDrawSeparator(String name, TimeScale timeScale, double y, Day min, Day max) { public TaskDrawSeparator(String name, TimeScale timeScale, double y, Day min, Day max, StyleBuilder styleBuilder,
HColorSet colorSet) {
this.styleBuilder = styleBuilder;
this.colorSet = colorSet;
this.name = name; this.name = name;
this.y = y; this.y = y;
this.timeScale = timeScale; this.timeScale = timeScale;
@ -71,7 +84,19 @@ public class TaskDrawSeparator implements TaskDraw {
} }
public void drawTitle(UGraphic ug) { public void drawTitle(UGraphic ug) {
getTitle().drawU(ug.apply(UTranslate.dx(MARGIN1))); final ClockwiseTopRightBottomLeft padding = getStyle().getPadding();
final ClockwiseTopRightBottomLeft margin = getStyle().getMargin();
final double dx = margin.getLeft() + padding.getLeft();
final double dy = margin.getTop() + padding.getTop();
getTitle().drawU(ug.apply(new UTranslate(dx, dy)));
}
private StyleSignature getStyleSignature() {
return StyleSignature.of(SName.root, SName.element, SName.ganttDiagram, SName.separator);
}
private Style getStyle() {
return getStyleSignature().getMergedStyle(styleBuilder);
} }
private TextBlock getTitle() { private TextBlock getTitle() {
@ -83,43 +108,67 @@ public class TaskDrawSeparator implements TaskDraw {
} }
private FontConfiguration getFontConfiguration() { private FontConfiguration getFontConfiguration() {
final UFont font = UFont.serif(11); return getStyle().getFontConfiguration(colorSet);
return new FontConfiguration(font, HColorUtils.BLACK, HColorUtils.BLACK, false);
} }
private final static double MARGIN1 = 10;
private final static double MARGIN2 = 2;
public void drawU(UGraphic ug) { public void drawU(UGraphic ug) {
final double widthTitle = getTitle().calculateDimension(ug.getStringBounder()).getWidth(); final StringBounder stringBounder = ug.getStringBounder();
final double start = timeScale.getStartingPosition(min) + widthTitle; final double widthTitle = getTitle().calculateDimension(stringBounder).getWidth();
final double start = timeScale.getStartingPosition(min);
// final double start2 = start1 + widthTitle;
final double end = timeScale.getEndingPosition(max); final double end = timeScale.getEndingPosition(max);
ug = ug.apply(HColorUtils.BLACK); final ClockwiseTopRightBottomLeft padding = getStyle().getPadding();
ug = ug.apply(UTranslate.dy(getHeightTask() / 2)); final ClockwiseTopRightBottomLeft margin = getStyle().getMargin();
ug = ug.apply(new UTranslate(0, margin.getTop()));
final HColor backColor = getStyle().value(PName.BackGroundColor).asColor(colorSet);
if (HColorUtils.isTransparent(backColor) == false) {
final double height = padding.getTop() + getTextHeight(stringBounder) + padding.getBottom();
if (height > 0) {
final URectangle rect = new URectangle(end - start, height);
ug.apply(backColor.bg()).draw(rect);
}
}
final HColor lineColor = getStyle().value(PName.LineColor).asColor(colorSet);
ug = ug.apply(lineColor);
ug = ug.apply(UTranslate.dy(padding.getTop() + getTextHeight(stringBounder) / 2));
if (widthTitle == 0) { if (widthTitle == 0) {
final ULine line = ULine.hline(end - start); final ULine line = ULine.hline(end - start);
ug.draw(line); ug.draw(line);
} else { } else {
final ULine line1 = ULine.hline(MARGIN1 - MARGIN2); if (padding.getLeft() > 1) {
final ULine line2 = ULine.hline(end - start - MARGIN1 - MARGIN2); final ULine line1 = ULine.hline(padding.getLeft());
ug.draw(line1); ug.draw(line1);
ug.apply(UTranslate.dx(widthTitle + MARGIN1 + MARGIN2)).draw(line2); }
final double x1 = padding.getLeft() + margin.getLeft() + widthTitle + margin.getRight();
final double x2 = end - 1;
final ULine line2 = ULine.hline(x2 - x1);
ug.apply(UTranslate.dx(x1)).draw(line2);
} }
} }
public FingerPrint getFingerPrint() { public FingerPrint getFingerPrint(StringBounder stringBounder) {
final double h = getHeightTask(); final double h = getHeightTask(stringBounder);
final double end = timeScale.getEndingPosition(max); final double end = timeScale.getEndingPosition(max);
return new FingerPrint(0, y, end, y + h); return new FingerPrint(0, y, end, y + h);
} }
public double getHeightTask() { public double getHeightTask(StringBounder stringBounder) {
return 16; final ClockwiseTopRightBottomLeft padding = getStyle().getPadding();
final ClockwiseTopRightBottomLeft margin = getStyle().getMargin();
return margin.getTop() + padding.getTop() + getTextHeight(stringBounder) + padding.getBottom()
+ margin.getBottom();
} }
public double getY() { private double getTextHeight(StringBounder stringBounder) {
return getTitle().calculateDimension(stringBounder).getHeight();
}
public double getY(StringBounder stringBounder) {
return y; return y;
} }
@ -138,7 +187,7 @@ public class TaskDrawSeparator implements TaskDraw {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
public double getY(Direction direction) { public double getY(StringBounder stringBounder, Direction direction) {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
@ -147,7 +196,7 @@ public class TaskDrawSeparator implements TaskDraw {
} }
public double getHeightMax(StringBounder stringBounder) { public double getHeightMax(StringBounder stringBounder) {
return getHeightTask(); return getHeightTask(stringBounder);
} }
} }

View File

@ -75,7 +75,7 @@ public abstract class TimeHeader {
this.max = max; this.max = max;
} }
protected abstract double getTimeHeaderHeight(); public abstract double getTimeHeaderHeight();
public abstract double getTimeFooterHeight(); public abstract double getTimeFooterHeight();
@ -116,12 +116,13 @@ public abstract class TimeHeader {
text.drawU(ug.apply(UTranslate.dx(start + diff / 2))); text.drawU(ug.apply(UTranslate.dx(start + diff / 2)));
} }
protected final void printCentered(UGraphic ug, double start, double end, TextBlock... texts) { protected final void printCentered(UGraphic ug, boolean hideIfTooBig, double start, double end,
TextBlock... texts) {
final double available = end - start; final double available = end - start;
for (int i = texts.length - 1; i >= 0; i--) { for (int i = texts.length - 1; i >= 0; i--) {
final TextBlock text = texts[i]; final TextBlock text = texts[i];
final double width = text.calculateDimension(ug.getStringBounder()).getWidth(); final double width = text.calculateDimension(ug.getStringBounder()).getWidth();
if (i == 0 || width <= available) { if ((i == 0 && hideIfTooBig == false) || width <= available) {
final double diff = Math.max(0, available - width); final double diff = Math.max(0, available - width);
text.drawU(ug.apply(UTranslate.dx(start + diff / 2))); text.drawU(ug.apply(UTranslate.dx(start + diff / 2)));
return; return;

View File

@ -51,7 +51,7 @@ import net.sourceforge.plantuml.ugraphic.color.HColorUtils;
public class TimeHeaderDaily extends TimeHeaderCalendar { public class TimeHeaderDaily extends TimeHeaderCalendar {
protected double getTimeHeaderHeight() { public double getTimeHeaderHeight() {
return Y_POS_ROW28() + 13; return Y_POS_ROW28() + 13;
} }
@ -153,7 +153,7 @@ public class TimeHeaderDaily extends TimeHeaderCalendar {
final TextBlock tiny = getTextBlock(monthYear.shortName(), 12, true, HColorUtils.BLACK); final TextBlock tiny = getTextBlock(monthYear.shortName(), 12, true, HColorUtils.BLACK);
final TextBlock small = getTextBlock(monthYear.longName(), 12, true, HColorUtils.BLACK); final TextBlock small = getTextBlock(monthYear.longName(), 12, true, HColorUtils.BLACK);
final TextBlock big = getTextBlock(monthYear.longNameYYYY(), 12, true, HColorUtils.BLACK); final TextBlock big = getTextBlock(monthYear.longNameYYYY(), 12, true, HColorUtils.BLACK);
printCentered(ug, start, end, tiny, small, big); printCentered(ug, false, start, end, tiny, small, big);
} }
private void drawVbar(UGraphic ug, double x, double y1, double y2) { private void drawVbar(UGraphic ug, double x, double y1, double y2) {

View File

@ -39,7 +39,6 @@ import java.util.Map;
import net.sourceforge.plantuml.graphic.TextBlock; import net.sourceforge.plantuml.graphic.TextBlock;
import net.sourceforge.plantuml.project.LoadPlanable; import net.sourceforge.plantuml.project.LoadPlanable;
import net.sourceforge.plantuml.project.core.PrintScale;
import net.sourceforge.plantuml.project.time.Day; import net.sourceforge.plantuml.project.time.Day;
import net.sourceforge.plantuml.project.time.DayOfWeek; import net.sourceforge.plantuml.project.time.DayOfWeek;
import net.sourceforge.plantuml.project.time.MonthYear; import net.sourceforge.plantuml.project.time.MonthYear;
@ -52,7 +51,7 @@ import net.sourceforge.plantuml.ugraphic.color.HColorUtils;
public class TimeHeaderMonthly extends TimeHeaderCalendar { public class TimeHeaderMonthly extends TimeHeaderCalendar {
protected double getTimeHeaderHeight() { public double getTimeHeaderHeight() {
return 16 + 13; return 16 + 13;
} }
@ -60,10 +59,10 @@ public class TimeHeaderMonthly extends TimeHeaderCalendar {
return 16 + 13 - 1; return 16 + 13 - 1;
} }
public TimeHeaderMonthly(Day calendar, Day min, Day max, LoadPlanable defaultPlan, Map<Day, HColor> colorDays, public TimeHeaderMonthly(double scale, Day calendar, Day min, Day max, LoadPlanable defaultPlan, Map<Day, HColor> colorDays,
Map<DayOfWeek, HColor> colorDaysOfWeek, int compress) { Map<DayOfWeek, HColor> colorDaysOfWeek) {
super(calendar, min, max, defaultPlan, colorDays, colorDaysOfWeek, super(calendar, min, max, defaultPlan, colorDays, colorDaysOfWeek,
new TimeScaleCompressed(calendar, compress)); new TimeScaleCompressed(calendar, scale));
} }
@Override @Override
@ -130,13 +129,13 @@ public class TimeHeaderMonthly extends TimeHeaderCalendar {
private void printYear(UGraphic ug, MonthYear monthYear, double start, double end) { private void printYear(UGraphic ug, MonthYear monthYear, double start, double end) {
final TextBlock small = getTextBlock("" + monthYear.year(), 12, true, HColorUtils.BLACK); final TextBlock small = getTextBlock("" + monthYear.year(), 12, true, HColorUtils.BLACK);
printCentered(ug, start, end, small); printCentered(ug, false, start, end, small);
} }
private void printMonth(UGraphic ug, MonthYear monthYear, double start, double end) { private void printMonth(UGraphic ug, MonthYear monthYear, double start, double end) {
final TextBlock small = getTextBlock(monthYear.shortName(), 10, false, HColorUtils.BLACK); final TextBlock small = getTextBlock(monthYear.shortName(), 10, false, HColorUtils.BLACK);
final TextBlock big = getTextBlock(monthYear.longName(), 10, false, HColorUtils.BLACK); final TextBlock big = getTextBlock(monthYear.longName(), 10, false, HColorUtils.BLACK);
printCentered(ug, start, end, small, big); printCentered(ug, false, start, end, small, big);
} }
private void drawVbar(UGraphic ug, double x, double y1, double y2) { private void drawVbar(UGraphic ug, double x, double y1, double y2) {

View File

@ -39,7 +39,6 @@ import java.util.Map;
import net.sourceforge.plantuml.graphic.TextBlock; import net.sourceforge.plantuml.graphic.TextBlock;
import net.sourceforge.plantuml.project.LoadPlanable; import net.sourceforge.plantuml.project.LoadPlanable;
import net.sourceforge.plantuml.project.core.PrintScale;
import net.sourceforge.plantuml.project.time.Day; import net.sourceforge.plantuml.project.time.Day;
import net.sourceforge.plantuml.project.time.DayOfWeek; import net.sourceforge.plantuml.project.time.DayOfWeek;
import net.sourceforge.plantuml.project.time.MonthYear; import net.sourceforge.plantuml.project.time.MonthYear;
@ -52,7 +51,7 @@ import net.sourceforge.plantuml.ugraphic.color.HColorUtils;
public class TimeHeaderQuarterly extends TimeHeaderCalendar { public class TimeHeaderQuarterly extends TimeHeaderCalendar {
protected double getTimeHeaderHeight() { public double getTimeHeaderHeight() {
return 16 + 13; return 16 + 13;
} }
@ -60,10 +59,10 @@ public class TimeHeaderQuarterly extends TimeHeaderCalendar {
return 16 + 13 - 1; return 16 + 13 - 1;
} }
public TimeHeaderQuarterly(Day calendar, Day min, Day max, LoadPlanable defaultPlan, Map<Day, HColor> colorDays, public TimeHeaderQuarterly(double scale, Day calendar, Day min, Day max, LoadPlanable defaultPlan, Map<Day, HColor> colorDays,
Map<DayOfWeek, HColor> colorDaysOfWeek, int compress) { Map<DayOfWeek, HColor> colorDaysOfWeek) {
super(calendar, min, max, defaultPlan, colorDays, colorDaysOfWeek, super(calendar, min, max, defaultPlan, colorDays, colorDaysOfWeek,
new TimeScaleCompressed(calendar, compress)); new TimeScaleCompressed(calendar, scale));
} }
@Override @Override
@ -134,12 +133,12 @@ public class TimeHeaderQuarterly extends TimeHeaderCalendar {
private void printYear(UGraphic ug, MonthYear monthYear, double start, double end) { private void printYear(UGraphic ug, MonthYear monthYear, double start, double end) {
final TextBlock small = getTextBlock("" + monthYear.year(), 12, true, HColorUtils.BLACK); final TextBlock small = getTextBlock("" + monthYear.year(), 12, true, HColorUtils.BLACK);
printCentered(ug, start, end, small); printCentered(ug, false, start, end, small);
} }
private void printQuarter(UGraphic ug, String quarter, double start, double end) { private void printQuarter(UGraphic ug, String quarter, double start, double end) {
final TextBlock small = getTextBlock(quarter, 10, false, HColorUtils.BLACK); final TextBlock small = getTextBlock(quarter, 10, false, HColorUtils.BLACK);
printCentered(ug, start, end, small); printCentered(ug, false, start, end, small);
} }
private void drawVbar(UGraphic ug, double x, double y1, double y2) { private void drawVbar(UGraphic ug, double x, double y1, double y2) {

View File

@ -54,7 +54,7 @@ public class TimeHeaderSimple extends TimeHeader {
return getTimeHeaderHeight() + getHeaderNameDayHeight(); return getTimeHeaderHeight() + getHeaderNameDayHeight();
} }
protected double getTimeHeaderHeight() { public double getTimeHeaderHeight() {
return 16; return 16;
} }

View File

@ -39,10 +39,10 @@ import java.util.Map;
import net.sourceforge.plantuml.graphic.TextBlock; import net.sourceforge.plantuml.graphic.TextBlock;
import net.sourceforge.plantuml.project.LoadPlanable; import net.sourceforge.plantuml.project.LoadPlanable;
import net.sourceforge.plantuml.project.core.PrintScale;
import net.sourceforge.plantuml.project.time.Day; import net.sourceforge.plantuml.project.time.Day;
import net.sourceforge.plantuml.project.time.DayOfWeek; import net.sourceforge.plantuml.project.time.DayOfWeek;
import net.sourceforge.plantuml.project.time.MonthYear; import net.sourceforge.plantuml.project.time.MonthYear;
import net.sourceforge.plantuml.project.time.WeekNumberStrategy;
import net.sourceforge.plantuml.project.timescale.TimeScaleCompressed; import net.sourceforge.plantuml.project.timescale.TimeScaleCompressed;
import net.sourceforge.plantuml.ugraphic.UGraphic; import net.sourceforge.plantuml.ugraphic.UGraphic;
import net.sourceforge.plantuml.ugraphic.ULine; import net.sourceforge.plantuml.ugraphic.ULine;
@ -52,7 +52,9 @@ import net.sourceforge.plantuml.ugraphic.color.HColorUtils;
public class TimeHeaderWeekly extends TimeHeaderCalendar { public class TimeHeaderWeekly extends TimeHeaderCalendar {
protected double getTimeHeaderHeight() { private final WeekNumberStrategy weekNumberStrategy;
public double getTimeHeaderHeight() {
return 16 + 13; return 16 + 13;
} }
@ -60,10 +62,10 @@ public class TimeHeaderWeekly extends TimeHeaderCalendar {
return 16; return 16;
} }
public TimeHeaderWeekly(Day calendar, Day min, Day max, LoadPlanable defaultPlan, Map<Day, HColor> colorDays, public TimeHeaderWeekly(double scale, Day calendar, Day min, Day max, LoadPlanable defaultPlan,
Map<DayOfWeek, HColor> colorDaysOfWeek, int compress) { Map<Day, HColor> colorDays, Map<DayOfWeek, HColor> colorDaysOfWeek, WeekNumberStrategy weekNumberStrategy) {
super(calendar, min, max, defaultPlan, colorDays, colorDaysOfWeek, super(calendar, min, max, defaultPlan, colorDays, colorDaysOfWeek, new TimeScaleCompressed(calendar, scale));
new TimeScaleCompressed(calendar, compress)); this.weekNumberStrategy = weekNumberStrategy;
} }
@Override @Override
@ -111,7 +113,7 @@ public class TimeHeaderWeekly extends TimeHeaderCalendar {
private void printSmallVbars(final UGraphic ug, double totalHeightWithoutFooter) { private void printSmallVbars(final UGraphic ug, double totalHeightWithoutFooter) {
for (Day wink = min; wink.compareTo(max) <= 0; wink = wink.increment()) { for (Day wink = min; wink.compareTo(max) <= 0; wink = wink.increment()) {
if (wink.getDayOfWeek() == DayOfWeek.MONDAY) { if (wink.getDayOfWeek() == weekNumberStrategy.getFirstDayOfWeek()) {
drawVbar(ug, getTimeScale().getStartingPosition(wink), Y_POS_ROW16(), totalHeightWithoutFooter); drawVbar(ug, getTimeScale().getStartingPosition(wink), Y_POS_ROW16(), totalHeightWithoutFooter);
} }
} }
@ -120,9 +122,11 @@ public class TimeHeaderWeekly extends TimeHeaderCalendar {
private void printDaysOfMonth(final UGraphic ug) { private void printDaysOfMonth(final UGraphic ug) {
for (Day wink = min; wink.compareTo(max) < 0; wink = wink.increment()) { for (Day wink = min; wink.compareTo(max) < 0; wink = wink.increment()) {
if (wink.getDayOfWeek() == DayOfWeek.MONDAY) { if (wink.getDayOfWeek() == weekNumberStrategy.getFirstDayOfWeek()) {
printLeft(ug.apply(UTranslate.dy(Y_POS_ROW16())), final String num = "" + wink.getWeekOfYear(weekNumberStrategy);
getTextBlock("" + wink.getDayOfMonth(), 10, false, HColorUtils.BLACK), // final String num = "" + wink.getDayOfMonth();
final TextBlock textBlock = getTextBlock(num, 10, false, HColorUtils.BLACK);
printLeft(ug.apply(UTranslate.dy(Y_POS_ROW16())), textBlock,
getTimeScale().getStartingPosition(wink) + 5); getTimeScale().getStartingPosition(wink) + 5);
} }
} }
@ -131,7 +135,7 @@ public class TimeHeaderWeekly extends TimeHeaderCalendar {
private void printMonth(UGraphic ug, MonthYear monthYear, double start, double end) { private void printMonth(UGraphic ug, MonthYear monthYear, double start, double end) {
final TextBlock small = getTextBlock(monthYear.shortName(), 12, true, HColorUtils.BLACK); final TextBlock small = getTextBlock(monthYear.shortName(), 12, true, HColorUtils.BLACK);
final TextBlock big = getTextBlock(monthYear.shortNameYYYY(), 12, true, HColorUtils.BLACK); final TextBlock big = getTextBlock(monthYear.shortNameYYYY(), 12, true, HColorUtils.BLACK);
printCentered(ug, start, end, small, big); printCentered(ug, false, start, end, small, big);
} }
private void drawVbar(UGraphic ug, double x, double y1, double y2) { private void drawVbar(UGraphic ug, double x, double y1, double y2) {

View File

@ -39,7 +39,6 @@ import java.util.Map;
import net.sourceforge.plantuml.graphic.TextBlock; import net.sourceforge.plantuml.graphic.TextBlock;
import net.sourceforge.plantuml.project.LoadPlanable; import net.sourceforge.plantuml.project.LoadPlanable;
import net.sourceforge.plantuml.project.core.PrintScale;
import net.sourceforge.plantuml.project.time.Day; import net.sourceforge.plantuml.project.time.Day;
import net.sourceforge.plantuml.project.time.DayOfWeek; import net.sourceforge.plantuml.project.time.DayOfWeek;
import net.sourceforge.plantuml.project.time.MonthYear; import net.sourceforge.plantuml.project.time.MonthYear;
@ -52,18 +51,17 @@ import net.sourceforge.plantuml.ugraphic.color.HColorUtils;
public class TimeHeaderYearly extends TimeHeaderCalendar { public class TimeHeaderYearly extends TimeHeaderCalendar {
protected double getTimeHeaderHeight() { public double getTimeHeaderHeight() {
return 16 + 13; return 20;
} }
public double getTimeFooterHeight() { public double getTimeFooterHeight() {
return 16 + 13 - 1; return 20 - 1;
} }
public TimeHeaderYearly(Day calendar, Day min, Day max, LoadPlanable defaultPlan, Map<Day, HColor> colorDays, public TimeHeaderYearly(double scale, Day calendar, Day min, Day max, LoadPlanable defaultPlan,
Map<DayOfWeek, HColor> colorDaysOfWeek, int compress) { Map<Day, HColor> colorDays, Map<DayOfWeek, HColor> colorDaysOfWeek) {
super(calendar, min, max, defaultPlan, colorDays, colorDaysOfWeek, super(calendar, min, max, defaultPlan, colorDays, colorDaysOfWeek, new TimeScaleCompressed(calendar, scale));
new TimeScaleCompressed(calendar, compress));
} }
@Override @Override
@ -88,7 +86,7 @@ public class TimeHeaderYearly extends TimeHeaderCalendar {
for (Day wink = min; wink.compareTo(max) < 0; wink = wink.increment()) { for (Day wink = min; wink.compareTo(max) < 0; wink = wink.increment()) {
final double x1 = getTimeScale().getStartingPosition(wink); final double x1 = getTimeScale().getStartingPosition(wink);
if (last == null || wink.monthYear().year() != last.year()) { if (last == null || wink.monthYear().year() != last.year()) {
drawVbar(ug, x1, 0, 15); drawVbar(ug, x1, 0, 19);
if (last != null) { if (last != null) {
printYear(ug, last, lastChange, x1); printYear(ug, last, lastChange, x1);
} }
@ -100,39 +98,12 @@ public class TimeHeaderYearly extends TimeHeaderCalendar {
if (x1 > lastChange) { if (x1 > lastChange) {
printYear(ug, last, lastChange, x1); printYear(ug, last, lastChange, x1);
} }
drawVbar(ug, getTimeScale().getEndingPosition(max), 0, 15); drawVbar(ug, getTimeScale().getEndingPosition(max), 0, 19);
}
private void drawMonths(UGraphic ug) {
MonthYear last = null;
double lastChange = -1;
for (Day wink = min; wink.compareTo(max) < 0; wink = wink.increment()) {
final double x1 = getTimeScale().getStartingPosition(wink);
if (wink.monthYear().equals(last) == false) {
drawVbar(ug, x1, 0, 12);
if (last != null) {
printMonth(ug, last, lastChange, x1);
}
lastChange = x1;
last = wink.monthYear();
}
}
final double x1 = getTimeScale().getStartingPosition(max.increment());
if (x1 > lastChange) {
printMonth(ug, last, lastChange, x1);
}
drawVbar(ug, getTimeScale().getEndingPosition(max), 0, 12);
} }
private void printYear(UGraphic ug, MonthYear monthYear, double start, double end) { private void printYear(UGraphic ug, MonthYear monthYear, double start, double end) {
final TextBlock small = getTextBlock("" + monthYear.year(), 12, true, HColorUtils.BLACK); final TextBlock small = getTextBlock("" + monthYear.year(), 14, true, HColorUtils.BLACK);
printCentered(ug, start, end, small); printCentered(ug, true, start, end, small);
}
private void printMonth(UGraphic ug, MonthYear monthYear, double start, double end) {
final TextBlock small = getTextBlock(monthYear.shortName(), 10, false, HColorUtils.BLACK);
final TextBlock big = getTextBlock(monthYear.longName(), 10, false, HColorUtils.BLACK);
printCentered(ug, start, end, small, big);
} }
private void drawVbar(UGraphic ug, double x, double y1, double y2) { private void drawVbar(UGraphic ug, double x, double y1, double y2) {
@ -140,10 +111,6 @@ public class TimeHeaderYearly extends TimeHeaderCalendar {
ug.apply(HColorUtils.LIGHT_GRAY).apply(new UTranslate(x, y1)).draw(vbar); ug.apply(HColorUtils.LIGHT_GRAY).apply(new UTranslate(x, y1)).draw(vbar);
} }
private void printLeft(UGraphic ug, TextBlock text, double start) {
text.drawU(ug.apply(UTranslate.dx(start)));
}
@Override @Override
public double getFullHeaderHeight() { public double getFullHeaderHeight() {
return getTimeHeaderHeight(); return getTimeHeaderHeight();

View File

@ -53,7 +53,8 @@ public class SentenceEnds extends SentenceSimple {
final Task task = (Task) subject; final Task task = (Task) subject;
final TaskInstant when = (TaskInstant) complement; final TaskInstant when = (TaskInstant) complement;
task.setEnd(when.getInstantPrecise().decrement()); task.setEnd(when.getInstantPrecise().decrement());
project.addContraint(new GanttConstraint(when, new TaskInstant(task, TaskAttribute.END))); project.addContraint(new GanttConstraint(project.getIHtmlColorSet(), project.getCurrentStyleBuilder(), when,
new TaskInstant(task, TaskAttribute.END)));
return CommandExecutionResult.ok(); return CommandExecutionResult.ok();
} }

View File

@ -64,10 +64,10 @@ public class SentenceOccurs extends SentenceSimple {
} }
task.setStart(from.getEnd()); task.setStart(from.getEnd());
task.setEnd(to.getEnd()); task.setEnd(to.getEnd());
project.addContraint(new GanttConstraint(new TaskInstant(from, TaskAttribute.START), project.addContraint(new GanttConstraint(project.getIHtmlColorSet(), project.getCurrentStyleBuilder(),
new TaskInstant(task, TaskAttribute.START))); new TaskInstant(from, TaskAttribute.START), new TaskInstant(task, TaskAttribute.START)));
project.addContraint( project.addContraint(new GanttConstraint(project.getIHtmlColorSet(), project.getCurrentStyleBuilder(),
new GanttConstraint(new TaskInstant(to, TaskAttribute.END), new TaskInstant(task, TaskAttribute.END))); new TaskInstant(to, TaskAttribute.END), new TaskInstant(task, TaskAttribute.END)));
return CommandExecutionResult.ok(); return CommandExecutionResult.ok();
} }

View File

@ -57,7 +57,8 @@ public class SentenceTaskStarts extends SentenceSimple {
when = (TaskInstant) complement; when = (TaskInstant) complement;
task.setStart(when.getInstantPrecise()); task.setStart(when.getInstantPrecise());
if (when.isTask()) { if (when.isTask()) {
project.addContraint(new GanttConstraint(when, new TaskInstant(task, TaskAttribute.START), color)); project.addContraint(new GanttConstraint(project.getIHtmlColorSet(), project.getCurrentStyleBuilder(), when,
new TaskInstant(task, TaskAttribute.START), color));
} }
return CommandExecutionResult.ok(); return CommandExecutionResult.ok();

View File

@ -62,7 +62,8 @@ public class SentenceTaskStartsWithColor extends SentenceSimple {
task.setStart(when.getInstantPrecise()); task.setStart(when.getInstantPrecise());
if (when.isTask()) { if (when.isTask()) {
final HColor color = complement22.getCenter(); final HColor color = complement22.getCenter();
final GanttConstraint link = new GanttConstraint(when, new TaskInstant(task, TaskAttribute.START), color); final GanttConstraint link = new GanttConstraint(project.getIHtmlColorSet(),
project.getCurrentStyleBuilder(), when, new TaskInstant(task, TaskAttribute.START), color);
link.applyStyle(complement22.getStyle()); link.applyStyle(complement22.getStyle());
project.addContraint(link); project.addContraint(link);
} }

View File

@ -45,6 +45,7 @@ import net.sourceforge.plantuml.command.regex.RegexResult;
import net.sourceforge.plantuml.project.Failable; import net.sourceforge.plantuml.project.Failable;
import net.sourceforge.plantuml.project.GanttDiagram; import net.sourceforge.plantuml.project.GanttDiagram;
// Removed
public class SubjectLinks implements Subject { public class SubjectLinks implements Subject {
public IRegex toRegex() { public IRegex toRegex() {
@ -68,7 +69,7 @@ public class SubjectLinks implements Subject {
@Override @Override
public CommandExecutionResult execute(GanttDiagram project, Object subject, Object complement) { public CommandExecutionResult execute(GanttDiagram project, Object subject, Object complement) {
final CenterBorderColor colors = (CenterBorderColor) complement; final CenterBorderColor colors = (CenterBorderColor) complement;
project.setLinksColor(colors.getCenter()); // project.setLinksColor(colors.getCenter());
return CommandExecutionResult.ok(); return CommandExecutionResult.ok();
} }

View File

@ -65,6 +65,16 @@ public class Day implements Comparable<Day>, Value {
return create(System.currentTimeMillis()); return create(System.currentTimeMillis());
} }
public int getWeekOfYear(WeekNumberStrategy strategy) {
synchronized (gmt) {
gmt.clear();
gmt.setTimeInMillis(ms1);
gmt.setFirstDayOfWeek(strategy.getFirstDayOfWeekAsLegacyInt());
gmt.setMinimalDaysInFirstWeek(strategy.getMinimalDaysInFirstWeek());
return gmt.get(Calendar.WEEK_OF_YEAR);
}
}
private Day(int year, Month month, int dayOfMonth) { private Day(int year, Month month, int dayOfMonth) {
this.dayOfMonth = dayOfMonth; this.dayOfMonth = dayOfMonth;
this.monthYear = MonthYear.create(year, month); this.monthYear = MonthYear.create(year, month);

View File

@ -44,7 +44,8 @@ import net.sourceforge.plantuml.StringUtils;
public enum DayOfWeek { public enum DayOfWeek {
MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY; MONDAY(Calendar.MONDAY), TUESDAY(Calendar.TUESDAY), WEDNESDAY(Calendar.WEDNESDAY), THURSDAY(Calendar.THURSDAY),
FRIDAY(Calendar.FRIDAY), SATURDAY(Calendar.SATURDAY), SUNDAY(Calendar.SUNDAY);
static final private Calendar gmt = Calendar.getInstance(TimeZone.getTimeZone("GMT")); static final private Calendar gmt = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
static final private SimpleDateFormat dateFormatGmt = new SimpleDateFormat("dd MMM yyyy HH:mm:ss.SSS", Locale.US); static final private SimpleDateFormat dateFormatGmt = new SimpleDateFormat("dd MMM yyyy HH:mm:ss.SSS", Locale.US);
@ -52,6 +53,16 @@ public enum DayOfWeek {
dateFormatGmt.setTimeZone(TimeZone.getTimeZone("GMT")); dateFormatGmt.setTimeZone(TimeZone.getTimeZone("GMT"));
} }
private final int legacy;
private DayOfWeek(int legacy) {
this.legacy = legacy;
}
public int getLegacyJavaValue() {
return legacy;
}
public static synchronized DayOfWeek fromTime(long time) { public static synchronized DayOfWeek fromTime(long time) {
gmt.setTimeInMillis(time); gmt.setTimeInMillis(time);
final int result = gmt.get(Calendar.DAY_OF_WEEK); final int result = gmt.get(Calendar.DAY_OF_WEEK);

View File

@ -0,0 +1,61 @@
/* ========================================================================
* PlantUML : a free UML diagram generator
* ========================================================================
*
* (C) Copyright 2009-2020, Arnaud Roques
*
* Project Info: http://plantuml.com
*
* If you like this project or if you find it useful, you can support us at:
*
* http://plantuml.com/patreon (only 1$ per month!)
* http://plantuml.com/paypal
*
* This file is part of PlantUML.
*
* PlantUML is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* PlantUML distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
* License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
* USA.
*
*
* Original Author: Arnaud Roques
*
*
*/
package net.sourceforge.plantuml.project.time;
public class WeekNumberStrategy {
private final DayOfWeek firstDayOfWeek;
private final int minimalDaysInFirstWeek;
public WeekNumberStrategy(DayOfWeek firstDayOfWeek, int minimalDaysInFirstWeek) {
this.firstDayOfWeek = firstDayOfWeek;
this.minimalDaysInFirstWeek = minimalDaysInFirstWeek;
}
public final int getFirstDayOfWeekAsLegacyInt() {
return firstDayOfWeek.getLegacyJavaValue();
}
public final int getMinimalDaysInFirstWeek() {
return minimalDaysInFirstWeek;
}
public final DayOfWeek getFirstDayOfWeek() {
return firstDayOfWeek;
}
}

View File

@ -40,24 +40,24 @@ import net.sourceforge.plantuml.project.time.DayOfWeek;
public class TimeScaleCompressed implements TimeScale { public class TimeScaleCompressed implements TimeScale {
private final int compress; private final double scale;
private final TimeScale daily; private final TimeScale daily;
public TimeScaleCompressed(Day calendar, int compress) { public TimeScaleCompressed(Day calendar, double scale) {
this.daily = new TimeScaleDaily(calendar, null); this.daily = new TimeScaleDaily(calendar, null);
this.compress = compress; this.scale = scale;
} }
public double getStartingPosition(Day instant) { public double getStartingPosition(Day instant) {
return daily.getStartingPosition(instant) / compress; return daily.getStartingPosition(instant) * scale;
} }
public double getEndingPosition(Day instant) { public double getEndingPosition(Day instant) {
return daily.getEndingPosition(instant) / compress; return daily.getEndingPosition(instant) * scale;
} }
public double getWidth(Day instant) { public double getWidth(Day instant) {
return daily.getWidth(instant) / compress; return daily.getWidth(instant) * scale;
} }
public boolean isBreaking(Day instant) { public boolean isBreaking(Day instant) {

View File

@ -107,6 +107,7 @@ public enum SName {
storage, // storage, //
swimlane, // swimlane, //
task, // task, //
timeline, //
title, // title, //
usecase, // usecase, //
wbsDiagram, // wbsDiagram, //

View File

@ -114,6 +114,16 @@ public class Style {
return new Style(this.signature, result); return new Style(this.signature, result);
} }
public Style eventuallyOverride(PName param, double value) {
return eventuallyOverride(param, "" + value);
}
public Style eventuallyOverride(PName param, String value) {
final EnumMap<PName, Value> result = new EnumMap<PName, Value>(this.map);
result.put(param, new ValueImpl(value, Integer.MAX_VALUE));
return new Style(this.signature, result);
}
public Style eventuallyOverride(Colors colors) { public Style eventuallyOverride(Colors colors) {
Style result = this; Style result = this;
if (colors != null) { if (colors != null) {
@ -169,6 +179,17 @@ public class Style {
return new SymbolContext(backColor, foreColor).withStroke(getStroke()).withDeltaShadow(deltaShadowing); return new SymbolContext(backColor, foreColor).withStroke(getStroke()).withDeltaShadow(deltaShadowing);
} }
public Style eventuallyOverride(UStroke stroke) {
if (stroke == null) {
return this;
}
Style result = this.eventuallyOverride(PName.LineThickness, stroke.getThickness());
final double space = stroke.getDashSpace();
final double visible = stroke.getDashVisible();
result = result.eventuallyOverride(PName.LineStyle, "" + visible + ";" + space);
return result;
}
public UStroke getStroke() { public UStroke getStroke() {
final double thickness = value(PName.LineThickness).asDouble(); final double thickness = value(PName.LineThickness).asDouble();
final String dash = value(PName.LineStyle).asString(); final String dash = value(PName.LineStyle).asString();

View File

@ -55,6 +55,11 @@ public class ValueImpl implements Value {
this.priority = counter.getNextInt(); this.priority = counter.getNextInt();
} }
public ValueImpl(String value, int priority) {
this.value = value;
this.priority = priority;
}
@Override @Override
public String toString() { public String toString() {
return value + " (" + priority + ")"; return value + " (" + priority + ")";

View File

@ -80,7 +80,7 @@ public class Version {
} }
public static int beta() { public static int beta() {
final int beta = 0; final int beta = 3;
return beta; return beta;
} }

View File

@ -73,7 +73,7 @@ RECTANGLE:
backcolor: ffe0e8e8 backcolor: ffe0e8e8
TEXT: TEXT:
text: 19 text: 43
position: [ 21.0000 ; 23.7778 ] position: [ 21.0000 ; 23.7778 ]
orientation: 0 orientation: 0
font: Serif.plain/10 [] font: Serif.plain/10 []
@ -81,7 +81,7 @@ TEXT:
extendedColor: NULL_COLOR extendedColor: NULL_COLOR
TEXT: TEXT:
text: 26 text: 44
position: [ 49.0000 ; 23.7778 ] position: [ 49.0000 ; 23.7778 ]
orientation: 0 orientation: 0
font: Serif.plain/10 [] font: Serif.plain/10 []
@ -89,7 +89,7 @@ TEXT:
extendedColor: NULL_COLOR extendedColor: NULL_COLOR
TEXT: TEXT:
text: 2 text: 45
position: [ 77.0000 ; 23.7778 ] position: [ 77.0000 ; 23.7778 ]
orientation: 0 orientation: 0
font: Serif.plain/10 [] font: Serif.plain/10 []
@ -97,7 +97,7 @@ TEXT:
extendedColor: NULL_COLOR extendedColor: NULL_COLOR
TEXT: TEXT:
text: 9 text: 46
position: [ 105.0000 ; 23.7778 ] position: [ 105.0000 ; 23.7778 ]
orientation: 0 orientation: 0
font: Serif.plain/10 [] font: Serif.plain/10 []
@ -105,7 +105,7 @@ TEXT:
extendedColor: NULL_COLOR extendedColor: NULL_COLOR
TEXT: TEXT:
text: 16 text: 47
position: [ 133.0000 ; 23.7778 ] position: [ 133.0000 ; 23.7778 ]
orientation: 0 orientation: 0
font: Serif.plain/10 [] font: Serif.plain/10 []
@ -113,7 +113,7 @@ TEXT:
extendedColor: NULL_COLOR extendedColor: NULL_COLOR
TEXT: TEXT:
text: 23 text: 48
position: [ 161.0000 ; 23.7778 ] position: [ 161.0000 ; 23.7778 ]
orientation: 0 orientation: 0
font: Serif.plain/10 [] font: Serif.plain/10 []