1
0
mirror of https://github.com/octoleo/plantuml.git synced 2024-11-25 06:17:33 +00:00

Gantt improvement

This commit is contained in:
Arnaud Roques 2022-08-18 18:55:09 +02:00
parent 62e5a00c8d
commit 9da0fd0939
25 changed files with 1007 additions and 236 deletions

View File

@ -42,11 +42,13 @@ import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.Objects; import java.util.Objects;
import java.util.Set;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
@ -74,6 +76,7 @@ import net.sourceforge.plantuml.project.core.Resource;
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.TaskCode; import net.sourceforge.plantuml.project.core.TaskCode;
import net.sourceforge.plantuml.project.core.TaskGroup;
import net.sourceforge.plantuml.project.core.TaskImpl; import net.sourceforge.plantuml.project.core.TaskImpl;
import net.sourceforge.plantuml.project.core.TaskInstant; import net.sourceforge.plantuml.project.core.TaskInstant;
import net.sourceforge.plantuml.project.core.TaskSeparator; import net.sourceforge.plantuml.project.core.TaskSeparator;
@ -81,6 +84,7 @@ import net.sourceforge.plantuml.project.draw.FingerPrint;
import net.sourceforge.plantuml.project.draw.ResourceDraw; import net.sourceforge.plantuml.project.draw.ResourceDraw;
import net.sourceforge.plantuml.project.draw.TaskDraw; import net.sourceforge.plantuml.project.draw.TaskDraw;
import net.sourceforge.plantuml.project.draw.TaskDrawDiamond; import net.sourceforge.plantuml.project.draw.TaskDrawDiamond;
import net.sourceforge.plantuml.project.draw.TaskDrawGroup;
import net.sourceforge.plantuml.project.draw.TaskDrawRegular; import net.sourceforge.plantuml.project.draw.TaskDrawRegular;
import net.sourceforge.plantuml.project.draw.TaskDrawSeparator; import net.sourceforge.plantuml.project.draw.TaskDrawSeparator;
import net.sourceforge.plantuml.project.draw.TimeHeader; import net.sourceforge.plantuml.project.draw.TimeHeader;
@ -296,33 +300,28 @@ public class GanttDiagram extends TitledDiagram implements ToTaskDraw, WithSprit
private TimeHeader getTimeHeader() { private TimeHeader getTimeHeader() {
if (openClose.getStartingDay() == null) if (openClose.getStartingDay() == null)
return new TimeHeaderSimple(printScale, getTimelineStyle(), getClosedStyle(), getFactorScale(), min, max, return new TimeHeaderSimple(thParam(), printScale);
getIHtmlColorSet(), getSkinParam().getThemeStyle(), colorDays());
else if (printScale == PrintScale.DAILY) else if (printScale == PrintScale.DAILY)
return new TimeHeaderDaily(locale, getTimelineStyle(), getClosedStyle(), getFactorScale(), return new TimeHeaderDaily(thParam(), nameDays, printStart, printEnd);
openClose.getStartingDay(), min, max, openClose, colorDays(), colorDaysOfWeek, nameDays, printStart,
printEnd, getIHtmlColorSet(), getSkinParam().getThemeStyle());
else if (printScale == PrintScale.WEEKLY) else if (printScale == PrintScale.WEEKLY)
return new TimeHeaderWeekly(weekNumberStrategy, withCalendarDate, locale, getTimelineStyle(), return new TimeHeaderWeekly(thParam(), weekNumberStrategy, withCalendarDate);
getClosedStyle(), getFactorScale(), openClose.getStartingDay(), min, max, openClose, colorDays(),
colorDaysOfWeek, getIHtmlColorSet(), getSkinParam().getThemeStyle());
else if (printScale == PrintScale.MONTHLY) else if (printScale == PrintScale.MONTHLY)
return new TimeHeaderMonthly(locale, getTimelineStyle(), getClosedStyle(), getFactorScale(), return new TimeHeaderMonthly(thParam());
openClose.getStartingDay(), min, max, openClose, colorDays(), colorDaysOfWeek, getIHtmlColorSet(),
getSkinParam().getThemeStyle());
else if (printScale == PrintScale.QUARTERLY) else if (printScale == PrintScale.QUARTERLY)
return new TimeHeaderQuarterly(locale, getTimelineStyle(), getClosedStyle(), getFactorScale(), return new TimeHeaderQuarterly(thParam());
openClose.getStartingDay(), min, max, openClose, colorDays(), colorDaysOfWeek, getIHtmlColorSet(),
getSkinParam().getThemeStyle());
else if (printScale == PrintScale.YEARLY) else if (printScale == PrintScale.YEARLY)
return new TimeHeaderYearly(locale, getTimelineStyle(), getClosedStyle(), getFactorScale(), return new TimeHeaderYearly(thParam());
openClose.getStartingDay(), min, max, openClose, colorDays(), colorDaysOfWeek, getIHtmlColorSet(),
getSkinParam().getThemeStyle());
else else
throw new IllegalStateException(); throw new IllegalStateException();
} }
private TimeHeaderParameters thParam() {
return new TimeHeaderParameters(colorDays(), getSkinParam().getThemeStyle(), getFactorScale(), min, max,
getIHtmlColorSet(), getTimelineStyle(), getClosedStyle(), locale, openClose, colorDaysOfWeek,
verticalSeparatorBefore);
}
private Map<Day, HColor> colorDays() { private Map<Day, HColor> colorDays() {
colorDaysInternal.putAll(colorDaysToday); colorDaysInternal.putAll(colorDaysToday);
return Collections.unmodifiableMap(colorDaysInternal); return Collections.unmodifiableMap(colorDaysInternal);
@ -425,26 +424,30 @@ 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, final TaskSeparator taskSeparator = (TaskSeparator) task;
task.getStyleBuilder(), getSkinParam().getIHtmlColorSet()); draw = new TaskDrawSeparator(taskSeparator.getName(), timeScale, y, min, max, task.getStyleBuilder(),
getSkinParam().getIHtmlColorSet());
} else if (task instanceof TaskGroup) {
final TaskGroup taskGroup = (TaskGroup) task;
draw = new TaskDrawGroup(timeScale, y, taskGroup.getCode().getSimpleDisplay(), getStart(taskGroup),
getEnd(taskGroup), getSkinParam(), task, this, task.getStyleBuilder());
} else { } else {
final TaskImpl tmp = (TaskImpl) task; final TaskImpl tmp = (TaskImpl) task;
final String disp = hideRessourceName ? tmp.getCode().getSimpleDisplay() : tmp.getPrettyDisplay(); final String disp = hideRessourceName ? tmp.getCode().getSimpleDisplay() : tmp.getPrettyDisplay();
if (tmp.isDiamond()) { if (tmp.isDiamond()) {
draw = new TaskDrawDiamond(timeScale, y, disp, getStart(tmp), getSkinParam(), task, this, draw = new TaskDrawDiamond(timeScale, y, disp, getStart(tmp), getSkinParam(), task, this,
task.getStyleBuilder(), getSkinParam().getIHtmlColorSet()); task.getStyleBuilder());
} 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, disp, getStart(tmp), getEnd(tmp), oddStart, oddEnd, draw = new TaskDrawRegular(timeScale, y, disp, getStart(tmp), getEnd(tmp), oddStart, oddEnd,
getSkinParam(), task, this, getConstraints(task), task.getStyleBuilder(), 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 = y.addAtLeast(draw.getFullHeightTask(stringBounder)); y = y.addAtLeast(draw.getFullHeightTask(stringBounder));
}
draws.put(task, draw); draws.put(task, draw);
} }
origin.compileNow(); origin.compileNow();
@ -504,17 +507,17 @@ public class GanttDiagram extends TitledDiagram implements ToTaskDraw, WithSprit
} }
} }
private Day getStart(final TaskImpl tmp) { private Day getStart(final Task tmp) {
if (printStart == null) { if (printStart == null)
return tmp.getStart(); return tmp.getStart();
}
return Day.max(min, tmp.getStart()); return Day.max(min, tmp.getStart());
} }
private Day getEnd(final TaskImpl tmp) { private Day getEnd(final Task tmp) {
if (printStart == null) { if (printStart == null)
return tmp.getEnd(); return tmp.getEnd();
}
return Day.min(max, tmp.getEnd()); return Day.min(max, tmp.getEnd());
} }
@ -524,7 +527,7 @@ public class GanttDiagram extends TitledDiagram implements ToTaskDraw, WithSprit
} else { } else {
max = null; max = null;
for (Task task : tasks.values()) { for (Task task : tasks.values()) {
if (task instanceof TaskSeparator) if (task instanceof TaskSeparator || task instanceof TaskGroup)
continue; continue;
final Day start = task.getStart(); final Day start = task.getStart();
@ -601,6 +604,9 @@ public class GanttDiagram extends TitledDiagram implements ToTaskDraw, WithSprit
result = new TaskImpl(getSkinParam().getCurrentStyleBuilder(), code, openClose.mutateMe(except), result = new TaskImpl(getSkinParam().getCurrentStyleBuilder(), code, openClose.mutateMe(except),
openClose.getStartingDay()); openClose.getStartingDay());
if (currentGroup != null)
currentGroup.addTask(result);
tasks.put(code, result); tasks.put(code, result);
if (byShortName != null) if (byShortName != null)
byShortName.put(shortName, result); byShortName.put(shortName, result);
@ -626,6 +632,14 @@ public class GanttDiagram extends TitledDiagram implements ToTaskDraw, WithSprit
tasks.put(separator.getCode(), separator); tasks.put(separator.getCode(), separator);
} }
private TaskGroup currentGroup = null;
public void addGroup(String comment) {
TaskGroup group = new TaskGroup(getSkinParam().getCurrentStyleBuilder(), comment);
currentGroup = group;
tasks.put(group.getCode(), group);
}
public void addContraint(GanttConstraint constraint) { public void addContraint(GanttConstraint constraint) {
constraints.add(constraint); constraints.add(constraint);
} }
@ -820,4 +834,10 @@ public class GanttDiagram extends TitledDiagram implements ToTaskDraw, WithSprit
return CommandExecutionResult.ok(); return CommandExecutionResult.ok();
} }
private final Set<Day> verticalSeparatorBefore = new HashSet<>();
public void addVerticalSeparatorBefore(Day day) {
verticalSeparatorBefore.add(day);
}
} }

View File

@ -52,6 +52,8 @@ import net.sourceforge.plantuml.project.command.CommandColorTask;
import net.sourceforge.plantuml.project.command.CommandFootbox; import net.sourceforge.plantuml.project.command.CommandFootbox;
import net.sourceforge.plantuml.project.command.CommandGanttArrow; import net.sourceforge.plantuml.project.command.CommandGanttArrow;
import net.sourceforge.plantuml.project.command.CommandGanttArrow2; import net.sourceforge.plantuml.project.command.CommandGanttArrow2;
import net.sourceforge.plantuml.project.command.CommandGroupEnd;
import net.sourceforge.plantuml.project.command.CommandGroupStart;
import net.sourceforge.plantuml.project.command.CommandHideRessourceFootbox; import net.sourceforge.plantuml.project.command.CommandHideRessourceFootbox;
import net.sourceforge.plantuml.project.command.CommandHideRessourceName; import net.sourceforge.plantuml.project.command.CommandHideRessourceName;
import net.sourceforge.plantuml.project.command.CommandLabelOnColumn; import net.sourceforge.plantuml.project.command.CommandLabelOnColumn;
@ -71,6 +73,7 @@ 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.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.SubjectSeparator;
import net.sourceforge.plantuml.project.lang.SubjectTask; import net.sourceforge.plantuml.project.lang.SubjectTask;
import net.sourceforge.plantuml.project.lang.SubjectToday; import net.sourceforge.plantuml.project.lang.SubjectToday;
import net.sourceforge.plantuml.style.CommandStyleImport; import net.sourceforge.plantuml.style.CommandStyleImport;
@ -80,7 +83,8 @@ 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 SubjectSeparator());
} }
public GanttDiagramFactory(DiagramType type) { public GanttDiagramFactory(DiagramType type) {
@ -96,16 +100,17 @@ public class GanttDiagramFactory extends PSystemCommandFactory {
cmds.add(new CommandStyleMultilinesCSS()); cmds.add(new CommandStyleMultilinesCSS());
cmds.add(new CommandStyleImport()); cmds.add(new CommandStyleImport());
// addCommonCommands(cmds);
cmds.add(new CommandNope()); cmds.add(new CommandNope());
// cmds.add(new CommandComment());
// cmds.add(new CommandMultilinesComment());
cmds.addAll(getLanguageCommands()); cmds.addAll(getLanguageCommands());
cmds.add(new CommandGanttArrow()); cmds.add(new CommandGanttArrow());
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 CommandWeekNumberStrategy());
cmds.add(new CommandGroupStart());
cmds.add(new CommandGroupEnd());
cmds.add(new CommandLanguage()); cmds.add(new CommandLanguage());
cmds.add(new CommandPrintScale()); cmds.add(new CommandPrintScale());
@ -116,12 +121,6 @@ public class GanttDiagramFactory extends PSystemCommandFactory {
cmds.add(new CommandHideRessourceName()); cmds.add(new CommandHideRessourceName());
cmds.add(new CommandHideRessourceFootbox()); cmds.add(new CommandHideRessourceFootbox());
// cmds.add(new CommandScaleWidthAndHeight());
// cmds.add(new CommandScaleWidthOrHeight());
// cmds.add(new CommandScaleMaxWidth());
// cmds.add(new CommandScaleMaxHeight());
// cmds.add(new CommandScaleMaxWidthAndHeight());
return cmds; return cmds;
} }

View File

@ -0,0 +1,133 @@
/* ========================================================================
* PlantUML : a free UML diagram generator
* ========================================================================
*
* (C) Copyright 2009-2023, 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;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import net.sourceforge.plantuml.api.ThemeStyle;
import net.sourceforge.plantuml.project.time.Day;
import net.sourceforge.plantuml.project.time.DayOfWeek;
import net.sourceforge.plantuml.style.Style;
import net.sourceforge.plantuml.ugraphic.color.HColor;
import net.sourceforge.plantuml.ugraphic.color.HColorSet;
public class TimeHeaderParameters {
private final Map<Day, HColor> colorDays;
private final ThemeStyle themeStyle;
private final double scale;
private final Day min;
private final Day max;
private final HColorSet colorSet;
private final Style timelineStyle;
private final Style closedStyle;
private final Locale locale;
private final OpenClose openClose;
private final Map<DayOfWeek, HColor> colorDaysOfWeek;
private final Set<Day> verticalSeparatorBefore;
public TimeHeaderParameters(Map<Day, HColor> colorDays, ThemeStyle themeStyle, double scale, Day min, Day max,
HColorSet colorSet, Style timelineStyle, Style closedStyle, Locale locale, OpenClose openClose,
Map<DayOfWeek, HColor> colorDaysOfWeek, Set<Day> verticalSeparatorBefore) {
this.colorDays = colorDays;
this.themeStyle = themeStyle;
this.scale = scale;
this.min = min;
this.max = max;
this.colorSet = colorSet;
this.timelineStyle = timelineStyle;
this.closedStyle = closedStyle;
this.locale = locale;
this.openClose = openClose;
this.colorDaysOfWeek = colorDaysOfWeek;
this.verticalSeparatorBefore = verticalSeparatorBefore;
}
public HColor getColor(Day wink) {
return colorDays.get(wink);
}
public HColor getColor(DayOfWeek dayOfWeek) {
return colorDaysOfWeek.get(dayOfWeek);
}
public ThemeStyle getThemeStyle() {
return themeStyle;
}
public final double getScale() {
return scale;
}
public final Day getMin() {
return min;
}
public final Day getMax() {
return max;
}
public final HColorSet getColorSet() {
return colorSet;
}
public final Style getTimelineStyle() {
return timelineStyle;
}
public final Style getClosedStyle() {
return closedStyle;
}
public final Locale getLocale() {
return locale;
}
public final LoadPlanable getLoadPlanable() {
return openClose;
}
public Day getStartingDay() {
return openClose.getStartingDay();
}
public final Set<Day> getVerticalSeparatorBefore() {
return verticalSeparatorBefore;
}
}

View File

@ -37,6 +37,7 @@ package net.sourceforge.plantuml.project;
import net.sourceforge.plantuml.project.core.Task; import net.sourceforge.plantuml.project.core.Task;
import net.sourceforge.plantuml.project.draw.TaskDraw; import net.sourceforge.plantuml.project.draw.TaskDraw;
import net.sourceforge.plantuml.ugraphic.color.HColorSet;
public interface ToTaskDraw { public interface ToTaskDraw {
@ -44,4 +45,6 @@ public interface ToTaskDraw {
public LoadPlanable getDefaultPlan(); public LoadPlanable getDefaultPlan();
public HColorSet getIHtmlColorSet();
} }

View File

@ -0,0 +1,68 @@
/* ========================================================================
* PlantUML : a free UML diagram generator
* ========================================================================
*
* (C) Copyright 2009-2023, 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;
public class CommandGroupEnd extends SingleLineCommand2<GanttDiagram> {
public CommandGroupEnd() {
super(getRegexConcat());
}
static IRegex getRegexConcat() {
return RegexConcat.build(CommandGroupEnd.class.getName(), RegexLeaf.start(), //
RegexLeaf.spaceZeroOrMore(), //
new RegexLeaf("end"), //
RegexLeaf.spaceZeroOrMore(), //
new RegexLeaf("group"), //
RegexLeaf.spaceZeroOrMore(), //
RegexLeaf.end());
}
@Override
protected CommandExecutionResult executeArg(GanttDiagram diagram, LineLocation location, RegexResult arg) {
return CommandExecutionResult.ok();
}
}

View File

@ -0,0 +1,71 @@
/* ========================================================================
* PlantUML : a free UML diagram generator
* ========================================================================
*
* (C) Copyright 2009-2023, 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;
public class CommandGroupStart extends SingleLineCommand2<GanttDiagram> {
public CommandGroupStart() {
super(getRegexConcat());
}
static IRegex getRegexConcat() {
return RegexConcat.build(CommandGroupStart.class.getName(), RegexLeaf.start(), //
new RegexLeaf("group"), //
RegexLeaf.spaceOneOrMore(), //
new RegexLeaf("\\["), //
new RegexLeaf("NAME", "([^\\[\\]]+)"), //
new RegexLeaf("\\]"), //
RegexLeaf.spaceZeroOrMore(), //
RegexLeaf.end());
}
@Override
protected CommandExecutionResult executeArg(GanttDiagram diagram, LineLocation location, RegexResult arg) {
final String name = arg.get("NAME", 0);
diagram.addGroup(name);
return CommandExecutionResult.ok();
}
}

View File

@ -0,0 +1,136 @@
/* ========================================================================
* PlantUML : a free UML diagram generator
* ========================================================================
*
* (C) Copyright 2009-2023, 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.core;
import java.util.ArrayList;
import java.util.List;
import net.sourceforge.plantuml.Url;
import net.sourceforge.plantuml.cucadiagram.Display;
import net.sourceforge.plantuml.project.Load;
import net.sourceforge.plantuml.project.lang.CenterBorderColor;
import net.sourceforge.plantuml.project.time.Day;
import net.sourceforge.plantuml.project.time.DayOfWeek;
import net.sourceforge.plantuml.style.StyleBuilder;
public class TaskGroup extends AbstractTask implements Task {
private final List<Task> children = new ArrayList<>();
public TaskGroup(StyleBuilder styleBuilder, String comment) {
super(styleBuilder, new TaskCode(comment));
}
public Day getStart() {
Day min = null;
for (Task child : children)
if (min == null || min.compareTo(child.getStart()) > 0)
min = child.getStart();
if (min != null)
return min;
throw new UnsupportedOperationException();
}
public Day getEnd() {
Day max = null;
for (Task child : children)
if (max == null || max.compareTo(child.getEnd()) < 0)
max = child.getEnd();
if (max != null)
return max;
throw new UnsupportedOperationException();
}
public void setStart(Day start) {
throw new UnsupportedOperationException();
}
public void setEnd(Day end) {
throw new UnsupportedOperationException();
}
public void setColors(CenterBorderColor... colors) {
throw new UnsupportedOperationException();
}
public void addResource(Resource resource, int percentage) {
throw new UnsupportedOperationException();
}
public Load getLoad() {
throw new UnsupportedOperationException();
}
public void setLoad(Load load) {
throw new UnsupportedOperationException();
}
public void setDiamond(boolean diamond) {
throw new UnsupportedOperationException();
}
public boolean isDiamond() {
throw new UnsupportedOperationException();
}
public void setCompletion(int completion) {
throw new UnsupportedOperationException();
}
public void setUrl(Url url) {
throw new UnsupportedOperationException();
}
public void addPause(Day pause) {
throw new UnsupportedOperationException();
}
public void addPause(DayOfWeek pause) {
throw new UnsupportedOperationException();
}
public void setNote(Display note) {
}
public void addTask(Task child) {
children.add(child);
}
}

View File

@ -70,7 +70,6 @@ public abstract class AbstractTaskDraw implements TaskDraw {
protected final String prettyDisplay; protected final String prettyDisplay;
protected final Day start; protected final Day start;
private final StyleBuilder styleBuilder; private final StyleBuilder styleBuilder;
private final HColorSet colorSet;
private final Task task; private final Task task;
private final ToTaskDraw toTaskDraw; private final ToTaskDraw toTaskDraw;
@ -87,9 +86,8 @@ public abstract class AbstractTaskDraw implements TaskDraw {
} }
public AbstractTaskDraw(TimeScale timeScale, Real y, String prettyDisplay, Day start, ISkinParam skinParam, public AbstractTaskDraw(TimeScale timeScale, Real y, String prettyDisplay, Day start, ISkinParam skinParam,
Task task, ToTaskDraw toTaskDraw, StyleBuilder styleBuilder, HColorSet colorSet) { Task task, ToTaskDraw toTaskDraw, StyleBuilder styleBuilder) {
this.y = y; this.y = y;
this.colorSet = colorSet;
this.styleBuilder = styleBuilder; this.styleBuilder = styleBuilder;
this.toTaskDraw = toTaskDraw; this.toTaskDraw = toTaskDraw;
this.start = start; this.start = start;
@ -106,22 +104,22 @@ public abstract class AbstractTaskDraw implements TaskDraw {
final protected HColor getLineColor() { final protected HColor getLineColor() {
final HColor unstarted = getStyleSignatureUnstarted().getMergedStyle(styleBuilder).value(PName.LineColor) final HColor unstarted = getStyleSignatureUnstarted().getMergedStyle(styleBuilder).value(PName.LineColor)
.asColor(getStyleBuilder().getSkinParam().getThemeStyle(), colorSet); .asColor(getStyleBuilder().getSkinParam().getThemeStyle(), getColorSet());
final HColor regular = getStyle().value(PName.LineColor) final HColor regular = getStyle().value(PName.LineColor)
.asColor(getStyleBuilder().getSkinParam().getThemeStyle(), colorSet); .asColor(getStyleBuilder().getSkinParam().getThemeStyle(), getColorSet());
return HColorUtils.unlinear(unstarted, regular, completion); return HColorUtils.unlinear(unstarted, regular, completion);
} }
final protected HColor getBackgroundColor() { final protected HColor getBackgroundColor() {
final HColor unstarted = getStyleSignatureUnstarted().getMergedStyle(styleBuilder).value(PName.BackGroundColor) final HColor unstarted = getStyleSignatureUnstarted().getMergedStyle(styleBuilder).value(PName.BackGroundColor)
.asColor(getStyleBuilder().getSkinParam().getThemeStyle(), colorSet); .asColor(getStyleBuilder().getSkinParam().getThemeStyle(), getColorSet());
final HColor regular = getStyle().value(PName.BackGroundColor) final HColor regular = getStyle().value(PName.BackGroundColor)
.asColor(getStyleBuilder().getSkinParam().getThemeStyle(), colorSet); .asColor(getStyleBuilder().getSkinParam().getThemeStyle(), getColorSet());
return HColorUtils.unlinear(unstarted, regular, completion); return HColorUtils.unlinear(unstarted, regular, completion);
} }
final protected FontConfiguration getFontConfiguration() { final protected FontConfiguration getFontConfiguration() {
return getStyle().getFontConfiguration(styleBuilder.getSkinParam().getThemeStyle(), colorSet); return getStyle().getFontConfiguration(styleBuilder.getSkinParam().getThemeStyle(), getColorSet());
} }
final protected Style getStyle() { final protected Style getStyle() {
@ -184,7 +182,7 @@ public abstract class AbstractTaskDraw implements TaskDraw {
} }
protected final HColorSet getColorSet() { protected final HColorSet getColorSet() {
return colorSet; return toTaskDraw.getIHtmlColorSet();
} }
protected CenterBorderColor getColors() { protected CenterBorderColor getColors() {

View File

@ -59,13 +59,12 @@ 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, Real y, String prettyDisplay, Day start, ISkinParam skinParam, public TaskDrawDiamond(TimeScale timeScale, Real y, String prettyDisplay, Day start, ISkinParam skinParam,
Task task, ToTaskDraw toTaskDraw, StyleBuilder styleBuilder, HColorSet colorSet) { Task task, ToTaskDraw toTaskDraw, StyleBuilder styleBuilder) {
super(timeScale, y, prettyDisplay, start, skinParam, task, toTaskDraw, styleBuilder, colorSet); super(timeScale, y, prettyDisplay, start, skinParam, task, toTaskDraw, styleBuilder);
} }
@Override @Override

View File

@ -0,0 +1,256 @@
/* ========================================================================
* PlantUML : a free UML diagram generator
* ========================================================================
*
* (C) Copyright 2009-2023, 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.draw;
import net.sourceforge.plantuml.ISkinParam;
import net.sourceforge.plantuml.SpriteContainerEmpty;
import net.sourceforge.plantuml.awt.geom.Dimension2D;
import net.sourceforge.plantuml.cucadiagram.Display;
import net.sourceforge.plantuml.graphic.HorizontalAlignment;
import net.sourceforge.plantuml.graphic.StringBounder;
import net.sourceforge.plantuml.graphic.TextBlock;
import net.sourceforge.plantuml.project.LabelStrategy;
import net.sourceforge.plantuml.project.ToTaskDraw;
import net.sourceforge.plantuml.project.core.Task;
import net.sourceforge.plantuml.project.core.TaskAttribute;
import net.sourceforge.plantuml.project.lang.CenterBorderColor;
import net.sourceforge.plantuml.project.time.Day;
import net.sourceforge.plantuml.project.timescale.TimeScale;
import net.sourceforge.plantuml.real.Real;
import net.sourceforge.plantuml.style.ClockwiseTopRightBottomLeft;
import net.sourceforge.plantuml.style.SName;
import net.sourceforge.plantuml.style.Style;
import net.sourceforge.plantuml.style.StyleBuilder;
import net.sourceforge.plantuml.style.StyleSignatureBasic;
import net.sourceforge.plantuml.ugraphic.UGraphic;
import net.sourceforge.plantuml.ugraphic.UPath;
import net.sourceforge.plantuml.ugraphic.URectangle;
import net.sourceforge.plantuml.ugraphic.UShape;
import net.sourceforge.plantuml.ugraphic.UTranslate;
import net.sourceforge.plantuml.ugraphic.color.HColorUtils;
public class TaskDrawGroup extends AbstractTaskDraw {
private final Day end;
private final ISkinParam skinParam;
public TaskDrawGroup(TimeScale timeScale, Real y, String prettyDisplay, Day start, Day end, ISkinParam skinParam,
Task task, ToTaskDraw toTaskDraw, StyleBuilder styleBuilder) {
super(timeScale, y, prettyDisplay, start, skinParam, task, toTaskDraw, styleBuilder);
this.skinParam = skinParam;
this.end = end;
}
@Override
protected double getShapeHeight(StringBounder stringBounder) {
final Style style = getStyle();
final ClockwiseTopRightBottomLeft padding = style.getPadding();
return padding.getTop() + getTitle().calculateDimension(stringBounder).getHeight() + padding.getBottom() + 8;
}
@Override
public void drawTitle(UGraphic ug, LabelStrategy labelStrategy, double colTitles, double colBars) {
final TextBlock title = getTitle();
final StringBounder stringBounder = ug.getStringBounder();
final Dimension2D dim = title.calculateDimension(stringBounder);
final Style style = getStyleSignature().getMergedStyle(getStyleBuilder());
final ClockwiseTopRightBottomLeft margin = style.getMargin();
final ClockwiseTopRightBottomLeft padding = style.getPadding();
ug = ug.apply(UTranslate.dy(margin.getTop() + padding.getTop()));
// if (labelStrategy.titleInFirstColumn()) {
// if (labelStrategy.rightAligned())
// title.drawU(ug.apply(UTranslate.dx(colTitles - dim.getWidth() - margin.getRight())));
// else
// title.drawU(ug.apply(UTranslate.dx(margin.getLeft())));
// return;
// } else if (labelStrategy.titleInLastColumn()) {
// title.drawU(ug.apply(UTranslate.dx(colBars + margin.getLeft())));
// return;
// }
//
final double pos1 = timeScale.getStartingPosition(start) + 6;
final double pos2 = timeScale.getEndingPosition(end) - 6;
final double pos;
if (pos2 - pos1 > dim.getWidth())
pos = pos1 + (pos2 - pos1 - dim.getWidth()) / 2;
else
pos = pos2 + 3;
title.drawU(ug.apply(UTranslate.dx(pos)));
}
@Override
protected TextBlock getTitle() {
return Display.getWithNewlines(prettyDisplay).create(getFontConfiguration(), HorizontalAlignment.LEFT,
new SpriteContainerEmpty());
}
@Override
StyleSignatureBasic getStyleSignature() {
return StyleSignatureBasic.of(SName.root, SName.element, SName.ganttDiagram, SName.task);
}
public void drawU(UGraphic ug) {
final double startPos = timeScale.getStartingPosition(start);
ug = applyColors(ug);
drawShape(ug);
}
@Override
public double getHeightMax(StringBounder stringBounder) {
return getFullHeightTask(stringBounder);
}
public FingerPrint getFingerPrint(StringBounder stringBounder) {
final double h = getFullHeightTask(stringBounder);
final double startPos = timeScale.getStartingPosition(start);
final double endPos = timeScale.getEndingPosition(end);
return new FingerPrint(startPos, getY(stringBounder).getCurrentValue(), endPos - startPos, h);
}
public FingerPrint getFingerPrintNote(StringBounder stringBounder) {
return null;
}
private UGraphic applyColors(UGraphic ug) {
final CenterBorderColor col = this.getColors();
if (col != null && col.isOk())
return col.apply(ug);
return ug.apply(getLineColor()).apply(getBackgroundColor().bg());
}
public double getX1(TaskAttribute taskAttribute) {
final Style style = getStyleSignature().getMergedStyle(getStyleBuilder());
final ClockwiseTopRightBottomLeft margin = style.getMargin();
final double startPos = taskAttribute == TaskAttribute.START ? timeScale.getStartingPosition(start)
: timeScale.getStartingPosition(end) + margin.getLeft();
return startPos;
}
public double getX2(TaskAttribute taskAttribute) {
final Style style = getStyleSignature().getMergedStyle(getStyleBuilder());
final ClockwiseTopRightBottomLeft margin = style.getMargin();
final double endPos = taskAttribute == TaskAttribute.START ? timeScale.getEndingPosition(start)
: timeScale.getEndingPosition(end) - margin.getLeft();
return endPos;
}
private void drawShape(UGraphic ug) {
final Style style = getStyleSignature().getMergedStyle(getStyleBuilder());
final ClockwiseTopRightBottomLeft margin = style.getMargin();
final double startPos = timeScale.getStartingPosition(start) + margin.getLeft();
final double endPos = timeScale.getEndingPosition(end) - margin.getRight();
if (url != null)
ug.startUrl(url);
// ug = ug.apply(UTranslate.dy(margin.getTop() + 7));
ug = ug.apply(UTranslate.dy(getShapeHeight(ug.getStringBounder()) - 10));
ug = ug.apply(HColorUtils.BLACK).apply(HColorUtils.BLACK.bg());
ug.draw(getShape(startPos, endPos));
if (url != null)
ug.closeUrl();
}
private UPath getShape(final double startPos, final double endPos) {
final UPath rect = new UPath();
final double height = 10;
final double thick = 2;
final double y1 = (height - thick) / 2;
final double y2 = height - (height - thick) / 2;
final double dx = 6;
rect.moveTo(startPos, 0);
rect.lineTo(startPos + dx, y1);
rect.lineTo(endPos - dx, y1);
rect.lineTo(endPos, 0);
rect.lineTo(endPos, height);
rect.lineTo(endPos - dx, y2);
rect.lineTo(startPos + dx, y2);
rect.lineTo(startPos, height);
rect.lineTo(startPos, 0);
rect.closePath();
return rect;
}
private UPath getShapeOld2(final double startPos, final double endPos) {
final UPath rect = new UPath();
final double height1 = 9;
final double height2 = 7;
final double dx = 6;
rect.moveTo(startPos, 0);
rect.lineTo(startPos + dx, height2);
rect.lineTo(endPos - dx, height2);
rect.lineTo(endPos, 0);
rect.lineTo(endPos, height1);
rect.lineTo(startPos, height1);
rect.lineTo(startPos, 0);
rect.closePath();
return rect;
}
private UPath getShapeOld(final double startPos, final double endPos) {
final UPath rect = new UPath();
final double height1 = 9;
final double height2 = 2;
final double dx = 6;
rect.moveTo(startPos, 0);
rect.lineTo(endPos, 0);
rect.lineTo(endPos, height1);
rect.lineTo(endPos - dx, height2);
rect.lineTo(startPos + dx, height2);
rect.lineTo(startPos, height1);
rect.lineTo(startPos, 0);
rect.closePath();
return rect;
}
}

View File

@ -73,7 +73,6 @@ import net.sourceforge.plantuml.svek.image.Opale;
import net.sourceforge.plantuml.ugraphic.UGraphic; import net.sourceforge.plantuml.ugraphic.UGraphic;
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;
public class TaskDrawRegular extends AbstractTaskDraw { public class TaskDrawRegular extends AbstractTaskDraw {
@ -86,8 +85,8 @@ public class TaskDrawRegular extends AbstractTaskDraw {
public TaskDrawRegular(TimeScale timeScale, Real y, String prettyDisplay, Day start, Day end, boolean oddStart, public TaskDrawRegular(TimeScale timeScale, Real 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, StyleBuilder styleBuilder, HColorSet colorSet) { Collection<GanttConstraint> constraints, StyleBuilder styleBuilder) {
super(timeScale, y, prettyDisplay, start, skinParam, task, toTaskDraw, styleBuilder, colorSet); super(timeScale, y, prettyDisplay, start, skinParam, task, toTaskDraw, styleBuilder);
this.skinParam = skinParam; this.skinParam = skinParam;
this.constraints = constraints; this.constraints = constraints;
this.end = end; this.end = end;
@ -190,6 +189,7 @@ public class TaskDrawRegular extends AbstractTaskDraw {
} }
@Override
public double getHeightMax(StringBounder stringBounder) { public double getHeightMax(StringBounder stringBounder) {
if (note == null) if (note == null)
return getFullHeightTask(stringBounder); return getFullHeightTask(stringBounder);

View File

@ -51,10 +51,12 @@ import net.sourceforge.plantuml.ugraphic.UFont;
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.URectangle;
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.HColorSet;
import net.sourceforge.plantuml.ugraphic.color.HColorUtils;
public abstract class TimeHeader { public abstract class TimeHeader {
@ -120,9 +122,13 @@ public abstract class TimeHeader {
ug.apply(getBarColor()).apply(UTranslate.dy(y)).draw(hline); ug.apply(getBarColor()).apply(UTranslate.dy(y)).draw(hline);
} }
protected final void drawVbar(UGraphic ug, double x, double y1, double y2) { protected final void drawVbar(UGraphic ug, double x, double y1, double y2, boolean bold) {
final ULine vbar = ULine.vline(y2 - y1); final ULine vbar = ULine.vline(y2 - y1);
ug.apply(getBarColor()).apply(new UTranslate(x, y1)).draw(vbar); if (bold)
ug = goBold(ug);
else
ug = ug.apply(getBarColor());
ug.apply(new UTranslate(x, y1)).draw(vbar);
} }
final protected FontConfiguration getFontConfiguration(int size, boolean bold, HColor color) { final protected FontConfiguration getFontConfiguration(int size, boolean bold, HColor color) {
@ -172,4 +178,10 @@ public abstract class TimeHeader {
ug.draw(new URectangle(x2 - x1, height)); ug.draw(new URectangle(x2 - x1, height));
} }
protected final UGraphic goBold(UGraphic ug) {
return ug.apply(HColorUtils.BLACK).apply(new UStroke(2));
}
} }

View File

@ -36,33 +36,29 @@
package net.sourceforge.plantuml.project.draw; package net.sourceforge.plantuml.project.draw;
import java.util.Locale; import java.util.Locale;
import java.util.Map;
import net.sourceforge.plantuml.api.ThemeStyle; import net.sourceforge.plantuml.project.TimeHeaderParameters;
import net.sourceforge.plantuml.project.LoadPlanable;
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.timescale.TimeScale; import net.sourceforge.plantuml.project.timescale.TimeScale;
import net.sourceforge.plantuml.style.Style;
import net.sourceforge.plantuml.ugraphic.UGraphic; import net.sourceforge.plantuml.ugraphic.UGraphic;
import net.sourceforge.plantuml.ugraphic.color.HColor; import net.sourceforge.plantuml.ugraphic.color.HColor;
import net.sourceforge.plantuml.ugraphic.color.HColorSet;
public abstract class TimeHeaderCalendar extends TimeHeader { public abstract class TimeHeaderCalendar extends TimeHeader {
protected final LoadPlanable defaultPlan; private final TimeHeaderParameters thParam;
protected final Map<Day, HColor> colorDays;
protected final Map<DayOfWeek, HColor> colorDaysOfWeek;
protected final Locale locale;
public TimeHeaderCalendar(Locale locale, Style timelineStyle, Style closedStyle, Day calendar, Day min, Day max, public TimeHeaderCalendar(TimeHeaderParameters thParam, TimeScale timeScale) {
LoadPlanable defaultPlan, Map<Day, HColor> colorDays, Map<DayOfWeek, HColor> colorDaysOfWeek, super(thParam.getTimelineStyle(), thParam.getClosedStyle(), thParam.getMin(), thParam.getMax(), timeScale,
TimeScale timeScale, HColorSet colorSet, ThemeStyle themeStyle) { thParam.getColorSet(), thParam.getThemeStyle());
super(timelineStyle, closedStyle, min, max, timeScale, colorSet, themeStyle); this.thParam = thParam;
this.locale = locale; }
this.defaultPlan = defaultPlan;
this.colorDays = colorDays; protected final Locale locale() {
this.colorDaysOfWeek = colorDaysOfWeek; return thParam.getLocale();
}
protected final int getLoadAt(Day instant) {
return thParam.getLoadPlanable().getLoadAt(instant);
} }
// Duplicate in TimeHeaderSimple // Duplicate in TimeHeaderSimple
@ -90,15 +86,15 @@ public abstract class TimeHeaderCalendar extends TimeHeader {
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);
final double x2 = getTimeScale().getEndingPosition(wink); final double x2 = getTimeScale().getEndingPosition(wink);
HColor back = colorDays.get(wink); HColor back = thParam.getColor(wink);
// Day of week should be stronger than period of time (back color). // Day of week should be stronger than period of time (back color).
final HColor backDoW = colorDaysOfWeek.get(wink.getDayOfWeek()); final HColor backDoW = thParam.getColor(wink.getDayOfWeek());
if (backDoW != null) { if (backDoW != null)
back = backDoW; back = backDoW;
}
if (back == null && defaultPlan.getLoadAt(wink) == 0) { if (back == null && getLoadAt(wink) == 0)
back = closedBackgroundColor(); back = closedBackgroundColor();
}
if (back == null) { if (back == null) {
if (pending != null) if (pending != null)
pending.draw(ug, height); pending.draw(ug, height);
@ -108,11 +104,11 @@ public abstract class TimeHeaderCalendar extends TimeHeader {
pending.draw(ug, height); pending.draw(ug, height);
pending = null; pending = null;
} }
if (pending == null) { if (pending == null)
pending = new Pending(back, x1, x2); pending = new Pending(back, x1, x2);
} else { else
pending.x2 = x2; pending.x2 = x2;
}
} }
} }
} }

View File

@ -35,21 +35,17 @@
*/ */
package net.sourceforge.plantuml.project.draw; package net.sourceforge.plantuml.project.draw;
import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.Set;
import net.sourceforge.plantuml.api.ThemeStyle;
import net.sourceforge.plantuml.graphic.TextBlock; import net.sourceforge.plantuml.graphic.TextBlock;
import net.sourceforge.plantuml.project.LoadPlanable; import net.sourceforge.plantuml.project.TimeHeaderParameters;
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.MonthYear; import net.sourceforge.plantuml.project.time.MonthYear;
import net.sourceforge.plantuml.project.timescale.TimeScaleDaily; import net.sourceforge.plantuml.project.timescale.TimeScaleDaily;
import net.sourceforge.plantuml.style.Style;
import net.sourceforge.plantuml.ugraphic.UGraphic; import net.sourceforge.plantuml.ugraphic.UGraphic;
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;
public class TimeHeaderDaily extends TimeHeaderCalendar { public class TimeHeaderDaily extends TimeHeaderCalendar {
@ -63,13 +59,16 @@ public class TimeHeaderDaily extends TimeHeaderCalendar {
} }
private final Map<Day, String> nameDays; private final Map<Day, String> nameDays;
private final Set<Day> verticalSeparators;
public TimeHeaderDaily(Locale locale, Style timelineStyle, Style closedStyle, double scale, Day calendar, Day min, public TimeHeaderDaily(TimeHeaderParameters thParam, Map<Day, String> nameDays, Day printStart, Day printEnd) {
Day max, LoadPlanable defaultPlan, Map<Day, HColor> colorDays, Map<DayOfWeek, HColor> colorDaysOfWeek, super(thParam, new TimeScaleDaily(thParam.getStartingDay(), thParam.getScale(), printStart));
Map<Day, String> nameDays, Day printStart, Day printEnd, HColorSet colorSet, ThemeStyle themeStyle) {
super(locale, timelineStyle, closedStyle, calendar, min, max, defaultPlan, colorDays, colorDaysOfWeek,
new TimeScaleDaily(scale, calendar, printStart), colorSet, themeStyle);
this.nameDays = nameDays; this.nameDays = nameDays;
this.verticalSeparators = thParam.getVerticalSeparatorBefore();
}
private boolean isBold(Day wink) {
return verticalSeparators.contains(wink);
} }
@Override @Override
@ -79,37 +78,19 @@ public class TimeHeaderDaily extends TimeHeaderCalendar {
drawTextDayOfMonth(ug.apply(UTranslate.dy(Y_POS_ROW28()))); drawTextDayOfMonth(ug.apply(UTranslate.dy(Y_POS_ROW28())));
drawMonths(ug); drawMonths(ug);
printSmallVbars(ug, totalHeightWithoutFooter); printSmallVbars(ug, totalHeightWithoutFooter);
// drawVBars(ug, totalHeightWithoutFooter);
// drawVbar(ug, getTimeScale().getStartingPosition(max.increment()), 0,
// totalHeightWithoutFooter + getTimeFooterHeight());
printNamedDays(ug); printNamedDays(ug);
drawHline(ug, getFullHeaderHeight()); drawHline(ug, getFullHeaderHeight());
drawHline(ug, totalHeightWithoutFooter); drawHline(ug, totalHeightWithoutFooter);
// drawHline(ug, 0);
// drawHline(ug, getFullHeaderHeight());
} }
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())
drawVbar(ug, getTimeScale().getStartingPosition(wink), getFullHeaderHeight(), totalHeightWithoutFooter); drawVbar(ug, getTimeScale().getStartingPosition(wink), getFullHeaderHeight(), totalHeightWithoutFooter,
} isBold(wink));
drawVbar(ug, getTimeScale().getEndingPosition(max), getFullHeaderHeight(), totalHeightWithoutFooter);
}
private void drawVBars(UGraphic ug, double totalHeightWithoutFooter) { drawVbar(ug, getTimeScale().getEndingPosition(max), getFullHeaderHeight(), totalHeightWithoutFooter, false);
MonthYear last = null;
for (Day wink = min; wink.compareTo(max) <= 0; wink = wink.increment()) {
double startingY = getFullHeaderHeight();
double len = totalHeightWithoutFooter;
if (wink.monthYear().equals(last) == false) {
startingY = 0;
last = wink.monthYear();
len += 24 + 13;
}
drawVbar(ug, getTimeScale().getStartingPosition(wink), startingY, len);
}
} }
@Override @Override
@ -117,8 +98,6 @@ public class TimeHeaderDaily extends TimeHeaderCalendar {
drawTextDayOfMonth(ug.apply(UTranslate.dy(12))); drawTextDayOfMonth(ug.apply(UTranslate.dy(12)));
drawTextsDayOfWeek(ug); drawTextsDayOfWeek(ug);
drawMonths(ug.apply(UTranslate.dy(24))); drawMonths(ug.apply(UTranslate.dy(24)));
// drawHline(ug, 0);
// drawHline(ug, getTimeFooterHeight());
} }
private void drawTextsDayOfWeek(UGraphic ug) { private void drawTextsDayOfWeek(UGraphic ug) {
@ -126,7 +105,7 @@ public class TimeHeaderDaily extends TimeHeaderCalendar {
final double x1 = getTimeScale().getStartingPosition(wink); final double x1 = getTimeScale().getStartingPosition(wink);
final double x2 = getTimeScale().getEndingPosition(wink); final double x2 = getTimeScale().getEndingPosition(wink);
final HColor textColor = getTextBackColor(wink); final HColor textColor = getTextBackColor(wink);
printCentered(ug, getTextBlock(wink.getDayOfWeek().shortName(locale), 10, false, textColor), x1, x2); printCentered(ug, getTextBlock(wink.getDayOfWeek().shortName(locale()), 10, false, textColor), x1, x2);
} }
} }
@ -140,9 +119,9 @@ public class TimeHeaderDaily extends TimeHeaderCalendar {
} }
private HColor getTextBackColor(Day wink) { private HColor getTextBackColor(Day wink) {
if (defaultPlan.getLoadAt(wink) <= 0) { if (getLoadAt(wink) <= 0)
return closedFontColor(); return closedFontColor();
}
return openFontColor(); return openFontColor();
} }
@ -152,23 +131,23 @@ public class TimeHeaderDaily 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 (wink.monthYear().equals(last) == false) { if (wink.monthYear().equals(last) == false) {
if (last != null) { if (last != null)
printMonth(ug, last, lastChangeMonth, x1); printMonth(ug, last, lastChangeMonth, x1);
}
lastChangeMonth = x1; lastChangeMonth = x1;
last = wink.monthYear(); last = wink.monthYear();
} }
} }
final double x1 = getTimeScale().getStartingPosition(max.increment()); final double x1 = getTimeScale().getStartingPosition(max.increment());
if (x1 > lastChangeMonth) { if (x1 > lastChangeMonth)
printMonth(ug, last, lastChangeMonth, x1); printMonth(ug, last, lastChangeMonth, x1);
}
} }
private void printMonth(UGraphic ug, MonthYear monthYear, double start, double end) { private void printMonth(UGraphic ug, MonthYear monthYear, double start, double end) {
final TextBlock tiny = getTextBlock(monthYear.shortName(locale), 12, true, openFontColor()); final TextBlock tiny = getTextBlock(monthYear.shortName(locale()), 12, true, openFontColor());
final TextBlock small = getTextBlock(monthYear.longName(locale), 12, true, openFontColor()); final TextBlock small = getTextBlock(monthYear.longName(locale()), 12, true, openFontColor());
final TextBlock big = getTextBlock(monthYear.longNameYYYY(locale), 12, true, openFontColor()); final TextBlock big = getTextBlock(monthYear.longNameYYYY(locale()), 12, true, openFontColor());
printCentered(ug, false, start, end, tiny, small, big); printCentered(ug, false, start, end, tiny, small, big);
} }
@ -197,9 +176,9 @@ public class TimeHeaderDaily extends TimeHeaderCalendar {
} }
private double getHeaderNameDayHeight() { private double getHeaderNameDayHeight() {
if (nameDays.size() > 0) { if (nameDays.size() > 0)
return 16; return 16;
}
return 0; return 0;
} }

View File

@ -35,21 +35,13 @@
*/ */
package net.sourceforge.plantuml.project.draw; package net.sourceforge.plantuml.project.draw;
import java.util.Locale;
import java.util.Map;
import net.sourceforge.plantuml.api.ThemeStyle;
import net.sourceforge.plantuml.graphic.TextBlock; import net.sourceforge.plantuml.graphic.TextBlock;
import net.sourceforge.plantuml.project.LoadPlanable; import net.sourceforge.plantuml.project.TimeHeaderParameters;
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.MonthYear; import net.sourceforge.plantuml.project.time.MonthYear;
import net.sourceforge.plantuml.project.timescale.TimeScaleCompressed; import net.sourceforge.plantuml.project.timescale.TimeScaleCompressed;
import net.sourceforge.plantuml.style.Style;
import net.sourceforge.plantuml.ugraphic.UGraphic; import net.sourceforge.plantuml.ugraphic.UGraphic;
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 TimeHeaderMonthly extends TimeHeaderCalendar { public class TimeHeaderMonthly extends TimeHeaderCalendar {
@ -61,11 +53,8 @@ public class TimeHeaderMonthly extends TimeHeaderCalendar {
return 16 + 13 - 1; return 16 + 13 - 1;
} }
public TimeHeaderMonthly(Locale locale, Style timelineStyle, Style closedStyle, double scale, Day calendar, Day min, public TimeHeaderMonthly(TimeHeaderParameters thParam) {
Day max, LoadPlanable defaultPlan, Map<Day, HColor> colorDays, Map<DayOfWeek, HColor> colorDaysOfWeek, super(thParam, new TimeScaleCompressed(thParam.getStartingDay(), thParam.getScale()));
HColorSet colorSet, ThemeStyle themeStyle) {
super(locale, timelineStyle, closedStyle, calendar, min, max, defaultPlan, colorDays, colorDaysOfWeek,
new TimeScaleCompressed(calendar, scale), colorSet, themeStyle);
} }
@Override @Override
@ -94,7 +83,7 @@ public class TimeHeaderMonthly 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, 15, false);
if (last != null) { if (last != null) {
printYear(ug, last, lastChange, x1); printYear(ug, last, lastChange, x1);
} }
@ -106,7 +95,7 @@ public class TimeHeaderMonthly 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, 15, false);
} }
private void drawMonths(UGraphic ug) { private void drawMonths(UGraphic ug) {
@ -115,7 +104,7 @@ public class TimeHeaderMonthly 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 (wink.monthYear().equals(last) == false) { if (wink.monthYear().equals(last) == false) {
drawVbar(ug, x1, 0, 12); drawVbar(ug, x1, 0, 12, false);
if (last != null) { if (last != null) {
printMonth(ug, last, lastChange, x1); printMonth(ug, last, lastChange, x1);
} }
@ -127,7 +116,7 @@ public class TimeHeaderMonthly extends TimeHeaderCalendar {
if (x1 > lastChange) { if (x1 > lastChange) {
printMonth(ug, last, lastChange, x1); printMonth(ug, last, lastChange, x1);
} }
drawVbar(ug, getTimeScale().getEndingPosition(max), 0, 12); drawVbar(ug, getTimeScale().getEndingPosition(max), 0, 12, false);
} }
private void printYear(UGraphic ug, MonthYear monthYear, double start, double end) { private void printYear(UGraphic ug, MonthYear monthYear, double start, double end) {
@ -136,8 +125,8 @@ public class TimeHeaderMonthly 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(locale), 10, false, openFontColor()); final TextBlock small = getTextBlock(monthYear.shortName(locale()), 10, false, openFontColor());
final TextBlock big = getTextBlock(monthYear.longName(locale), 10, false, openFontColor()); final TextBlock big = getTextBlock(monthYear.longName(locale()), 10, false, openFontColor());
printCentered(ug, false, start, end, small, big); printCentered(ug, false, start, end, small, big);
} }

View File

@ -35,21 +35,13 @@
*/ */
package net.sourceforge.plantuml.project.draw; package net.sourceforge.plantuml.project.draw;
import java.util.Locale;
import java.util.Map;
import net.sourceforge.plantuml.api.ThemeStyle;
import net.sourceforge.plantuml.graphic.TextBlock; import net.sourceforge.plantuml.graphic.TextBlock;
import net.sourceforge.plantuml.project.LoadPlanable; import net.sourceforge.plantuml.project.TimeHeaderParameters;
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.MonthYear; import net.sourceforge.plantuml.project.time.MonthYear;
import net.sourceforge.plantuml.project.timescale.TimeScaleCompressed; import net.sourceforge.plantuml.project.timescale.TimeScaleCompressed;
import net.sourceforge.plantuml.style.Style;
import net.sourceforge.plantuml.ugraphic.UGraphic; import net.sourceforge.plantuml.ugraphic.UGraphic;
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 TimeHeaderQuarterly extends TimeHeaderCalendar { public class TimeHeaderQuarterly extends TimeHeaderCalendar {
@ -61,11 +53,8 @@ public class TimeHeaderQuarterly extends TimeHeaderCalendar {
return 16 + 13 - 1; return 16 + 13 - 1;
} }
public TimeHeaderQuarterly(Locale locale, Style timelineStyle, Style closedStyle, double scale, Day calendar, Day min, Day max, public TimeHeaderQuarterly(TimeHeaderParameters thParam) {
LoadPlanable defaultPlan, Map<Day, HColor> colorDays, Map<DayOfWeek, HColor> colorDaysOfWeek, super(thParam, new TimeScaleCompressed(thParam.getStartingDay(), thParam.getScale()));
HColorSet colorSet, ThemeStyle themeStyle) {
super(locale, timelineStyle, closedStyle, calendar, min, max, defaultPlan, colorDays, colorDaysOfWeek,
new TimeScaleCompressed(calendar, scale), colorSet, themeStyle);
} }
@Override @Override
@ -94,7 +83,7 @@ public class TimeHeaderQuarterly 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, 15, false);
if (last != null) { if (last != null) {
printYear(ug, last, lastChange, x1); printYear(ug, last, lastChange, x1);
} }
@ -106,7 +95,7 @@ public class TimeHeaderQuarterly 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, 15, false);
} }
private void drawQuarters(UGraphic ug) { private void drawQuarters(UGraphic ug) {
@ -115,7 +104,7 @@ public class TimeHeaderQuarterly 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 (quarter(wink).equals(last) == false) { if (quarter(wink).equals(last) == false) {
drawVbar(ug, x1, 0, 12); drawVbar(ug, x1, 0, 12, false);
if (last != null) { if (last != null) {
printQuarter(ug, last, lastChange, x1); printQuarter(ug, last, lastChange, x1);
} }
@ -127,7 +116,7 @@ public class TimeHeaderQuarterly extends TimeHeaderCalendar {
if (x1 > lastChange) { if (x1 > lastChange) {
printQuarter(ug, last, lastChange, x1); printQuarter(ug, last, lastChange, x1);
} }
drawVbar(ug, getTimeScale().getEndingPosition(max), 0, 12); drawVbar(ug, getTimeScale().getEndingPosition(max), 0, 12, false);
} }
private String quarter(Day day) { private String quarter(Day day) {

View File

@ -35,28 +35,27 @@
*/ */
package net.sourceforge.plantuml.project.draw; package net.sourceforge.plantuml.project.draw;
import java.util.Map; import java.util.Set;
import net.sourceforge.plantuml.SpriteContainerEmpty; import net.sourceforge.plantuml.SpriteContainerEmpty;
import net.sourceforge.plantuml.api.ThemeStyle;
import net.sourceforge.plantuml.cucadiagram.Display; import net.sourceforge.plantuml.cucadiagram.Display;
import net.sourceforge.plantuml.graphic.HorizontalAlignment; import net.sourceforge.plantuml.graphic.HorizontalAlignment;
import net.sourceforge.plantuml.graphic.TextBlock; import net.sourceforge.plantuml.graphic.TextBlock;
import net.sourceforge.plantuml.project.TimeHeaderParameters;
import net.sourceforge.plantuml.project.core.PrintScale; 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.timescale.TimeScale; import net.sourceforge.plantuml.project.timescale.TimeScale;
import net.sourceforge.plantuml.project.timescale.TimeScaleWink; import net.sourceforge.plantuml.project.timescale.TimeScaleWink;
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.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;
public class TimeHeaderSimple extends TimeHeader { public class TimeHeaderSimple extends TimeHeader {
private final Map<Day, HColor> colorDays; private final TimeHeaderParameters colorDays;
private final PrintScale printScale; private final PrintScale printScale;
private final Set<Day> verticalSeparators;
@Override @Override
public double getFullHeaderHeight() { public double getFullHeaderHeight() {
@ -75,11 +74,26 @@ public class TimeHeaderSimple extends TimeHeader {
return 0; return 0;
} }
public TimeHeaderSimple(PrintScale printScale, Style timelineStyle, Style closedStyle, double scale, Day min, public TimeHeaderSimple(TimeHeaderParameters thParam, PrintScale printScale) {
Day max, HColorSet colorSet, ThemeStyle themeStyle, Map<Day, HColor> colorDays) { super(thParam.getTimelineStyle(), thParam.getClosedStyle(), thParam.getMin(), thParam.getMax(),
super(timelineStyle, closedStyle, min, max, new TimeScaleWink(scale, printScale), colorSet, themeStyle); new TimeScaleWink(thParam.getScale(), printScale), thParam.getColorSet(), thParam.getThemeStyle());
this.colorDays = colorDays; this.colorDays = thParam;
this.printScale = printScale; this.printScale = printScale;
this.verticalSeparators = thParam.getVerticalSeparatorBefore();
}
private boolean isBold(Day wink) {
return verticalSeparators.contains(wink);
}
private void drawSeparatorsDay(UGraphic ug, TimeScale timeScale, double totalHeightWithoutFooter) {
final ULine vbar = ULine.vline(totalHeightWithoutFooter - getFullHeaderHeight() + 2);
ug = goBold(ug).apply(UTranslate.dy(getFullHeaderHeight() - 1));
for (Day i = min; i.compareTo(max.increment()) <= 0; i = i.increment(printScale))
if (isBold(i)) {
final double x1 = timeScale.getStartingPosition(i);
ug.apply(UTranslate.dx(x1)).draw(vbar);
}
} }
private void drawSmallVlinesDay(UGraphic ug, TimeScale timeScale, double totalHeightWithoutFooter) { private void drawSmallVlinesDay(UGraphic ug, TimeScale timeScale, double totalHeightWithoutFooter) {
@ -119,7 +133,8 @@ public class TimeHeaderSimple extends TimeHeader {
drawTextsBackground(ug.apply(UTranslate.dy(-3)), totalHeightWithoutFooter + 6); drawTextsBackground(ug.apply(UTranslate.dy(-3)), totalHeightWithoutFooter + 6);
final double xmin = getTimeScale().getStartingPosition(min); final double xmin = getTimeScale().getStartingPosition(min);
final double xmax = getTimeScale().getEndingPosition(max); final double xmax = getTimeScale().getEndingPosition(max);
drawSmallVlinesDay(ug, getTimeScale(), totalHeightWithoutFooter); drawSmallVlinesDay(ug, getTimeScale(), totalHeightWithoutFooter + 2);
drawSeparatorsDay(ug, getTimeScale(), totalHeightWithoutFooter);
drawSimpleDayCounter(ug, getTimeScale()); drawSimpleDayCounter(ug, getTimeScale());
ug.apply(getBarColor()).draw(ULine.hline(xmax - xmin)); ug.apply(getBarColor()).draw(ULine.hline(xmax - xmin));
ug.apply(getBarColor()).apply(UTranslate.dy(getFullHeaderHeight() - 3)).draw(ULine.hline(xmax - xmin)); ug.apply(getBarColor()).apply(UTranslate.dy(getFullHeaderHeight() - 3)).draw(ULine.hline(xmax - xmin));
@ -130,8 +145,8 @@ public class TimeHeaderSimple extends TimeHeader {
public void drawTimeFooter(UGraphic ug) { public void drawTimeFooter(UGraphic ug) {
final double xmin = getTimeScale().getStartingPosition(min); final double xmin = getTimeScale().getStartingPosition(min);
final double xmax = getTimeScale().getEndingPosition(max); final double xmax = getTimeScale().getEndingPosition(max);
drawSmallVlinesDay(ug, getTimeScale(), getTimeFooterHeight());
ug = ug.apply(UTranslate.dy(3)); ug = ug.apply(UTranslate.dy(3));
drawSmallVlinesDay(ug, getTimeScale(), getTimeFooterHeight() - 3);
drawSimpleDayCounter(ug, getTimeScale()); drawSimpleDayCounter(ug, getTimeScale());
ug.apply(getBarColor()).draw(ULine.hline(xmax - xmin)); ug.apply(getBarColor()).draw(ULine.hline(xmax - xmin));
} }
@ -161,7 +176,7 @@ public class TimeHeaderSimple extends TimeHeader {
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);
final double x2 = getTimeScale().getEndingPosition(wink); final double x2 = getTimeScale().getEndingPosition(wink);
HColor back = colorDays.get(wink); HColor back = colorDays.getColor(wink);
// // Day of week should be stronger than period of time (back color). // // Day of week should be stronger than period of time (back color).
// final HColor backDoW = colorDaysOfWeek.get(wink.getDayOfWeek()); // final HColor backDoW = colorDaysOfWeek.get(wink.getDayOfWeek());
// if (backDoW != null) { // if (backDoW != null) {

View File

@ -35,22 +35,14 @@
*/ */
package net.sourceforge.plantuml.project.draw; package net.sourceforge.plantuml.project.draw;
import java.util.Locale;
import java.util.Map;
import net.sourceforge.plantuml.api.ThemeStyle;
import net.sourceforge.plantuml.graphic.TextBlock; import net.sourceforge.plantuml.graphic.TextBlock;
import net.sourceforge.plantuml.project.LoadPlanable; import net.sourceforge.plantuml.project.TimeHeaderParameters;
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.MonthYear; import net.sourceforge.plantuml.project.time.MonthYear;
import net.sourceforge.plantuml.project.time.WeekNumberStrategy; 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.style.Style;
import net.sourceforge.plantuml.ugraphic.UGraphic; import net.sourceforge.plantuml.ugraphic.UGraphic;
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 TimeHeaderWeekly extends TimeHeaderCalendar { public class TimeHeaderWeekly extends TimeHeaderCalendar {
@ -65,12 +57,9 @@ public class TimeHeaderWeekly extends TimeHeaderCalendar {
return 16; return 16;
} }
public TimeHeaderWeekly(WeekNumberStrategy weekNumberStrategy, boolean withCalendarDate, Locale locale, Style timelineStyle, public TimeHeaderWeekly(TimeHeaderParameters thParam, WeekNumberStrategy weekNumberStrategy,
Style closedStyle, double scale, Day calendar, Day min, Day max, LoadPlanable defaultPlan, boolean withCalendarDate) {
Map<Day, HColor> colorDays, Map<DayOfWeek, HColor> colorDaysOfWeek, HColorSet colorSet, super(thParam, new TimeScaleCompressed(thParam.getStartingDay(), thParam.getScale()));
ThemeStyle themeStyle) {
super(locale, timelineStyle, closedStyle, calendar, min, max, defaultPlan, colorDays, colorDaysOfWeek,
new TimeScaleCompressed(calendar, scale), colorSet, themeStyle);
this.weekNumberStrategy = weekNumberStrategy; this.weekNumberStrategy = weekNumberStrategy;
this.withCalendarDate = withCalendarDate; this.withCalendarDate = withCalendarDate;
} }
@ -103,7 +92,7 @@ public class TimeHeaderWeekly 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 (wink.monthYear().equals(last) == false) { if (wink.monthYear().equals(last) == false) {
drawVbar(ug, x1, 0, Y_POS_ROW16()); drawVbar(ug, x1, 0, Y_POS_ROW16(), false);
if (last != null) { if (last != null) {
printMonth(ug, last, lastChangeMonth, x1); printMonth(ug, last, lastChangeMonth, x1);
} }
@ -111,7 +100,7 @@ public class TimeHeaderWeekly extends TimeHeaderCalendar {
last = wink.monthYear(); last = wink.monthYear();
} }
} }
drawVbar(ug, getTimeScale().getEndingPosition(max), 0, Y_POS_ROW16()); drawVbar(ug, getTimeScale().getEndingPosition(max), 0, Y_POS_ROW16(), false);
final double x1 = getTimeScale().getStartingPosition(max.increment()); final double x1 = getTimeScale().getStartingPosition(max.increment());
if (x1 > lastChangeMonth) { if (x1 > lastChangeMonth) {
printMonth(ug, last, lastChangeMonth, x1); printMonth(ug, last, lastChangeMonth, x1);
@ -121,10 +110,10 @@ 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() == weekNumberStrategy.getFirstDayOfWeek()) { if (wink.getDayOfWeek() == weekNumberStrategy.getFirstDayOfWeek()) {
drawVbar(ug, getTimeScale().getStartingPosition(wink), Y_POS_ROW16(), totalHeightWithoutFooter); drawVbar(ug, getTimeScale().getStartingPosition(wink), Y_POS_ROW16(), totalHeightWithoutFooter, false);
} }
} }
drawVbar(ug, getTimeScale().getEndingPosition(max), Y_POS_ROW16(), totalHeightWithoutFooter); drawVbar(ug, getTimeScale().getEndingPosition(max), Y_POS_ROW16(), totalHeightWithoutFooter, false);
} }
private void printDaysOfMonth(final UGraphic ug) { private void printDaysOfMonth(final UGraphic ug) {
@ -143,8 +132,8 @@ 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(locale), 12, true, openFontColor()); final TextBlock small = getTextBlock(monthYear.shortName(locale()), 12, true, openFontColor());
final TextBlock big = getTextBlock(monthYear.shortNameYYYY(locale), 12, true, openFontColor()); final TextBlock big = getTextBlock(monthYear.shortNameYYYY(locale()), 12, true, openFontColor());
printCentered(ug, false, start, end, small, big); printCentered(ug, false, start, end, small, big);
} }

View File

@ -35,21 +35,13 @@
*/ */
package net.sourceforge.plantuml.project.draw; package net.sourceforge.plantuml.project.draw;
import java.util.Locale;
import java.util.Map;
import net.sourceforge.plantuml.api.ThemeStyle;
import net.sourceforge.plantuml.graphic.TextBlock; import net.sourceforge.plantuml.graphic.TextBlock;
import net.sourceforge.plantuml.project.LoadPlanable; import net.sourceforge.plantuml.project.TimeHeaderParameters;
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.MonthYear; import net.sourceforge.plantuml.project.time.MonthYear;
import net.sourceforge.plantuml.project.timescale.TimeScaleCompressed; import net.sourceforge.plantuml.project.timescale.TimeScaleCompressed;
import net.sourceforge.plantuml.style.Style;
import net.sourceforge.plantuml.ugraphic.UGraphic; import net.sourceforge.plantuml.ugraphic.UGraphic;
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 TimeHeaderYearly extends TimeHeaderCalendar { public class TimeHeaderYearly extends TimeHeaderCalendar {
@ -61,11 +53,8 @@ public class TimeHeaderYearly extends TimeHeaderCalendar {
return 20 - 1; return 20 - 1;
} }
public TimeHeaderYearly(Locale locale, Style timelineStyle, Style closedStyle, double scale, Day calendar, Day min, Day max, public TimeHeaderYearly(TimeHeaderParameters thParam) {
LoadPlanable defaultPlan, Map<Day, HColor> colorDays, Map<DayOfWeek, HColor> colorDaysOfWeek, super(thParam, new TimeScaleCompressed(thParam.getStartingDay(), thParam.getScale()));
HColorSet colorSet, ThemeStyle themeStyle) {
super(locale, timelineStyle, closedStyle, calendar, min, max, defaultPlan, colorDays, colorDaysOfWeek,
new TimeScaleCompressed(calendar, scale), colorSet, themeStyle);
} }
@Override @Override
@ -90,7 +79,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, 19); drawVbar(ug, x1, 0, 19, false);
if (last != null) { if (last != null) {
printYear(ug, last, lastChange, x1); printYear(ug, last, lastChange, x1);
} }
@ -102,7 +91,7 @@ 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, 19); drawVbar(ug, getTimeScale().getEndingPosition(max), 0, 19, false);
} }
private void printYear(UGraphic ug, MonthYear monthYear, double start, double end) { private void printYear(UGraphic ug, MonthYear monthYear, double start, double end) {

View File

@ -48,17 +48,19 @@ import net.sourceforge.plantuml.project.core.TaskInstant;
public class ComplementBeforeOrAfterOrAtTaskStartOrEnd implements Something { public class ComplementBeforeOrAfterOrAtTaskStartOrEnd implements Something {
private static final int POS_NB1 = 0; private static final int POS_NB1 = 0;
private static final int POS_DAY_OR_WEEK1 = 1; private static final int POS_WORKING1 = 1;
private static final int POS_NB2 = 2; private static final int POS_DAY_OR_WEEK1 = 2;
private static final int POS_DAY_OR_WEEK2 = 3; private static final int POS_NB2 = 3;
private static final int POS_BEFORE_OR_AFTER = 4; private static final int POS_WORKING2 = 4;
private static final int POS_CODE_OTHER = 5; private static final int POS_DAY_OR_WEEK2 = 5;
private static final int POS_START_OR_END = 6; private static final int POS_BEFORE_OR_AFTER = 6;
private static final int POS_CODE_OTHER = 7;
private static final int POS_START_OR_END = 8;
public IRegex toRegex(String suffix) { // "+" public IRegex toRegex(String suffix) { // "+"
return new RegexLeaf("COMPLEMENT" + suffix, "(?:at|with|after|" + // return new RegexLeaf("COMPLEMENT" + suffix, "(?:at|with|after|" + //
"(\\d+)[%s]+(day|week)s?" + // "(\\d+)[%s]+(working[%s]+)?(day|week)s?" + //
"(?:[%s]+and[%s]+(\\d+)[%s]+(day|week)s?)?" + // "(?:[%s]+and[%s]+(\\d+)[%s]+(working[%s]+)?(day|week)s?)?" + //
"[%s]+(before|after))[%s]+\\[([^\\[\\]]+?)\\].?s[%s]+(start|end)"); "[%s]+(before|after))[%s]+\\[([^\\[\\]]+?)\\].?s[%s]+(start|end)");
} }
@ -89,7 +91,11 @@ public class ComplementBeforeOrAfterOrAtTaskStartOrEnd implements Something {
if ("before".equalsIgnoreCase(arg.get("COMPLEMENT" + suffix, POS_BEFORE_OR_AFTER))) if ("before".equalsIgnoreCase(arg.get("COMPLEMENT" + suffix, POS_BEFORE_OR_AFTER)))
delta = -delta; delta = -delta;
final GanttConstraintMode mode = GanttConstraintMode.IGNORE_CALENDAR; final boolean working = arg.get("COMPLEMENT" + suffix, POS_WORKING1) != null
|| arg.get("COMPLEMENT" + suffix, POS_WORKING2) != null;
final GanttConstraintMode mode = working ? GanttConstraintMode.DO_NOT_COUNT_CLOSE_DAY
: GanttConstraintMode.IGNORE_CALENDAR;
result = result.withDelta(delta, mode, system.getDefaultPlan()); result = result.withDelta(delta, mode, system.getDefaultPlan());
} }

View File

@ -0,0 +1,113 @@
/* ========================================================================
* PlantUML : a free UML diagram generator
* ========================================================================
*
* (C) Copyright 2009-2023, 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.lang;
import java.util.Arrays;
import java.util.Collection;
import net.sourceforge.plantuml.command.CommandExecutionResult;
import net.sourceforge.plantuml.command.regex.IRegex;
import net.sourceforge.plantuml.command.regex.RegexLeaf;
import net.sourceforge.plantuml.command.regex.RegexResult;
import net.sourceforge.plantuml.project.Failable;
import net.sourceforge.plantuml.project.GanttDiagram;
import net.sourceforge.plantuml.project.core.TaskInstant;
import net.sourceforge.plantuml.project.time.Day;
public class SubjectSeparator implements Subject {
public IRegex toRegex() {
return new RegexLeaf("SUBJECT", "separator");
}
public Failable<GanttDiagram> getMe(GanttDiagram project, RegexResult arg) {
return Failable.ok(project);
}
public Collection<? extends SentenceSimple> getSentences() {
return Arrays.asList(new JustBefore(), new JustAfter(), new Just());
}
class JustBefore extends SentenceSimple {
public JustBefore() {
super(SubjectSeparator.this, Verbs.justBefore(), new ComplementDate());
}
@Override
public CommandExecutionResult execute(GanttDiagram project, Object subject, Object complement) {
final Day day = (Day) complement;
assert project == subject;
project.addVerticalSeparatorBefore(day);
return CommandExecutionResult.ok();
}
}
class JustAfter extends SentenceSimple {
public JustAfter() {
super(SubjectSeparator.this, Verbs.justAfter(), new ComplementDate());
}
@Override
public CommandExecutionResult execute(GanttDiagram project, Object subject, Object complement) {
final Day day = (Day) complement;
assert project == subject;
project.addVerticalSeparatorBefore(day.increment());
return CommandExecutionResult.ok();
}
}
class Just extends SentenceSimple {
public Just() {
super(SubjectSeparator.this, Verbs.just(), new ComplementBeforeOrAfterOrAtTaskStartOrEnd());
}
@Override
public CommandExecutionResult execute(GanttDiagram project, Object subject, Object complement) {
final TaskInstant when = (TaskInstant) complement;
assert project == subject;
project.addVerticalSeparatorBefore(when.getInstantPrecise());
return CommandExecutionResult.ok();
}
}
}

View File

@ -155,4 +155,16 @@ public class Verbs {
); );
} }
public static IRegex just() {
return new RegexLeaf("just");
}
public static IRegex justBefore() {
return new RegexLeaf("just[%s]*before");
}
public static IRegex justAfter() {
return new RegexLeaf("just[%s]*after");
}
} }

View File

@ -43,7 +43,7 @@ public class TimeScaleCompressed implements TimeScale {
private final TimeScale daily; private final TimeScale daily;
public TimeScaleCompressed(Day calendar, double scale) { public TimeScaleCompressed(Day calendar, double scale) {
this.daily = new TimeScaleDaily(scale, calendar, null); this.daily = new TimeScaleDaily(calendar, scale, null);
} }
public double getStartingPosition(Day instant) { public double getStartingPosition(Day instant) {

View File

@ -43,13 +43,12 @@ public final class TimeScaleDaily implements TimeScale {
private final TimeScaleWink basic; private final TimeScaleWink basic;
private final double delta; private final double delta;
public TimeScaleDaily(double scale, Day calendar, Day zeroDay) { public TimeScaleDaily(Day startingDay, double scale, Day zeroDay) {
this.basic = new TimeScaleWink(scale, PrintScale.DAILY); this.basic = new TimeScaleWink(scale, PrintScale.DAILY);
if (zeroDay == null) { if (zeroDay == null)
this.delta = basic.getStartingPosition(calendar); this.delta = basic.getStartingPosition(startingDay);
} else { else
this.delta = basic.getStartingPosition(zeroDay); this.delta = basic.getStartingPosition(zeroDay);
}
} }

View File

@ -81,7 +81,7 @@ public class Version {
} }
public static int beta() { public static int beta() {
final int beta = 10; final int beta = 11;
return beta; return beta;
} }