mirror of
https://github.com/octoleo/plantuml.git
synced 2024-12-22 10:59:01 +00:00
fix: several Gantt improvement
https://forum.plantuml.net/18397/gantt-how-handle-resource-starts-terminates-specific-date https://forum.plantuml.net/17571/is-it-possible-to-set-gantt-tasks-to-be-incomplete-by-default?show=17571#q17571 https://forum.plantuml.net/18128/gantt-diagram-vertical-separator-styling?show=18128#q18128
This commit is contained in:
parent
e4c246750e
commit
8b5a1521e7
@ -1,4 +1,4 @@
|
||||
# Warning, "version" should be the same in gradle.properties and Version.java
|
||||
# Any idea anyone how to magically synchronize those :-) ?
|
||||
version = 1.2023.13beta2
|
||||
version = 1.2023.13beta3
|
||||
org.gradle.workers.max = 3
|
@ -367,6 +367,11 @@ ganttDiagram {
|
||||
Margin 5
|
||||
Padding 5
|
||||
}
|
||||
verticalSeparator {
|
||||
LineThickness 2
|
||||
LineStyle 2-2
|
||||
LineColor black
|
||||
}
|
||||
timeline {
|
||||
BackgroundColor transparent
|
||||
LineColor #C0C0C0
|
||||
|
@ -85,83 +85,77 @@ public class OptionPrint {
|
||||
System.out.println("\t?\tone and only one character but '" + SFile.separator + "'");
|
||||
System.out.println("\t**\tmeans any characters (used to recurse through directories)");
|
||||
System.out.println();
|
||||
System.out.println("where options include:");
|
||||
System.out.println(" -darkmode\t\tTo use dark mode for diagrams");
|
||||
System.out.println(" -gui\t\tTo run the graphical user interface");
|
||||
System.out.println(" -tpng\t\tTo generate images using PNG format (default)");
|
||||
System.out.println(" -tsvg\t\tTo generate images using SVG format");
|
||||
System.out.println(" -teps\t\tTo generate images using EPS format");
|
||||
System.out.println(" -tpdf\t\tTo generate images using PDF format");
|
||||
System.out.println(" -tvdx\t\tTo generate images using VDX format");
|
||||
System.out.println(" -txmi\t\tTo generate XMI file for class diagram");
|
||||
System.out.println(" -tscxml\t\tTo generate SCXML file for state diagram");
|
||||
System.out.println(" -thtml\t\tTo generate HTML file for class diagram");
|
||||
System.out.println(" -ttxt\t\tTo generate images with ASCII art");
|
||||
System.out.println(" -tutxt\t\tTo generate images with ASCII art using Unicode characters");
|
||||
System.out.println(" -tlatex\t\tTo generate images using LaTeX/Tikz format");
|
||||
System.out.println(" -tlatex:nopreamble\tTo generate images using LaTeX/Tikz format without preamble");
|
||||
System.out.println(" -o[utput] \"dir\"\tTo generate images in the specified directory");
|
||||
System.out.println(" -DVAR1=value\tTo set a preprocessing variable as if '!define VAR1 value' were used");
|
||||
System.out.println(" -Sparam1=value\tTo set a skin parameter as if 'skinparam param1 value' were used");
|
||||
System.out.println(" -Ppragma1=value\tTo set pragma as if '!pragma pragma1 value' were used");
|
||||
// System.out.println(" -config \"file\"\tTo read the provided config file
|
||||
// before each diagram");
|
||||
final char separator = SFile.separatorChar;
|
||||
System.out.println(" -I" + separator + "path" + separator + "to" + separator
|
||||
+ "file\tTo include file as if '!include file' were used");
|
||||
System.out.println(
|
||||
" -I" + separator + "path" + separator + "to" + separator + "*.puml\tTo include files with pattern");
|
||||
System.out.println(" -theme xxx\t\tTo use a specific theme");
|
||||
System.out.println(" -charset xxx\tTo use a specific charset (default is " + charset + ")");
|
||||
System.out.println(" -e[x]clude pattern\tTo exclude files that match the provided pattern");
|
||||
System.out.println(" -metadata\t\tTo retrieve PlantUML sources from PNG images");
|
||||
System.out.println(" -nometadata\t\tTo NOT export metadata in PNG/SVG generated files");
|
||||
System.out.println("where options include:");
|
||||
System.out.println(" -author[s]\t\tTo print information about PlantUML authors");
|
||||
System.out.println(" -checkmetadata\t\tSkip PNG files that don't need to be regenerated");
|
||||
System.out.println(" -version\t\tTo display information about PlantUML and Java versions");
|
||||
System.out.println(" -v[erbose]\t\tTo have log information");
|
||||
System.out.println(" -quiet\t\tTo NOT print error message into the console");
|
||||
System.out.println(" -debugsvek\t\tTo generate intermediate svek files");
|
||||
System.out.println(" -h[elp]\t\tTo display this help message");
|
||||
System.out.println(" -testdot\t\tTo test the installation of graphviz");
|
||||
System.out.println(" -graphvizdot \"exe\"\tTo specify dot executable");
|
||||
System.out.println(" -p[ipe]\t\tTo use stdin for PlantUML source and stdout for PNG/SVG/EPS generation");
|
||||
System.out.println(
|
||||
" -encodesprite 4|8|16[z] \"file\"\tTo encode a sprite at gray level (z for compression) from an image");
|
||||
System.out.println(" -computeurl|-encodeurl\tTo compute the encoded URL of a PlantUML source file");
|
||||
System.out.println(" -decodeurl\t\tTo retrieve the PlantUML source from an encoded URL");
|
||||
System.out.println(" -syntax\t\tTo report any syntax error from standard input without generating images");
|
||||
System.out.println(" -language\t\tTo print the list of PlantUML keywords");
|
||||
// System.out.println(" -nosuggestengine\tTo disable the suggest engine when
|
||||
// errors in diagrams");
|
||||
System.out.println(" -checkonly\t\tTo check the syntax of files without generating images");
|
||||
System.out.println(" -charset xxx\tTo use a specific charset (default is " + charset + ")");
|
||||
System.out.println(" -computeurl|-encodeurl\tTo compute the encoded URL of a PlantUML source file");
|
||||
// System.out.println(" -config \"file\"\tTo read the provided config file
|
||||
System.out.println(" -cypher\t\tTo cypher texts of diagrams so that you can share them");
|
||||
System.out.println(" -DVAR1=value\tTo set a preprocessing variable as if '!define VAR1 value' were used");
|
||||
System.out.println(" -darkmode\t\tTo use dark mode for diagrams");
|
||||
System.out.println(" -debugsvek\t\tTo generate intermediate svek files");
|
||||
System.out.println(" -decodeurl\t\tTo retrieve the PlantUML source from an encoded URL");
|
||||
System.out.println(" -disablestats\tTo disable statistics computation (default)");
|
||||
System.out.println(" -duration\t\tTo print the duration of complete diagrams processing");
|
||||
System.out.println(" -e[x]clude pattern\tTo exclude files that match the provided pattern");
|
||||
System.out.println(" -enablestats\tTo enable statistics computation");
|
||||
System.out.println(" -encodesprite 4|8|16[z] \"file\"\tTo encode a sprite at gray level (z for compression) from an image");
|
||||
System.out.println(" -extractstdlib\tTo extract PlantUML Standard Library into stdlib folder");
|
||||
System.out.println(" -failfast\t\tTo stop processing as soon as a syntax error in diagram occurs");
|
||||
System.out.println(" -failfast2\t\tTo do a first syntax check before processing files, to fail even faster");
|
||||
System.out.println(" -noerror\t\tTo skip images when error in diagrams");
|
||||
System.out.println(" -duration\t\tTo print the duration of complete diagrams processing");
|
||||
System.out.println(" -filedir xxx\tTo behave as if the PlantUML source is in this dir (only affects '-pipe' and PicoWeb 'POST /render')");
|
||||
System.out.println(" -filename \"example.puml\"\tTo override %filename% variable");
|
||||
System.out.println(" -graphvizdot \"exe\"\tTo specify dot executable");
|
||||
System.out.println(" -gui\t\tTo run the graphical user interface");
|
||||
System.out.println(" -h[elp]\t\tTo display this help message");
|
||||
System.out.println(" -htmlstats\t\tTo output general statistics in file plantuml-stats.html");
|
||||
System.out.println(" -I" + separator + "path" + separator + "to" + separator + "file\tTo include file as if '!include file' were used");
|
||||
System.out.println(" -I" + separator + "path" + separator + "to" + separator + "*.puml\tTo include files with pattern");
|
||||
System.out.println(" -language\t\tTo print the list of PlantUML keywords");
|
||||
System.out.println(" -loopstats\t\tTo continuously print statistics about usage");
|
||||
System.out.println(" -metadata\t\tTo retrieve PlantUML sources from PNG images");
|
||||
System.out.println(" -nbthread N\t\tTo use (N) threads for processing");
|
||||
System.out.println(" -nbthread auto\tTo use " + Option.defaultNbThreads() + " threads for processing");
|
||||
System.out
|
||||
.println(" -timeout N\t\tProcessing timeout in (N) seconds. Defaults to 15 minutes (900 seconds).");
|
||||
System.out.println(" -author[s]\t\tTo print information about PlantUML authors");
|
||||
System.out.println(" -noerror\t\tTo skip images when error in diagrams");
|
||||
System.out.println(" -nometadata\t\tTo NOT export metadata in PNG/SVG generated files");
|
||||
System.out.println(" -o[utput] \"dir\"\tTo generate images in the specified directory");
|
||||
System.out.println(" -overwrite\t\tTo allow to overwrite read only files");
|
||||
System.out.println(" -printfonts\t\tTo print fonts available on your system");
|
||||
System.out.println(" -enablestats\tTo enable statistics computation");
|
||||
System.out.println(" -disablestats\tTo disable statistics computation (default)");
|
||||
System.out.println(" -htmlstats\t\tTo output general statistics in file plantuml-stats.html");
|
||||
System.out.println(" -xmlstats\t\tTo output general statistics in file plantuml-stats.xml");
|
||||
System.out.println(" -realtimestats\tTo generate statistics on the fly rather than at the end");
|
||||
System.out.println(" -loopstats\t\tTo continuously print statistics about usage");
|
||||
System.out.println(" -splash\t\tTo display a splash screen with some progress bar");
|
||||
System.out.println(" -progress\t\tTo display a textual progress bar in console");
|
||||
System.out.println(" -pipeimageindex N\tTo generate the Nth image with pipe option");
|
||||
System.out.println(" -stdlib\t\tTo print standard library info");
|
||||
System.out.println(" -extractstdlib\tTo extract PlantUML Standard Library into stdlib folder");
|
||||
System.out.println(
|
||||
" -filedir xxx\tTo behave as if the PlantUML source is in this dir (only affects '-pipe' and PicoWeb 'POST /render')");
|
||||
System.out.println(" -filename \"example.puml\"\tTo override %filename% variable");
|
||||
System.out.println(" -preproc\t\tTo output preprocessor text of diagrams");
|
||||
System.out.println(" -cypher\t\tTo cypher texts of diagrams so that you can share them");
|
||||
System.out.println(" -Ppragma1=value\tTo set pragma as if '!pragma pragma1 value' were used");
|
||||
System.out.println(" -p[ipe]\t\tTo use stdin for PlantUML source and stdout for PNG/SVG/EPS generation");
|
||||
System.out.println(" -picoweb\t\tTo start internal HTTP Server. See https://plantuml.com/picoweb");
|
||||
System.out.println(" -pipeimageindex N\tTo generate the Nth image with pipe option");
|
||||
System.out.println(" -preproc\t\tTo output preprocessor text of diagrams");
|
||||
System.out.println(" -printfonts\t\tTo print fonts available on your system");
|
||||
System.out.println(" -progress\t\tTo display a textual progress bar in console");
|
||||
System.out.println(" -quiet\t\tTo NOT print error message into the console");
|
||||
System.out.println(" -realtimestats\tTo generate statistics on the fly rather than at the end");
|
||||
System.out.println(" -Sparam1=value\tTo set a skin parameter as if 'skinparam param1 value' were used");
|
||||
System.out.println(" -splash\t\tTo display a splash screen with some progress bar");
|
||||
System.out.println(" -stdlib\t\tTo print standard library info");
|
||||
System.out.println(" -syntax\t\tTo report any syntax error from standard input without generating images");
|
||||
System.out.println(" -testdot\t\tTo test the installation of graphviz");
|
||||
System.out.println(" -theme xxx\t\tTo use a specific theme");
|
||||
System.out.println(" -timeout N\t\tProcessing timeout in (N) seconds. Defaults to 15 minutes (900 seconds).");
|
||||
System.out.println(" -teps\t\tTo generate images using EPS format");
|
||||
System.out.println(" -testdot\t\tTo test the installation of graphviz");
|
||||
System.out.println(" -theme xxx\t\tTo use a specific theme");
|
||||
System.out.println(" -thtml\t\tTo generate HTML file for class diagram");
|
||||
System.out.println(" -tlatex:nopreamble\tTo generate images using LaTeX/Tikz format without preamble");
|
||||
System.out.println(" -tlatex\t\tTo generate images using LaTeX/Tikz format");
|
||||
System.out.println(" -tpdf\t\tTo generate images using PDF format");
|
||||
System.out.println(" -tpng\t\tTo generate images using PNG format (default)");
|
||||
System.out.println(" -tscxml\t\tTo generate SCXML file for state diagram");
|
||||
System.out.println(" -tsvg\t\tTo generate images using SVG format");
|
||||
System.out.println(" -ttxt\t\tTo generate images with ASCII art");
|
||||
System.out.println(" -tutxt\t\tTo generate images with ASCII art using Unicode characters");
|
||||
System.out.println(" -tvdx\t\tTo generate images using VDX format");
|
||||
System.out.println(" -txmi\t\tTo generate XMI file for class diagram");
|
||||
System.out.println(" -v[erbose]\t\tTo have log information");
|
||||
System.out.println(" -version\t\tTo display information about PlantUML and Java versions");
|
||||
System.out.println(" -xmlstats\t\tTo output general statistics in file plantuml-stats.xml");
|
||||
System.out.println();
|
||||
System.out.println("If needed, you can setup the environment variable GRAPHVIZ_DOT.");
|
||||
exit(0);
|
||||
|
@ -53,8 +53,14 @@ public class ConstantPlan implements LoadPlanable {
|
||||
return new ConstantPlan(load);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLoadAt(Day instant) {
|
||||
return loadPerInstant;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Day getLastDayIfAny() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@ -86,6 +86,7 @@ import net.sourceforge.plantuml.project.core.TaskInstant;
|
||||
import net.sourceforge.plantuml.project.core.TaskSeparator;
|
||||
import net.sourceforge.plantuml.project.draw.FingerPrint;
|
||||
import net.sourceforge.plantuml.project.draw.ResourceDraw;
|
||||
import net.sourceforge.plantuml.project.draw.ResourceDrawVersion2;
|
||||
import net.sourceforge.plantuml.project.draw.TaskDraw;
|
||||
import net.sourceforge.plantuml.project.draw.TaskDrawDiamond;
|
||||
import net.sourceforge.plantuml.project.draw.TaskDrawGroup;
|
||||
@ -99,6 +100,7 @@ import net.sourceforge.plantuml.project.draw.TimeHeaderSimple;
|
||||
import net.sourceforge.plantuml.project.draw.TimeHeaderWeekly;
|
||||
import net.sourceforge.plantuml.project.draw.TimeHeaderYearly;
|
||||
import net.sourceforge.plantuml.project.lang.CenterBorderColor;
|
||||
import net.sourceforge.plantuml.project.solver.ImpossibleSolvingException;
|
||||
import net.sourceforge.plantuml.project.time.Day;
|
||||
import net.sourceforge.plantuml.project.time.DayOfWeek;
|
||||
import net.sourceforge.plantuml.project.time.WeekNumberStrategy;
|
||||
@ -149,6 +151,8 @@ public class GanttDiagram extends TitledDiagram implements ToTaskDraw, WithSprit
|
||||
|
||||
private final RealOrigin origin = RealUtils.createOrigin();
|
||||
|
||||
private int defaultCompletion = 100;
|
||||
|
||||
public CommandExecutionResult changeLanguage(String lang) {
|
||||
this.locale = new Locale(lang);
|
||||
return CommandExecutionResult.ok();
|
||||
@ -202,6 +206,16 @@ public class GanttDiagram extends TitledDiagram implements ToTaskDraw, WithSprit
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String checkFinalError() {
|
||||
try {
|
||||
initMinMax();
|
||||
} catch (ImpossibleSolvingException ex) {
|
||||
return ex.getMessage();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected TextBlock getTextBlock() {
|
||||
final FileFormatOption fileFormatOption = new FileFormatOption(FileFormat.PNG);
|
||||
@ -312,7 +326,8 @@ public class GanttDiagram extends TitledDiagram implements ToTaskDraw, WithSprit
|
||||
|
||||
private TimeHeaderParameters thParam() {
|
||||
return new TimeHeaderParameters(colorDays(), getFactorScale(), min, max, getIHtmlColorSet(), getTimelineStyle(),
|
||||
getClosedStyle(), locale, openClose, colorDaysOfWeek, verticalSeparatorBefore);
|
||||
getClosedStyle(), locale, openClose, colorDaysOfWeek, verticalSeparatorBefore,
|
||||
getVerticalSeparatorStyle());
|
||||
}
|
||||
|
||||
private Map<Day, HColor> colorDays() {
|
||||
@ -330,6 +345,11 @@ public class GanttDiagram extends TitledDiagram implements ToTaskDraw, WithSprit
|
||||
.getMergedStyle(getCurrentStyleBuilder());
|
||||
}
|
||||
|
||||
private Style getVerticalSeparatorStyle() {
|
||||
return StyleSignatureBasic.of(SName.root, SName.element, SName.ganttDiagram, SName.verticalSeparator)
|
||||
.getMergedStyle(getCurrentStyleBuilder());
|
||||
}
|
||||
|
||||
private double getTotalHeight(TimeHeader timeHeader) {
|
||||
if (showFootbox)
|
||||
return totalHeightWithoutFooter + timeHeader.getTimeFooterHeight();
|
||||
@ -457,14 +477,19 @@ public class GanttDiagram extends TitledDiagram implements ToTaskDraw, WithSprit
|
||||
yy = headerHeight;
|
||||
} else if (this.hideResourceFoobox == false)
|
||||
for (Resource res : resources.values()) {
|
||||
final ResourceDraw draw = new ResourceDraw(this, res, timeScale, yy, min, max);
|
||||
final ResourceDraw draw = buildResourceDraw(this, res, timeScale, yy, min, max);
|
||||
res.setTaskDraw(draw);
|
||||
yy += draw.getHeight();
|
||||
yy += draw.getHeight(stringBounder);
|
||||
}
|
||||
|
||||
this.totalHeightWithoutFooter = yy;
|
||||
}
|
||||
|
||||
private ResourceDraw buildResourceDraw(GanttDiagram gantt, Resource res, TimeScale timeScale, double y, Day min,
|
||||
Day max) {
|
||||
return new ResourceDrawVersion2(gantt, res, timeScale, y, min, max);
|
||||
}
|
||||
|
||||
private Collection<GanttConstraint> getConstraints(Task task) {
|
||||
final List<GanttConstraint> result = new ArrayList<>();
|
||||
for (GanttConstraint constraint : constraints) {
|
||||
@ -603,7 +628,7 @@ public class GanttDiagram extends TitledDiagram implements ToTaskDraw, WithSprit
|
||||
final OpenClose except = this.openCloseForTask.get(codeOrShortName);
|
||||
|
||||
result = new TaskImpl(getSkinParam().getCurrentStyleBuilder(), code, openClose.mutateMe(except),
|
||||
openClose.getStartingDay());
|
||||
openClose.getStartingDay(), defaultCompletion);
|
||||
if (currentGroup != null)
|
||||
currentGroup.addTask(result);
|
||||
|
||||
@ -866,4 +891,19 @@ public class GanttDiagram extends TitledDiagram implements ToTaskDraw, WithSprit
|
||||
verticalSeparatorBefore.add(day);
|
||||
}
|
||||
|
||||
public void setTaskDefaultCompletion(int defaultCompletion) {
|
||||
this.defaultCompletion = defaultCompletion;
|
||||
}
|
||||
|
||||
public List<TaskDrawRegular> getAllTasksForResource(Resource res) {
|
||||
final List<TaskDrawRegular> result = new ArrayList<TaskDrawRegular>();
|
||||
for (Task task : tasks.values())
|
||||
if (task.isAssignedTo(res)) {
|
||||
final TaskDrawRegular draw = (TaskDrawRegular) draws.get(task);
|
||||
result.add(draw);
|
||||
}
|
||||
|
||||
return Collections.unmodifiableList(result);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -59,6 +59,7 @@ import net.sourceforge.plantuml.project.command.CommandNoteBottom;
|
||||
import net.sourceforge.plantuml.project.command.CommandPrintBetween;
|
||||
import net.sourceforge.plantuml.project.command.CommandPrintScale;
|
||||
import net.sourceforge.plantuml.project.command.CommandSeparator;
|
||||
import net.sourceforge.plantuml.project.command.CommandTaskCompleteDefault;
|
||||
import net.sourceforge.plantuml.project.command.CommandWeekNumberStrategy;
|
||||
import net.sourceforge.plantuml.project.command.NaturalCommand;
|
||||
import net.sourceforge.plantuml.project.lang.SentenceAnd;
|
||||
@ -115,6 +116,7 @@ public class GanttDiagramFactory extends PSystemCommandFactory {
|
||||
cmds.add(new CommandLabelOnColumn());
|
||||
cmds.add(new CommandHideResourceName());
|
||||
cmds.add(new CommandHideResourceFootbox());
|
||||
cmds.add(new CommandTaskCompleteDefault());
|
||||
}
|
||||
|
||||
private void addLanguageCommands(List<Command> cmd) {
|
||||
|
@ -40,4 +40,6 @@ import net.sourceforge.plantuml.project.time.Day;
|
||||
public interface LoadPlanable {
|
||||
|
||||
public int getLoadAt(Day instant);
|
||||
|
||||
public Day getLastDayIfAny();
|
||||
}
|
||||
|
@ -49,6 +49,8 @@ public class OpenClose implements Histogram, LoadPlanable {
|
||||
private final Map<DayOfWeek, DayStatus> weekdayStatus = new EnumMap<>(DayOfWeek.class);
|
||||
private final Map<Day, DayStatus> dayStatus = new HashMap<>();
|
||||
private Day startingDay;
|
||||
private Day offBefore;
|
||||
private Day offAfter;
|
||||
|
||||
public int daysInWeek() {
|
||||
int result = 7;
|
||||
@ -89,6 +91,11 @@ public class OpenClose implements Histogram, LoadPlanable {
|
||||
}
|
||||
|
||||
private DayStatus getLocalStatus(Day day) {
|
||||
if (offBefore != null && day.compareTo(offBefore) < 0)
|
||||
return DayStatus.CLOSE;
|
||||
if (offAfter != null && day.compareTo(offAfter) > 0)
|
||||
return DayStatus.CLOSE;
|
||||
|
||||
final DayStatus status1 = dayStatus.get(day);
|
||||
if (status1 != null)
|
||||
return status1;
|
||||
@ -174,6 +181,14 @@ public class OpenClose implements Histogram, LoadPlanable {
|
||||
return getLoatAtInternal(day);
|
||||
}
|
||||
|
||||
public void setOffBeforeDate(Day day) {
|
||||
this.offBefore = day;
|
||||
}
|
||||
|
||||
public void setOffAfterDate(Day day) {
|
||||
this.offAfter = day;
|
||||
}
|
||||
|
||||
private int getLoatAtInternal(Day day) {
|
||||
if (isClosed(day))
|
||||
return 0;
|
||||
@ -193,8 +208,18 @@ public class OpenClose implements Histogram, LoadPlanable {
|
||||
return 100;
|
||||
return OpenClose.this.getLoadAt(instant);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Day getLastDayIfAny() {
|
||||
return offAfter;
|
||||
}
|
||||
};
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Day getLastDayIfAny() {
|
||||
return offAfter;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -48,6 +48,10 @@ public class PlanUtils {
|
||||
public int getLoadAt(Day instant) {
|
||||
return Math.min(p1.getLoadAt(instant), p2.getLoadAt(instant));
|
||||
}
|
||||
|
||||
public Day getLastDayIfAny() {
|
||||
return lastOf(p1.getLastDayIfAny(), p2.getLastDayIfAny());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@ -56,7 +60,21 @@ public class PlanUtils {
|
||||
public int getLoadAt(Day instant) {
|
||||
return p1.getLoadAt(instant) * p2.getLoadAt(instant) / 100;
|
||||
}
|
||||
|
||||
public Day getLastDayIfAny() {
|
||||
return lastOf(p1.getLastDayIfAny(), p2.getLastDayIfAny());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private static Day lastOf(Day day1, Day day2) {
|
||||
if (day1 == null)
|
||||
return day2;
|
||||
if (day2 == null)
|
||||
return day1;
|
||||
if (day1.compareTo(day2) > 0)
|
||||
return day1;
|
||||
return day2;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -39,10 +39,13 @@ import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import net.sourceforge.plantuml.klimt.UStroke;
|
||||
import net.sourceforge.plantuml.klimt.color.HColor;
|
||||
import net.sourceforge.plantuml.klimt.color.HColorSet;
|
||||
import net.sourceforge.plantuml.klimt.drawing.UGraphic;
|
||||
import net.sourceforge.plantuml.project.time.Day;
|
||||
import net.sourceforge.plantuml.project.time.DayOfWeek;
|
||||
import net.sourceforge.plantuml.style.PName;
|
||||
import net.sourceforge.plantuml.style.Style;
|
||||
|
||||
public class TimeHeaderParameters {
|
||||
@ -54,6 +57,7 @@ public class TimeHeaderParameters {
|
||||
private final HColorSet colorSet;
|
||||
private final Style timelineStyle;
|
||||
private final Style closedStyle;
|
||||
private final Style verticalSeparatorStyle;
|
||||
private final Locale locale;
|
||||
private final OpenClose openClose;
|
||||
private final Map<DayOfWeek, HColor> colorDaysOfWeek;
|
||||
@ -61,7 +65,7 @@ public class TimeHeaderParameters {
|
||||
|
||||
public TimeHeaderParameters(Map<Day, HColor> colorDays, double scale, Day min, Day max, HColorSet colorSet,
|
||||
Style timelineStyle, Style closedStyle, Locale locale, OpenClose openClose,
|
||||
Map<DayOfWeek, HColor> colorDaysOfWeek, Set<Day> verticalSeparatorBefore) {
|
||||
Map<DayOfWeek, HColor> colorDaysOfWeek, Set<Day> verticalSeparatorBefore, Style verticalSeparatorStyle) {
|
||||
this.colorDays = colorDays;
|
||||
this.scale = scale;
|
||||
this.min = min;
|
||||
@ -73,6 +77,7 @@ public class TimeHeaderParameters {
|
||||
this.openClose = openClose;
|
||||
this.colorDaysOfWeek = colorDaysOfWeek;
|
||||
this.verticalSeparatorBefore = verticalSeparatorBefore;
|
||||
this.verticalSeparatorStyle = verticalSeparatorStyle;
|
||||
}
|
||||
|
||||
public HColor getColor(Day wink) {
|
||||
@ -123,4 +128,10 @@ public class TimeHeaderParameters {
|
||||
return verticalSeparatorBefore;
|
||||
}
|
||||
|
||||
public final UGraphic forVerticalSeparator(UGraphic ug) {
|
||||
final HColor color = verticalSeparatorStyle.value(PName.LineColor).asColor(getColorSet());
|
||||
final UStroke stroke = verticalSeparatorStyle.getStroke();
|
||||
return ug.apply(color).apply(stroke);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -48,7 +48,7 @@ import net.sourceforge.plantuml.utils.LineLocation;
|
||||
|
||||
public class CommandPrintBetween extends SingleLineCommand2<GanttDiagram> {
|
||||
|
||||
private static final ComplementDate pattern = new ComplementDate();
|
||||
private static final ComplementDate pattern = ComplementDate.any();
|
||||
|
||||
public CommandPrintBetween() {
|
||||
super(getRegexConcat());
|
||||
|
@ -0,0 +1,84 @@
|
||||
/* ========================================================================
|
||||
* PlantUML : a free UML diagram generator
|
||||
* ========================================================================
|
||||
*
|
||||
* (C) Copyright 2009-2024, Arnaud Roques
|
||||
*
|
||||
* Project Info: https://plantuml.com
|
||||
*
|
||||
* If you like this project or if you find it useful, you can support us at:
|
||||
*
|
||||
* https://plantuml.com/patreon (only 1$ per month!)
|
||||
* https://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.command.CommandExecutionResult;
|
||||
import net.sourceforge.plantuml.command.SingleLineCommand2;
|
||||
import net.sourceforge.plantuml.klimt.color.NoSuchColorException;
|
||||
import net.sourceforge.plantuml.project.GanttDiagram;
|
||||
import net.sourceforge.plantuml.regex.IRegex;
|
||||
import net.sourceforge.plantuml.regex.RegexConcat;
|
||||
import net.sourceforge.plantuml.regex.RegexLeaf;
|
||||
import net.sourceforge.plantuml.regex.RegexOr;
|
||||
import net.sourceforge.plantuml.regex.RegexResult;
|
||||
import net.sourceforge.plantuml.utils.LineLocation;
|
||||
|
||||
public class CommandTaskCompleteDefault extends SingleLineCommand2<GanttDiagram> {
|
||||
|
||||
public CommandTaskCompleteDefault() {
|
||||
super(getRegexConcat());
|
||||
}
|
||||
|
||||
static IRegex getRegexConcat() {
|
||||
return RegexConcat.build(CommandTaskCompleteDefault.class.getName(), RegexLeaf.start(), //
|
||||
new RegexLeaf("task"), //
|
||||
RegexLeaf.spaceOneOrMore(), //
|
||||
new RegexOr(//
|
||||
new RegexLeaf("default[%s]+completion"), //
|
||||
new RegexLeaf("completion[%s]+default")), //
|
||||
RegexLeaf.spaceOneOrMore(), //
|
||||
new RegexLeaf("to"), //
|
||||
RegexLeaf.spaceOneOrMore(), //
|
||||
new RegexLeaf("VALUE", "(\\d+)"), //
|
||||
new RegexLeaf(".*"), //
|
||||
RegexLeaf.spaceZeroOrMore(), //
|
||||
RegexLeaf.end());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected CommandExecutionResult executeArg(GanttDiagram diagram, LineLocation location, RegexResult arg)
|
||||
throws NoSuchColorException {
|
||||
|
||||
final int value = Integer.parseInt(arg.get("VALUE", 0));
|
||||
if (value > 100)
|
||||
return CommandExecutionResult.error("Completetion must between 0 and 100");
|
||||
|
||||
diagram.setTaskDefaultCompletion(value);
|
||||
|
||||
return CommandExecutionResult.ok();
|
||||
}
|
||||
|
||||
}
|
@ -94,4 +94,17 @@ public class Resource {
|
||||
public void addCloseDay(DayOfWeek day) {
|
||||
openClose.close(day);
|
||||
}
|
||||
|
||||
public void setOffBeforeDate(Day day) {
|
||||
openClose.setOffBeforeDate(day);
|
||||
}
|
||||
|
||||
public void setOffAfterDate(Day day) {
|
||||
openClose.setOffAfterDate(day);
|
||||
}
|
||||
|
||||
public Day getLastDayIfAny() {
|
||||
return openClose.getLastDayIfAny();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -79,4 +79,6 @@ public interface Task extends Moment {
|
||||
|
||||
public StyleBuilder getStyleBuilder();
|
||||
|
||||
public boolean isAssignedTo(Resource res);
|
||||
|
||||
}
|
||||
|
@ -56,6 +56,7 @@ public class TaskGroup extends AbstractTask implements Task {
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Day getStart() {
|
||||
Day min = null;
|
||||
for (Task child : children)
|
||||
@ -68,6 +69,7 @@ public class TaskGroup extends AbstractTask implements Task {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Day getEnd() {
|
||||
Day max = null;
|
||||
for (Task child : children)
|
||||
@ -80,54 +82,67 @@ public class TaskGroup extends AbstractTask implements Task {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setStart(Day start) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setEnd(Day end) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setColors(CenterBorderColor... colors) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addResource(Resource resource, int percentage) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Load getLoad() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLoad(Load load) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDiamond(boolean diamond) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDiamond() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCompletion(int completion) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setUrl(Url url) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addPause(Day pause) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addPause(DayOfWeek pause) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setNote(Display note) {
|
||||
}
|
||||
|
||||
@ -139,4 +154,9 @@ public class TaskGroup extends AbstractTask implements Task {
|
||||
return parent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAssignedTo(Resource res) {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -66,7 +66,7 @@ public class TaskImpl extends AbstractTask implements Task, LoadPlanable {
|
||||
private final LoadPlanable defaultPlan;
|
||||
private boolean diamond;
|
||||
|
||||
private int completion = 100;
|
||||
private int completion;
|
||||
private Display note;
|
||||
|
||||
private Url url;
|
||||
@ -76,8 +76,9 @@ public class TaskImpl extends AbstractTask implements Task, LoadPlanable {
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
public TaskImpl(StyleBuilder styleBuilder, TaskCode code, LoadPlanable plan, Day startingDay) {
|
||||
public TaskImpl(StyleBuilder styleBuilder, TaskCode code, LoadPlanable plan, Day startingDay, int completion) {
|
||||
super(styleBuilder, code);
|
||||
this.completion = completion;
|
||||
this.defaultPlan = plan;
|
||||
this.solver = new SolverImpl(this);
|
||||
if (startingDay == null)
|
||||
@ -88,6 +89,7 @@ public class TaskImpl extends AbstractTask implements Task, LoadPlanable {
|
||||
setLoad(Load.inWinks(1));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLoadAt(Day instant) {
|
||||
if (isPaused(instant))
|
||||
return 0;
|
||||
@ -131,10 +133,12 @@ public class TaskImpl extends AbstractTask implements Task, LoadPlanable {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addPause(Day pause) {
|
||||
this.pausedDay.add(pause);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addPause(DayOfWeek pause) {
|
||||
this.pausedDayOfWeek.add(pause);
|
||||
}
|
||||
@ -156,9 +160,29 @@ public class TaskImpl extends AbstractTask implements Task, LoadPlanable {
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Day getLastDayIfAny() {
|
||||
return TaskImpl.this.getLastDayIfAny();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public Day getLastDayIfAny() {
|
||||
Day result = null;
|
||||
|
||||
for (Resource res : resources.keySet()) {
|
||||
if (res.getLastDayIfAny() == null)
|
||||
return null;
|
||||
|
||||
if (result == null || result.compareTo(res.getLastDayIfAny()) < 0)
|
||||
result = res.getLastDayIfAny();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public String getPrettyDisplay() {
|
||||
if (resources.size() > 0) {
|
||||
final StringBuilder result = new StringBuilder(getCode().getSimpleDisplay());
|
||||
@ -190,6 +214,7 @@ public class TaskImpl extends AbstractTask implements Task, LoadPlanable {
|
||||
return "" + getStart() + " ---> " + getEnd() + " [" + getLoad() + "]";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Day getStart() {
|
||||
Day result = (Day) solver.getData(TaskAttribute.START);
|
||||
if (diamond == false)
|
||||
@ -199,42 +224,52 @@ public class TaskImpl extends AbstractTask implements Task, LoadPlanable {
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Day getEnd() {
|
||||
return (Day) solver.getData(TaskAttribute.END);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Load getLoad() {
|
||||
return (Load) solver.getData(TaskAttribute.LOAD);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLoad(Load load) {
|
||||
solver.setData(TaskAttribute.LOAD, load);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setStart(Day start) {
|
||||
solver.setData(TaskAttribute.START, start);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setEnd(Day end) {
|
||||
solver.setData(TaskAttribute.END, end);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setColors(CenterBorderColor... colors) {
|
||||
this.colors = colors;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addResource(Resource resource, int percentage) {
|
||||
this.resources.put(resource, percentage);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDiamond(boolean diamond) {
|
||||
this.diamond = diamond;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDiamond() {
|
||||
return this.diamond;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCompletion(int completion) {
|
||||
this.completion = completion;
|
||||
}
|
||||
@ -274,6 +309,7 @@ public class TaskImpl extends AbstractTask implements Task, LoadPlanable {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setNote(Display note) {
|
||||
this.note = note;
|
||||
}
|
||||
@ -286,4 +322,9 @@ public class TaskImpl extends AbstractTask implements Task, LoadPlanable {
|
||||
return defaultPlan;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAssignedTo(Resource res) {
|
||||
return resources.containsKey(res);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -52,22 +52,27 @@ public class TaskSeparator extends AbstractTask implements Task {
|
||||
this.comment = comment;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Day getStart() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Day getEnd() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setStart(Day start) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setEnd(Day end) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setColors(CenterBorderColor... colors) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
@ -76,10 +81,12 @@ public class TaskSeparator extends AbstractTask implements Task {
|
||||
return comment;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addResource(Resource resource, int percentage) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Load getLoad() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
@ -88,31 +95,43 @@ public class TaskSeparator extends AbstractTask implements Task {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDiamond(boolean diamond) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDiamond() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCompletion(int completion) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setUrl(Url url) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addPause(Day pause) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addPause(DayOfWeek pause) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setNote(Display note) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAssignedTo(Resource res) {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -35,96 +35,13 @@
|
||||
*/
|
||||
package net.sourceforge.plantuml.project.draw;
|
||||
|
||||
import net.sourceforge.plantuml.klimt.UTranslate;
|
||||
import net.sourceforge.plantuml.klimt.color.HColor;
|
||||
import net.sourceforge.plantuml.klimt.color.HColors;
|
||||
import net.sourceforge.plantuml.klimt.creole.Display;
|
||||
import net.sourceforge.plantuml.klimt.drawing.UGraphic;
|
||||
import net.sourceforge.plantuml.klimt.font.FontConfiguration;
|
||||
import net.sourceforge.plantuml.klimt.font.UFont;
|
||||
import net.sourceforge.plantuml.klimt.geom.HorizontalAlignment;
|
||||
import net.sourceforge.plantuml.klimt.shape.TextBlock;
|
||||
import net.sourceforge.plantuml.klimt.font.StringBounder;
|
||||
import net.sourceforge.plantuml.klimt.shape.UDrawable;
|
||||
import net.sourceforge.plantuml.klimt.shape.ULine;
|
||||
import net.sourceforge.plantuml.klimt.sprite.SpriteContainerEmpty;
|
||||
import net.sourceforge.plantuml.project.GanttDiagram;
|
||||
import net.sourceforge.plantuml.project.core.Resource;
|
||||
import net.sourceforge.plantuml.project.time.Day;
|
||||
import net.sourceforge.plantuml.project.timescale.TimeScale;
|
||||
|
||||
public class ResourceDraw implements UDrawable {
|
||||
public interface ResourceDraw extends UDrawable {
|
||||
|
||||
private final Resource res;
|
||||
private final TimeScale timeScale;
|
||||
private final double y;
|
||||
private final Day min;
|
||||
private final Day max;
|
||||
private final GanttDiagram gantt;
|
||||
public double getHeight(StringBounder stringBounder);
|
||||
|
||||
public ResourceDraw(GanttDiagram gantt, Resource res, TimeScale timeScale, double y, Day min, Day max) {
|
||||
this.res = res;
|
||||
this.timeScale = timeScale;
|
||||
this.y = y;
|
||||
this.min = min;
|
||||
this.max = max;
|
||||
this.gantt = gantt;
|
||||
}
|
||||
|
||||
public void drawU(UGraphic ug) {
|
||||
final TextBlock title = Display.getWithNewlines(res.getName()).create(getFontConfiguration(13),
|
||||
HorizontalAlignment.LEFT, new SpriteContainerEmpty());
|
||||
title.drawU(ug);
|
||||
final ULine line = ULine.hline(timeScale.getEndingPosition(max) - timeScale.getStartingPosition(min));
|
||||
ug.apply(HColors.BLACK).apply(UTranslate.dy(title.calculateDimension(ug.getStringBounder()).getHeight()))
|
||||
.draw(line);
|
||||
|
||||
double startingPosition = -1;
|
||||
int totalLoad = 0;
|
||||
int totalLimit = 0;
|
||||
for (Day i = min; i.compareTo(max) <= 0; i = i.increment()) {
|
||||
final boolean isBreaking = timeScale.isBreaking(i);
|
||||
totalLoad += gantt.getLoadForResource(res, i);
|
||||
totalLimit += 100;
|
||||
if (isBreaking) {
|
||||
if (totalLoad > 0) {
|
||||
final boolean over = totalLoad > totalLimit;
|
||||
final FontConfiguration fontConfiguration = getFontConfiguration(9,
|
||||
over ? HColors.RED : HColors.BLACK);
|
||||
final TextBlock value = Display.getWithNewlines("" + totalLoad).create(fontConfiguration,
|
||||
HorizontalAlignment.LEFT, new SpriteContainerEmpty());
|
||||
if (startingPosition == -1)
|
||||
startingPosition = timeScale.getStartingPosition(i);
|
||||
final double endingPosition = timeScale.getEndingPosition(i);
|
||||
final double start = (startingPosition + endingPosition) / 2
|
||||
- value.calculateDimension(ug.getStringBounder()).getWidth() / 2;
|
||||
value.drawU(ug.apply(new UTranslate(start, 16)));
|
||||
}
|
||||
startingPosition = -1;
|
||||
totalLoad = 0;
|
||||
totalLimit = 0;
|
||||
} else {
|
||||
if (startingPosition == -1)
|
||||
startingPosition = timeScale.getStartingPosition(i);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private FontConfiguration getFontConfiguration(int size) {
|
||||
return getFontConfiguration(size, HColors.BLACK);
|
||||
}
|
||||
|
||||
private FontConfiguration getFontConfiguration(int size, HColor color) {
|
||||
final UFont font = UFont.serif(size);
|
||||
return FontConfiguration.create(font, color, color, null);
|
||||
}
|
||||
|
||||
public double getHeight() {
|
||||
return 16 * 2;
|
||||
}
|
||||
|
||||
public final double getY() {
|
||||
return y;
|
||||
}
|
||||
public double getY();
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,132 @@
|
||||
/* ========================================================================
|
||||
* PlantUML : a free UML diagram generator
|
||||
* ========================================================================
|
||||
*
|
||||
* (C) Copyright 2009-2024, Arnaud Roques
|
||||
*
|
||||
* Project Info: https://plantuml.com
|
||||
*
|
||||
* If you like this project or if you find it useful, you can support us at:
|
||||
*
|
||||
* https://plantuml.com/patreon (only 1$ per month!)
|
||||
* https://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.klimt.UTranslate;
|
||||
import net.sourceforge.plantuml.klimt.color.HColor;
|
||||
import net.sourceforge.plantuml.klimt.color.HColors;
|
||||
import net.sourceforge.plantuml.klimt.creole.Display;
|
||||
import net.sourceforge.plantuml.klimt.drawing.UGraphic;
|
||||
import net.sourceforge.plantuml.klimt.font.FontConfiguration;
|
||||
import net.sourceforge.plantuml.klimt.font.StringBounder;
|
||||
import net.sourceforge.plantuml.klimt.font.UFont;
|
||||
import net.sourceforge.plantuml.klimt.geom.HorizontalAlignment;
|
||||
import net.sourceforge.plantuml.klimt.shape.TextBlock;
|
||||
import net.sourceforge.plantuml.klimt.shape.ULine;
|
||||
import net.sourceforge.plantuml.klimt.sprite.SpriteContainerEmpty;
|
||||
import net.sourceforge.plantuml.project.GanttDiagram;
|
||||
import net.sourceforge.plantuml.project.core.Resource;
|
||||
import net.sourceforge.plantuml.project.time.Day;
|
||||
import net.sourceforge.plantuml.project.timescale.TimeScale;
|
||||
|
||||
public class ResourceDrawBasicImpl implements ResourceDraw {
|
||||
|
||||
private final Resource res;
|
||||
private final TimeScale timeScale;
|
||||
private final double y;
|
||||
private final Day min;
|
||||
private final Day max;
|
||||
private final GanttDiagram gantt;
|
||||
|
||||
public ResourceDrawBasicImpl(GanttDiagram gantt, Resource res, TimeScale timeScale, double y, Day min, Day max) {
|
||||
this.res = res;
|
||||
this.timeScale = timeScale;
|
||||
this.y = y;
|
||||
this.min = min;
|
||||
this.max = max;
|
||||
this.gantt = gantt;
|
||||
}
|
||||
|
||||
public void drawU(UGraphic ug) {
|
||||
final TextBlock title = Display.getWithNewlines(res.getName()).create(getFontConfiguration(13),
|
||||
HorizontalAlignment.LEFT, new SpriteContainerEmpty());
|
||||
title.drawU(ug);
|
||||
final ULine line = ULine.hline(timeScale.getEndingPosition(max) - timeScale.getStartingPosition(min));
|
||||
ug.apply(HColors.BLACK).apply(UTranslate.dy(title.calculateDimension(ug.getStringBounder()).getHeight()))
|
||||
.draw(line);
|
||||
|
||||
double startingPosition = -1;
|
||||
int totalLoad = 0;
|
||||
int totalLimit = 0;
|
||||
for (Day i = min; i.compareTo(max) <= 0; i = i.increment()) {
|
||||
final boolean isBreaking = timeScale.isBreaking(i);
|
||||
totalLoad += gantt.getLoadForResource(res, i);
|
||||
totalLimit += 100;
|
||||
if (isBreaking) {
|
||||
if (totalLoad > 0) {
|
||||
final boolean over = totalLoad > totalLimit;
|
||||
final FontConfiguration fontConfiguration = getFontConfiguration(9,
|
||||
over ? HColors.RED : HColors.BLACK);
|
||||
final TextBlock value = Display.getWithNewlines("" + totalLoad).create(fontConfiguration,
|
||||
HorizontalAlignment.LEFT, new SpriteContainerEmpty());
|
||||
if (startingPosition == -1)
|
||||
startingPosition = timeScale.getStartingPosition(i);
|
||||
final double endingPosition = timeScale.getEndingPosition(i);
|
||||
final double start = (startingPosition + endingPosition) / 2
|
||||
- value.calculateDimension(ug.getStringBounder()).getWidth() / 2;
|
||||
value.drawU(ug.apply(new UTranslate(start, 16)));
|
||||
}
|
||||
startingPosition = -1;
|
||||
totalLoad = 0;
|
||||
totalLimit = 0;
|
||||
} else {
|
||||
if (startingPosition == -1)
|
||||
startingPosition = timeScale.getStartingPosition(i);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private FontConfiguration getFontConfiguration(int size) {
|
||||
return getFontConfiguration(size, HColors.BLACK);
|
||||
}
|
||||
|
||||
private FontConfiguration getFontConfiguration(int size, HColor color) {
|
||||
final UFont font = UFont.serif(size);
|
||||
return FontConfiguration.create(font, color, color, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getHeight(StringBounder stringBounder) {
|
||||
return 16 * 2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final double getY() {
|
||||
return y;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,138 @@
|
||||
/* ========================================================================
|
||||
* PlantUML : a free UML diagram generator
|
||||
* ========================================================================
|
||||
*
|
||||
* (C) Copyright 2009-2024, Arnaud Roques
|
||||
*
|
||||
* Project Info: https://plantuml.com
|
||||
*
|
||||
* If you like this project or if you find it useful, you can support us at:
|
||||
*
|
||||
* https://plantuml.com/patreon (only 1$ per month!)
|
||||
* https://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.klimt.UShape;
|
||||
import net.sourceforge.plantuml.klimt.UTranslate;
|
||||
import net.sourceforge.plantuml.klimt.color.HColor;
|
||||
import net.sourceforge.plantuml.klimt.color.HColors;
|
||||
import net.sourceforge.plantuml.klimt.creole.Display;
|
||||
import net.sourceforge.plantuml.klimt.drawing.UGraphic;
|
||||
import net.sourceforge.plantuml.klimt.font.FontConfiguration;
|
||||
import net.sourceforge.plantuml.klimt.font.StringBounder;
|
||||
import net.sourceforge.plantuml.klimt.font.UFont;
|
||||
import net.sourceforge.plantuml.klimt.geom.HorizontalAlignment;
|
||||
import net.sourceforge.plantuml.klimt.shape.TextBlock;
|
||||
import net.sourceforge.plantuml.klimt.shape.ULine;
|
||||
import net.sourceforge.plantuml.klimt.shape.URectangle;
|
||||
import net.sourceforge.plantuml.klimt.sprite.SpriteContainerEmpty;
|
||||
import net.sourceforge.plantuml.project.GanttDiagram;
|
||||
import net.sourceforge.plantuml.project.LabelPosition;
|
||||
import net.sourceforge.plantuml.project.LabelStrategy;
|
||||
import net.sourceforge.plantuml.project.core.Resource;
|
||||
import net.sourceforge.plantuml.project.time.Day;
|
||||
import net.sourceforge.plantuml.project.timescale.TimeScale;
|
||||
|
||||
public class ResourceDrawVersion2 implements ResourceDraw {
|
||||
|
||||
private final Resource res;
|
||||
private final TimeScale timeScale;
|
||||
private final double y;
|
||||
private final Day min;
|
||||
private final Day max;
|
||||
private final GanttDiagram gantt;
|
||||
|
||||
public ResourceDrawVersion2(GanttDiagram gantt, Resource res, TimeScale timeScale, double y, Day min, Day max) {
|
||||
this.res = res;
|
||||
this.timeScale = timeScale;
|
||||
this.y = y;
|
||||
this.min = min;
|
||||
this.max = max;
|
||||
this.gantt = gantt;
|
||||
}
|
||||
|
||||
public void drawU(UGraphic ug) {
|
||||
final StringBounder stringBounder = ug.getStringBounder();
|
||||
|
||||
double ypos = 16;
|
||||
final double tmpHeight = getHeight(stringBounder) - ypos;
|
||||
for (Day wink = gantt.getStartingDate(); wink.compareTo(gantt.getEndingDate()) <= 0; wink = wink.increment()) {
|
||||
final double start = timeScale.getStartingPosition(wink);
|
||||
final double end = timeScale.getEndingPosition(wink);
|
||||
final UShape rect = URectangle.build(end - start, tmpHeight);
|
||||
if (res.isClosedAt(wink))
|
||||
ug.apply(HColors.LIGHT_GRAY.bg()).apply(new UTranslate(start, ypos)).draw(rect);
|
||||
|
||||
}
|
||||
|
||||
final TextBlock title = Display.getWithNewlines(res.getName()).create(getFontConfiguration(13),
|
||||
HorizontalAlignment.LEFT, new SpriteContainerEmpty());
|
||||
title.drawU(ug);
|
||||
final ULine line = ULine.hline(timeScale.getEndingPosition(max) - timeScale.getStartingPosition(min));
|
||||
ug.apply(HColors.BLACK).apply(UTranslate.dy(title.calculateDimension(ug.getStringBounder()).getHeight()))
|
||||
.draw(line);
|
||||
|
||||
final LabelStrategy labelStrategy = new LabelStrategy(LabelPosition.LEGACY, HorizontalAlignment.LEFT);
|
||||
|
||||
for (TaskDrawRegular draw : gantt.getAllTasksForResource(res)) {
|
||||
draw.drawShape(ug.apply(UTranslate.dy(ypos + getTopMarginBetweenTask())));
|
||||
draw.drawTitle(ug.apply(UTranslate.dy(ypos + getTopMarginBetweenTask())), labelStrategy, 10, 100);
|
||||
ypos += draw.getShapeHeight(stringBounder) + getMarginBetweenTask();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getHeight(StringBounder stringBounder) {
|
||||
double ypos = 16;
|
||||
for (TaskDrawRegular draw : gantt.getAllTasksForResource(res))
|
||||
ypos += draw.getShapeHeight(stringBounder) + getMarginBetweenTask();
|
||||
|
||||
return ypos + 8;
|
||||
}
|
||||
|
||||
private double getTopMarginBetweenTask() {
|
||||
return 2;
|
||||
}
|
||||
|
||||
private double getMarginBetweenTask() {
|
||||
return 4;
|
||||
}
|
||||
|
||||
private FontConfiguration getFontConfiguration(int size) {
|
||||
return getFontConfiguration(size, HColors.BLACK);
|
||||
}
|
||||
|
||||
private FontConfiguration getFontConfiguration(int size, HColor color) {
|
||||
final UFont font = UFont.serif(size);
|
||||
return FontConfiguration.create(font, color, color, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final double getY() {
|
||||
return y;
|
||||
}
|
||||
|
||||
}
|
@ -101,7 +101,7 @@ public class TaskDrawRegular extends AbstractTaskDraw {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected double getShapeHeight(StringBounder stringBounder) {
|
||||
public double getShapeHeight(StringBounder stringBounder) {
|
||||
final Style style = getStyle();
|
||||
final ClockwiseTopRightBottomLeft padding = style.getPadding();
|
||||
return padding.getTop() + getTitle().calculateDimension(stringBounder).getHeight() + padding.getBottom();
|
||||
@ -170,7 +170,6 @@ public class TaskDrawRegular extends AbstractTaskDraw {
|
||||
final double startPos = timeScale.getStartingPosition(start);
|
||||
drawNote(ug.apply((new UTranslate(startPos, getYNotePosition(ug.getStringBounder())))));
|
||||
|
||||
ug = applyColors(ug);
|
||||
drawShape(ug);
|
||||
}
|
||||
|
||||
@ -256,7 +255,8 @@ public class TaskDrawRegular extends AbstractTaskDraw {
|
||||
return endPos;
|
||||
}
|
||||
|
||||
private void drawShape(UGraphic ug) {
|
||||
public void drawShape(UGraphic ug) {
|
||||
ug = applyColors(ug);
|
||||
final Style style = getStyleSignature().getMergedStyle(getStyleBuilder());
|
||||
final ClockwiseTopRightBottomLeft margin = style.getMargin();
|
||||
|
||||
|
@ -35,12 +35,8 @@
|
||||
*/
|
||||
package net.sourceforge.plantuml.project.draw;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
import net.sourceforge.plantuml.klimt.UStroke;
|
||||
import net.sourceforge.plantuml.klimt.UTranslate;
|
||||
import net.sourceforge.plantuml.klimt.color.HColor;
|
||||
import net.sourceforge.plantuml.klimt.color.HColorSet;
|
||||
import net.sourceforge.plantuml.klimt.color.HColors;
|
||||
import net.sourceforge.plantuml.klimt.creole.Display;
|
||||
import net.sourceforge.plantuml.klimt.drawing.UGraphic;
|
||||
@ -51,10 +47,10 @@ import net.sourceforge.plantuml.klimt.shape.TextBlock;
|
||||
import net.sourceforge.plantuml.klimt.shape.ULine;
|
||||
import net.sourceforge.plantuml.klimt.shape.URectangle;
|
||||
import net.sourceforge.plantuml.klimt.sprite.SpriteContainerEmpty;
|
||||
import net.sourceforge.plantuml.project.TimeHeaderParameters;
|
||||
import net.sourceforge.plantuml.project.time.Day;
|
||||
import net.sourceforge.plantuml.project.timescale.TimeScale;
|
||||
import net.sourceforge.plantuml.style.PName;
|
||||
import net.sourceforge.plantuml.style.Style;
|
||||
|
||||
public abstract class TimeHeader {
|
||||
// ::remove folder when __HAXE__
|
||||
@ -68,38 +64,40 @@ public abstract class TimeHeader {
|
||||
}
|
||||
|
||||
private final TimeScale timeScale;
|
||||
private final Style closedStyle;
|
||||
private final Style timelineStyle;
|
||||
|
||||
private final HColorSet colorSet;
|
||||
protected final TimeHeaderParameters thParam;
|
||||
|
||||
protected final Day min;
|
||||
protected final Day max;
|
||||
|
||||
public TimeHeader(Style timelineStyle, Style closedStyle, Day min, Day max, TimeScale timeScale,
|
||||
HColorSet colorSet) {
|
||||
public TimeHeader(TimeHeaderParameters thParam, TimeScale timeScale) {
|
||||
this.thParam = thParam;
|
||||
this.timeScale = timeScale;
|
||||
this.min = min;
|
||||
this.max = max;
|
||||
this.closedStyle = Objects.requireNonNull(closedStyle);
|
||||
this.timelineStyle = Objects.requireNonNull(timelineStyle);
|
||||
this.colorSet = colorSet;
|
||||
}
|
||||
|
||||
protected final boolean isBold2(Day wink) {
|
||||
return thParam.getVerticalSeparatorBefore().contains(wink);
|
||||
}
|
||||
|
||||
protected final Day getMin() {
|
||||
return thParam.getMin();
|
||||
}
|
||||
|
||||
protected final Day getMax() {
|
||||
return thParam.getMax();
|
||||
}
|
||||
|
||||
protected final HColor closedBackgroundColor() {
|
||||
return closedStyle.value(PName.BackGroundColor).asColor(colorSet);
|
||||
return thParam.getClosedStyle().value(PName.BackGroundColor).asColor(thParam.getColorSet());
|
||||
}
|
||||
|
||||
protected final HColor closedFontColor() {
|
||||
return closedStyle.value(PName.FontColor).asColor(colorSet);
|
||||
return thParam.getClosedStyle().value(PName.FontColor).asColor(thParam.getColorSet());
|
||||
}
|
||||
|
||||
protected final HColor openFontColor() {
|
||||
return timelineStyle.value(PName.FontColor).asColor(colorSet);
|
||||
return thParam.getTimelineStyle().value(PName.FontColor).asColor(thParam.getColorSet());
|
||||
}
|
||||
|
||||
protected final HColor getBarColor() {
|
||||
return timelineStyle.value(PName.LineColor).asColor(colorSet);
|
||||
protected final HColor getLineColor() {
|
||||
return thParam.getTimelineStyle().value(PName.LineColor).asColor(thParam.getColorSet());
|
||||
}
|
||||
|
||||
public abstract double getTimeHeaderHeight();
|
||||
@ -113,18 +111,14 @@ public abstract class TimeHeader {
|
||||
public abstract double getFullHeaderHeight();
|
||||
|
||||
protected final void drawHline(UGraphic ug, double y) {
|
||||
final double xmin = getTimeScale().getStartingPosition(min);
|
||||
final double xmax = getTimeScale().getEndingPosition(max);
|
||||
final double xmin = getTimeScale().getStartingPosition(thParam.getMin());
|
||||
final double xmax = getTimeScale().getEndingPosition(thParam.getMax());
|
||||
final ULine hline = ULine.hline(xmax - xmin);
|
||||
ug.apply(getBarColor()).apply(UTranslate.dy(y)).draw(hline);
|
||||
ug.apply(getLineColor()).apply(UTranslate.dy(y)).draw(hline);
|
||||
}
|
||||
|
||||
protected final void drawVbar(UGraphic ug, double x, double y1, double y2, boolean bold) {
|
||||
protected final void drawVline(UGraphic ug, double x, double y1, double y2) {
|
||||
final ULine vbar = ULine.vline(y2 - y1);
|
||||
if (bold)
|
||||
ug = goBold(ug);
|
||||
else
|
||||
ug = ug.apply(getBarColor());
|
||||
ug.apply(new UTranslate(x, y1)).draw(vbar);
|
||||
}
|
||||
|
||||
@ -175,8 +169,12 @@ public abstract class TimeHeader {
|
||||
ug.draw(URectangle.build(x2 - x1, height));
|
||||
}
|
||||
|
||||
protected final UGraphic goBold(UGraphic ug) {
|
||||
return ug.apply(HColors.BLACK).apply(UStroke.withThickness(2));
|
||||
protected void printVerticalSeparators(UGraphic ug, double totalHeightWithoutFooter) {
|
||||
ug = thParam.forVerticalSeparator(ug);
|
||||
for (Day wink = getMin(); wink.compareTo(getMax()) <= 0; wink = wink.increment())
|
||||
if (isBold2(wink))
|
||||
drawVline(ug, getTimeScale().getStartingPosition(wink), getFullHeaderHeight(),
|
||||
totalHeightWithoutFooter);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -45,16 +45,8 @@ import net.sourceforge.plantuml.project.timescale.TimeScale;
|
||||
|
||||
public abstract class TimeHeaderCalendar extends TimeHeader {
|
||||
|
||||
private final TimeHeaderParameters thParam;
|
||||
|
||||
public TimeHeaderCalendar(TimeHeaderParameters thParam, TimeScale timeScale) {
|
||||
super(thParam.getTimelineStyle(), thParam.getClosedStyle(), thParam.getMin(), thParam.getMax(), timeScale,
|
||||
thParam.getColorSet());
|
||||
this.thParam = thParam;
|
||||
}
|
||||
|
||||
protected final boolean isBold(Day wink) {
|
||||
return thParam.getVerticalSeparatorBefore().contains(wink);
|
||||
super(thParam, timeScale);
|
||||
}
|
||||
|
||||
protected final Locale locale() {
|
||||
@ -87,7 +79,7 @@ public abstract class TimeHeaderCalendar extends TimeHeader {
|
||||
final double height = totalHeightWithoutFooter - getFullHeaderHeight();
|
||||
Pending pending = null;
|
||||
|
||||
for (Day wink = min; wink.compareTo(max) <= 0; wink = wink.increment()) {
|
||||
for (Day wink = getMin(); wink.compareTo(getMax()) <= 0; wink = wink.increment()) {
|
||||
final double x1 = getTimeScale().getStartingPosition(wink);
|
||||
final double x2 = getTimeScale().getEndingPosition(wink);
|
||||
HColor back = thParam.getColor(wink);
|
||||
|
@ -70,7 +70,7 @@ public class TimeHeaderDaily extends TimeHeaderCalendar {
|
||||
drawTextsDayOfWeek(ug.apply(UTranslate.dy(Y_POS_ROW16())));
|
||||
drawTextDayOfMonth(ug.apply(UTranslate.dy(Y_POS_ROW28())));
|
||||
drawMonths(ug);
|
||||
printSmallVbars(ug, totalHeightWithoutFooter);
|
||||
printVerticalSeparators(ug, totalHeightWithoutFooter);
|
||||
|
||||
printNamedDays(ug);
|
||||
|
||||
@ -78,12 +78,20 @@ public class TimeHeaderDaily extends TimeHeaderCalendar {
|
||||
drawHline(ug, totalHeightWithoutFooter);
|
||||
}
|
||||
|
||||
private void printSmallVbars(final UGraphic ug, double totalHeightWithoutFooter) {
|
||||
for (Day wink = min; wink.compareTo(max) <= 0; wink = wink.increment())
|
||||
drawVbar(ug, getTimeScale().getStartingPosition(wink), getFullHeaderHeight(), totalHeightWithoutFooter,
|
||||
isBold(wink));
|
||||
@Override
|
||||
protected void printVerticalSeparators(final UGraphic ug, double totalHeightWithoutFooter) {
|
||||
final UGraphic ugVerticalSeparator = thParam.forVerticalSeparator(ug);
|
||||
final UGraphic ugLineColor = ug.apply(getLineColor());
|
||||
for (Day wink = getMin(); wink.compareTo(getMax()) <= 0; wink = wink.increment())
|
||||
if (isBold2(wink))
|
||||
drawVline(ugVerticalSeparator, getTimeScale().getStartingPosition(wink), getFullHeaderHeight(),
|
||||
totalHeightWithoutFooter);
|
||||
else
|
||||
drawVline(ugLineColor, getTimeScale().getStartingPosition(wink), getFullHeaderHeight(),
|
||||
totalHeightWithoutFooter);
|
||||
|
||||
drawVbar(ug, getTimeScale().getEndingPosition(max), getFullHeaderHeight(), totalHeightWithoutFooter, false);
|
||||
drawVline(ugLineColor, getTimeScale().getEndingPosition(getMax()), getFullHeaderHeight(),
|
||||
totalHeightWithoutFooter);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -94,7 +102,7 @@ public class TimeHeaderDaily extends TimeHeaderCalendar {
|
||||
}
|
||||
|
||||
private void drawTextsDayOfWeek(UGraphic ug) {
|
||||
for (Day wink = min; wink.compareTo(max) <= 0; wink = wink.increment()) {
|
||||
for (Day wink = getMin(); wink.compareTo(getMax()) <= 0; wink = wink.increment()) {
|
||||
final double x1 = getTimeScale().getStartingPosition(wink);
|
||||
final double x2 = getTimeScale().getEndingPosition(wink);
|
||||
final HColor textColor = getTextBackColor(wink);
|
||||
@ -103,7 +111,7 @@ public class TimeHeaderDaily extends TimeHeaderCalendar {
|
||||
}
|
||||
|
||||
private void drawTextDayOfMonth(UGraphic ug) {
|
||||
for (Day wink = min; wink.compareTo(max) <= 0; wink = wink.increment()) {
|
||||
for (Day wink = getMin(); wink.compareTo(getMax()) <= 0; wink = wink.increment()) {
|
||||
final double x1 = getTimeScale().getStartingPosition(wink);
|
||||
final double x2 = getTimeScale().getEndingPosition(wink);
|
||||
final HColor textColor = getTextBackColor(wink);
|
||||
@ -121,7 +129,7 @@ public class TimeHeaderDaily extends TimeHeaderCalendar {
|
||||
private void drawMonths(final UGraphic ug) {
|
||||
MonthYear last = null;
|
||||
double lastChangeMonth = -1;
|
||||
for (Day wink = min; wink.compareTo(max) <= 0; wink = wink.increment()) {
|
||||
for (Day wink = getMin(); wink.compareTo(getMax()) <= 0; wink = wink.increment()) {
|
||||
final double x1 = getTimeScale().getStartingPosition(wink);
|
||||
if (wink.monthYear().equals(last) == false) {
|
||||
if (last != null)
|
||||
@ -131,7 +139,7 @@ public class TimeHeaderDaily extends TimeHeaderCalendar {
|
||||
last = wink.monthYear();
|
||||
}
|
||||
}
|
||||
final double x1 = getTimeScale().getStartingPosition(max.increment());
|
||||
final double x1 = getTimeScale().getStartingPosition(getMax().increment());
|
||||
if (x1 > lastChangeMonth)
|
||||
printMonth(ug, last, lastChangeMonth, x1);
|
||||
|
||||
@ -147,7 +155,7 @@ public class TimeHeaderDaily extends TimeHeaderCalendar {
|
||||
private void printNamedDays(final UGraphic ug) {
|
||||
if (nameDays.size() > 0) {
|
||||
String last = null;
|
||||
for (Day wink = min; wink.compareTo(max.increment()) <= 0; wink = wink.increment()) {
|
||||
for (Day wink = getMin(); wink.compareTo(getMax().increment()) <= 0; wink = wink.increment()) {
|
||||
final String name = nameDays.get(wink);
|
||||
if (name != null && name.equals(last) == false) {
|
||||
final double x1 = getTimeScale().getStartingPosition(wink);
|
||||
|
@ -62,19 +62,12 @@ public class TimeHeaderMonthly extends TimeHeaderCalendar {
|
||||
drawTextsBackground(ug, totalHeightWithoutFooter);
|
||||
drawYears(ug);
|
||||
drawMonths(ug.apply(UTranslate.dy(16)));
|
||||
printSmallVbars(ug, totalHeightWithoutFooter);
|
||||
printVerticalSeparators(ug, totalHeightWithoutFooter);
|
||||
drawHline(ug, 0);
|
||||
drawHline(ug, 16);
|
||||
drawHline(ug, getFullHeaderHeight());
|
||||
}
|
||||
|
||||
private void printSmallVbars(final UGraphic ug, double totalHeightWithoutFooter) {
|
||||
for (Day wink = min; wink.compareTo(max) <= 0; wink = wink.increment())
|
||||
if (isBold(wink))
|
||||
drawVbar(ug, getTimeScale().getStartingPosition(wink), getFullHeaderHeight(), totalHeightWithoutFooter,
|
||||
isBold(wink));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawTimeFooter(UGraphic ug) {
|
||||
ug = ug.apply(UTranslate.dy(3));
|
||||
@ -88,43 +81,43 @@ public class TimeHeaderMonthly extends TimeHeaderCalendar {
|
||||
private void drawYears(final UGraphic ug) {
|
||||
MonthYear last = null;
|
||||
double lastChange = -1;
|
||||
for (Day wink = min; wink.compareTo(max) < 0; wink = wink.increment()) {
|
||||
for (Day wink = getMin(); wink.compareTo(getMax()) < 0; wink = wink.increment()) {
|
||||
final double x1 = getTimeScale().getStartingPosition(wink);
|
||||
if (last == null || wink.monthYear().year() != last.year()) {
|
||||
drawVbar(ug, x1, 0, 15, false);
|
||||
if (last != null) {
|
||||
drawVline(ug.apply(getLineColor()), x1, 0, 15);
|
||||
if (last != null)
|
||||
printYear(ug, last, lastChange, x1);
|
||||
}
|
||||
|
||||
lastChange = x1;
|
||||
last = wink.monthYear();
|
||||
}
|
||||
}
|
||||
final double x1 = getTimeScale().getStartingPosition(max.increment());
|
||||
if (x1 > lastChange) {
|
||||
final double x1 = getTimeScale().getStartingPosition(getMax().increment());
|
||||
if (x1 > lastChange)
|
||||
printYear(ug, last, lastChange, x1);
|
||||
}
|
||||
drawVbar(ug, getTimeScale().getEndingPosition(max), 0, 15, false);
|
||||
|
||||
drawVline(ug.apply(getLineColor()), getTimeScale().getEndingPosition(getMax()), (double) 0, (double) 15);
|
||||
}
|
||||
|
||||
private void drawMonths(UGraphic ug) {
|
||||
MonthYear last = null;
|
||||
double lastChange = -1;
|
||||
for (Day wink = min; wink.compareTo(max) < 0; wink = wink.increment()) {
|
||||
for (Day wink = getMin(); wink.compareTo(getMax()) < 0; wink = wink.increment()) {
|
||||
final double x1 = getTimeScale().getStartingPosition(wink);
|
||||
if (wink.monthYear().equals(last) == false) {
|
||||
drawVbar(ug, x1, 0, 12, false);
|
||||
if (last != null) {
|
||||
drawVline(ug.apply(getLineColor()), x1, (double) 0, (double) 12);
|
||||
if (last != null)
|
||||
printMonth(ug, last, lastChange, x1);
|
||||
}
|
||||
|
||||
lastChange = x1;
|
||||
last = wink.monthYear();
|
||||
}
|
||||
}
|
||||
final double x1 = getTimeScale().getStartingPosition(max.increment());
|
||||
if (x1 > lastChange) {
|
||||
final double x1 = getTimeScale().getStartingPosition(getMax().increment());
|
||||
if (x1 > lastChange)
|
||||
printMonth(ug, last, lastChange, x1);
|
||||
}
|
||||
drawVbar(ug, getTimeScale().getEndingPosition(max), 0, 12, false);
|
||||
|
||||
drawVline(ug.apply(getLineColor()), getTimeScale().getEndingPosition(getMax()), (double) 0, (double) 12);
|
||||
}
|
||||
|
||||
private void printYear(UGraphic ug, MonthYear monthYear, double start, double end) {
|
||||
|
@ -62,19 +62,12 @@ public class TimeHeaderQuarterly extends TimeHeaderCalendar {
|
||||
drawTextsBackground(ug, totalHeightWithoutFooter);
|
||||
drawYears(ug);
|
||||
drawQuarters(ug.apply(UTranslate.dy(16)));
|
||||
printSmallVbars(ug, totalHeightWithoutFooter);
|
||||
printVerticalSeparators(ug, totalHeightWithoutFooter);
|
||||
drawHline(ug, 0);
|
||||
drawHline(ug, 16);
|
||||
drawHline(ug, getFullHeaderHeight());
|
||||
}
|
||||
|
||||
private void printSmallVbars(final UGraphic ug, double totalHeightWithoutFooter) {
|
||||
for (Day wink = min; wink.compareTo(max) <= 0; wink = wink.increment())
|
||||
if (isBold(wink))
|
||||
drawVbar(ug, getTimeScale().getStartingPosition(wink), getFullHeaderHeight(), totalHeightWithoutFooter,
|
||||
isBold(wink));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawTimeFooter(UGraphic ug) {
|
||||
ug = ug.apply(UTranslate.dy(3));
|
||||
@ -88,43 +81,43 @@ public class TimeHeaderQuarterly extends TimeHeaderCalendar {
|
||||
private void drawYears(final UGraphic ug) {
|
||||
MonthYear last = null;
|
||||
double lastChange = -1;
|
||||
for (Day wink = min; wink.compareTo(max) < 0; wink = wink.increment()) {
|
||||
for (Day wink = getMin(); wink.compareTo(getMax()) < 0; wink = wink.increment()) {
|
||||
final double x1 = getTimeScale().getStartingPosition(wink);
|
||||
if (last == null || wink.monthYear().year() != last.year()) {
|
||||
drawVbar(ug, x1, 0, 15, false);
|
||||
if (last != null) {
|
||||
drawVline(ug.apply(getLineColor()), x1, (double) 0, (double) 15);
|
||||
if (last != null)
|
||||
printYear(ug, last, lastChange, x1);
|
||||
}
|
||||
|
||||
lastChange = x1;
|
||||
last = wink.monthYear();
|
||||
}
|
||||
}
|
||||
final double x1 = getTimeScale().getStartingPosition(max.increment());
|
||||
if (x1 > lastChange) {
|
||||
final double x1 = getTimeScale().getStartingPosition(getMax().increment());
|
||||
if (x1 > lastChange)
|
||||
printYear(ug, last, lastChange, x1);
|
||||
}
|
||||
drawVbar(ug, getTimeScale().getEndingPosition(max), 0, 15, false);
|
||||
|
||||
drawVline(ug.apply(getLineColor()), getTimeScale().getEndingPosition(getMax()), (double) 0, (double) 15);
|
||||
}
|
||||
|
||||
private void drawQuarters(UGraphic ug) {
|
||||
String last = null;
|
||||
double lastChange = -1;
|
||||
for (Day wink = min; wink.compareTo(max) < 0; wink = wink.increment()) {
|
||||
for (Day wink = getMin(); wink.compareTo(getMax()) < 0; wink = wink.increment()) {
|
||||
final double x1 = getTimeScale().getStartingPosition(wink);
|
||||
if (quarter(wink).equals(last) == false) {
|
||||
drawVbar(ug, x1, 0, 12, false);
|
||||
if (last != null) {
|
||||
drawVline(ug.apply(getLineColor()), x1, (double) 0, (double) 12);
|
||||
if (last != null)
|
||||
printQuarter(ug, last, lastChange, x1);
|
||||
}
|
||||
|
||||
lastChange = x1;
|
||||
last = quarter(wink);
|
||||
}
|
||||
}
|
||||
final double x1 = getTimeScale().getStartingPosition(max.increment());
|
||||
if (x1 > lastChange) {
|
||||
final double x1 = getTimeScale().getStartingPosition(getMax().increment());
|
||||
if (x1 > lastChange)
|
||||
printQuarter(ug, last, lastChange, x1);
|
||||
}
|
||||
drawVbar(ug, getTimeScale().getEndingPosition(max), 0, 12, false);
|
||||
|
||||
drawVline(ug.apply(getLineColor()), getTimeScale().getEndingPosition(getMax()), (double) 0, (double) 12);
|
||||
}
|
||||
|
||||
private String quarter(Day day) {
|
||||
|
@ -35,8 +35,6 @@
|
||||
*/
|
||||
package net.sourceforge.plantuml.project.draw;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import net.sourceforge.plantuml.klimt.UTranslate;
|
||||
import net.sourceforge.plantuml.klimt.color.HColor;
|
||||
import net.sourceforge.plantuml.klimt.creole.Display;
|
||||
@ -53,9 +51,7 @@ import net.sourceforge.plantuml.project.timescale.TimeScaleWink;
|
||||
|
||||
public class TimeHeaderSimple extends TimeHeader {
|
||||
|
||||
private final TimeHeaderParameters colorDays;
|
||||
private final PrintScale printScale;
|
||||
private final Set<Day> verticalSeparators;
|
||||
|
||||
@Override
|
||||
public double getFullHeaderHeight() {
|
||||
@ -75,37 +71,21 @@ public class TimeHeaderSimple extends TimeHeader {
|
||||
}
|
||||
|
||||
public TimeHeaderSimple(TimeHeaderParameters thParam, PrintScale printScale) {
|
||||
super(thParam.getTimelineStyle(), thParam.getClosedStyle(), thParam.getMin(), thParam.getMax(),
|
||||
new TimeScaleWink(thParam.getScale(), printScale), thParam.getColorSet());
|
||||
this.colorDays = thParam;
|
||||
super(thParam, new TimeScaleWink(thParam.getScale(), 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)) {
|
||||
private void drawSmallVlinesDay(UGraphic ug, TimeScale timeScale, double totalHeightWithoutFooter) {
|
||||
ug = ug.apply(getLineColor());
|
||||
final ULine vbar = ULine.vline(totalHeightWithoutFooter);
|
||||
for (Day i = getMin(); i.compareTo(getMax().increment()) <= 0; i = i.increment(printScale)) {
|
||||
final double x1 = timeScale.getStartingPosition(i);
|
||||
ug.apply(UTranslate.dx(x1)).draw(vbar);
|
||||
}
|
||||
}
|
||||
|
||||
private void drawSmallVlinesDay(UGraphic ug, TimeScale timeScale, double totalHeightWithoutFooter) {
|
||||
final ULine vbar = ULine.vline(totalHeightWithoutFooter);
|
||||
for (Day i = min; i.compareTo(max.increment()) <= 0; i = i.increment(printScale)) {
|
||||
final double x1 = timeScale.getStartingPosition(i);
|
||||
ug.apply(getBarColor()).apply(UTranslate.dx(x1)).draw(vbar);
|
||||
}
|
||||
}
|
||||
|
||||
private void drawSimpleDayCounter(UGraphic ug, TimeScale timeScale) {
|
||||
for (Day i = min; i.compareTo(max.increment()) <= 0; i = i.increment(printScale)) {
|
||||
for (Day i = getMin(); i.compareTo(getMax().increment()) <= 0; i = i.increment(printScale)) {
|
||||
final int value;
|
||||
if (printScale == PrintScale.WEEKLY)
|
||||
value = i.getAbsoluteDayNum() / 7 + 1;
|
||||
@ -122,33 +102,34 @@ public class TimeHeaderSimple extends TimeHeader {
|
||||
x2 = timeScale.getEndingPosition(i);
|
||||
final double width = num.calculateDimension(ug.getStringBounder()).getWidth();
|
||||
final double delta = (x2 - x1) - width;
|
||||
if (i.compareTo(max.increment()) < 0)
|
||||
if (i.compareTo(getMax().increment()) < 0)
|
||||
num.drawU(ug.apply(UTranslate.dx(x1 + delta / 2)));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawTimeHeader(final UGraphic ug, double totalHeightWithoutFooter) {
|
||||
public void drawTimeHeader(UGraphic ug, double totalHeightWithoutFooter) {
|
||||
drawTextsBackground(ug.apply(UTranslate.dy(-3)), totalHeightWithoutFooter + 6);
|
||||
final double xmin = getTimeScale().getStartingPosition(min);
|
||||
final double xmax = getTimeScale().getEndingPosition(max);
|
||||
final double xmin = getTimeScale().getStartingPosition(getMin());
|
||||
final double xmax = getTimeScale().getEndingPosition(getMax());
|
||||
drawSmallVlinesDay(ug, getTimeScale(), totalHeightWithoutFooter + 2);
|
||||
drawSeparatorsDay(ug, getTimeScale(), totalHeightWithoutFooter);
|
||||
printVerticalSeparators(ug, totalHeightWithoutFooter);
|
||||
drawSimpleDayCounter(ug, getTimeScale());
|
||||
ug.apply(getBarColor()).draw(ULine.hline(xmax - xmin));
|
||||
ug.apply(getBarColor()).apply(UTranslate.dy(getFullHeaderHeight() - 3)).draw(ULine.hline(xmax - xmin));
|
||||
ug = ug.apply(getLineColor());
|
||||
ug.draw(ULine.hline(xmax - xmin));
|
||||
ug.apply(UTranslate.dy(getFullHeaderHeight() - 3)).draw(ULine.hline(xmax - xmin));
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawTimeFooter(UGraphic ug) {
|
||||
final double xmin = getTimeScale().getStartingPosition(min);
|
||||
final double xmax = getTimeScale().getEndingPosition(max);
|
||||
final double xmin = getTimeScale().getStartingPosition(getMin());
|
||||
final double xmax = getTimeScale().getEndingPosition(getMax());
|
||||
ug = ug.apply(UTranslate.dy(3));
|
||||
drawSmallVlinesDay(ug, getTimeScale(), getTimeFooterHeight() - 3);
|
||||
drawSimpleDayCounter(ug, getTimeScale());
|
||||
ug.apply(getBarColor()).draw(ULine.hline(xmax - xmin));
|
||||
ug.apply(getLineColor()).draw(ULine.hline(xmax - xmin));
|
||||
}
|
||||
|
||||
// Duplicate in TimeHeaderDaily
|
||||
@ -173,10 +154,10 @@ public class TimeHeaderSimple extends TimeHeader {
|
||||
final double height = totalHeightWithoutFooter - getFullHeaderHeight();
|
||||
Pending pending = null;
|
||||
|
||||
for (Day wink = min; wink.compareTo(max) <= 0; wink = wink.increment()) {
|
||||
for (Day wink = getMin(); wink.compareTo(getMax()) <= 0; wink = wink.increment()) {
|
||||
final double x1 = getTimeScale().getStartingPosition(wink);
|
||||
final double x2 = getTimeScale().getEndingPosition(wink);
|
||||
HColor back = colorDays.getColor(wink);
|
||||
HColor back = thParam.getColor(wink);
|
||||
// // Day of week should be stronger than period of time (back color).
|
||||
// final HColor backDoW = colorDaysOfWeek.get(wink.getDayOfWeek());
|
||||
// if (backDoW != null) {
|
||||
|
@ -82,47 +82,43 @@ public class TimeHeaderWeekly extends TimeHeaderCalendar {
|
||||
|
||||
private void drawCalendar(final UGraphic ug, double totalHeightWithoutFooter) {
|
||||
printDaysOfMonth(ug);
|
||||
printSmallVbars(ug, totalHeightWithoutFooter);
|
||||
printVerticalSeparators(ug, totalHeightWithoutFooter);
|
||||
printMonths(ug);
|
||||
}
|
||||
|
||||
private void printMonths(final UGraphic ug) {
|
||||
MonthYear last = null;
|
||||
double lastChangeMonth = -1;
|
||||
for (Day wink = min; wink.compareTo(max) < 0; wink = wink.increment()) {
|
||||
for (Day wink = getMin(); wink.compareTo(getMax()) < 0; wink = wink.increment()) {
|
||||
final double x1 = getTimeScale().getStartingPosition(wink);
|
||||
if (wink.monthYear().equals(last) == false) {
|
||||
drawVbar(ug, x1, 0, Y_POS_ROW16(), false);
|
||||
if (last != null) {
|
||||
drawVline(ug.apply(getLineColor()), x1, (double) 0, Y_POS_ROW16());
|
||||
if (last != null)
|
||||
printMonth(ug, last, lastChangeMonth, x1);
|
||||
}
|
||||
|
||||
lastChangeMonth = x1;
|
||||
last = wink.monthYear();
|
||||
}
|
||||
}
|
||||
drawVbar(ug, getTimeScale().getEndingPosition(max), 0, Y_POS_ROW16(), false);
|
||||
final double x1 = getTimeScale().getStartingPosition(max.increment());
|
||||
if (x1 > lastChangeMonth) {
|
||||
drawVline(ug.apply(getLineColor()), getTimeScale().getEndingPosition(getMax()), (double) 0, Y_POS_ROW16());
|
||||
final double x1 = getTimeScale().getStartingPosition(getMax().increment());
|
||||
if (x1 > lastChangeMonth)
|
||||
printMonth(ug, last, lastChangeMonth, x1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void printSmallVbars(final UGraphic ug, double totalHeightWithoutFooter) {
|
||||
for (Day wink = min; wink.compareTo(max) <= 0; wink = wink.increment())
|
||||
@Override
|
||||
protected void printVerticalSeparators(final UGraphic ug, double totalHeightWithoutFooter) {
|
||||
for (Day wink = getMin(); wink.compareTo(getMax()) <= 0; wink = wink.increment())
|
||||
if (wink.getDayOfWeek() == weekNumberStrategy.getFirstDayOfWeek())
|
||||
drawVbar(ug, getTimeScale().getStartingPosition(wink), Y_POS_ROW16(), totalHeightWithoutFooter, false);
|
||||
|
||||
drawVbar(ug, getTimeScale().getEndingPosition(max), Y_POS_ROW16(), totalHeightWithoutFooter, false);
|
||||
|
||||
for (Day wink = min; wink.compareTo(max) <= 0; wink = wink.increment())
|
||||
if (isBold(wink))
|
||||
drawVbar(ug, getTimeScale().getStartingPosition(wink), getFullHeaderHeight(), totalHeightWithoutFooter,
|
||||
isBold(wink));
|
||||
drawVline(ug.apply(getLineColor()), getTimeScale().getStartingPosition(wink), Y_POS_ROW16(), totalHeightWithoutFooter);
|
||||
|
||||
drawVline(ug.apply(getLineColor()), getTimeScale().getEndingPosition(getMax()), Y_POS_ROW16(), totalHeightWithoutFooter);
|
||||
super.printVerticalSeparators(ug, totalHeightWithoutFooter);
|
||||
}
|
||||
|
||||
private void printDaysOfMonth(final UGraphic ug) {
|
||||
for (Day wink = min; wink.compareTo(max) < 0; wink = wink.increment()) {
|
||||
for (Day wink = getMin(); wink.compareTo(getMax()) < 0; wink = wink.increment()) {
|
||||
if (wink.getDayOfWeek() == weekNumberStrategy.getFirstDayOfWeek()) {
|
||||
final String num;
|
||||
if (withCalendarDate)
|
||||
|
@ -61,18 +61,11 @@ public class TimeHeaderYearly extends TimeHeaderCalendar {
|
||||
public void drawTimeHeader(final UGraphic ug, double totalHeightWithoutFooter) {
|
||||
drawTextsBackground(ug, totalHeightWithoutFooter);
|
||||
drawYears(ug);
|
||||
printSmallVbars(ug, totalHeightWithoutFooter);
|
||||
printVerticalSeparators(ug, totalHeightWithoutFooter);
|
||||
drawHline(ug, 0);
|
||||
drawHline(ug, getFullHeaderHeight());
|
||||
}
|
||||
|
||||
private void printSmallVbars(final UGraphic ug, double totalHeightWithoutFooter) {
|
||||
for (Day wink = min; wink.compareTo(max) <= 0; wink = wink.increment())
|
||||
if (isBold(wink))
|
||||
drawVbar(ug, getTimeScale().getStartingPosition(wink), getFullHeaderHeight(), totalHeightWithoutFooter,
|
||||
isBold(wink));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawTimeFooter(UGraphic ug) {
|
||||
ug = ug.apply(UTranslate.dy(3));
|
||||
@ -84,22 +77,22 @@ public class TimeHeaderYearly extends TimeHeaderCalendar {
|
||||
private void drawYears(final UGraphic ug) {
|
||||
MonthYear last = null;
|
||||
double lastChange = -1;
|
||||
for (Day wink = min; wink.compareTo(max) < 0; wink = wink.increment()) {
|
||||
for (Day wink = getMin(); wink.compareTo(getMax()) < 0; wink = wink.increment()) {
|
||||
final double x1 = getTimeScale().getStartingPosition(wink);
|
||||
if (last == null || wink.monthYear().year() != last.year()) {
|
||||
drawVbar(ug, x1, 0, 19, false);
|
||||
if (last != null) {
|
||||
drawVline(ug.apply(getLineColor()), x1, (double) 0, (double) 19);
|
||||
if (last != null)
|
||||
printYear(ug, last, lastChange, x1);
|
||||
}
|
||||
|
||||
lastChange = x1;
|
||||
last = wink.monthYear();
|
||||
}
|
||||
}
|
||||
final double x1 = getTimeScale().getStartingPosition(max.increment());
|
||||
if (x1 > lastChange) {
|
||||
final double x1 = getTimeScale().getStartingPosition(getMax().increment());
|
||||
if (x1 > lastChange)
|
||||
printYear(ug, last, lastChange, x1);
|
||||
}
|
||||
drawVbar(ug, getTimeScale().getEndingPosition(max), 0, 19, false);
|
||||
|
||||
drawVline(ug.apply(getLineColor()), getTimeScale().getEndingPosition(getMax()), (double) 0, (double) 19);
|
||||
}
|
||||
|
||||
private void printYear(UGraphic ug, MonthYear monthYear, double start, double end) {
|
||||
|
@ -47,7 +47,35 @@ import net.sourceforge.plantuml.regex.RegexResult;
|
||||
|
||||
public class ComplementDate implements Something {
|
||||
|
||||
private final Type type;
|
||||
|
||||
static enum Type {
|
||||
ANY, ONLY_RELATIVE, ONLY_ABSOLUTE;
|
||||
}
|
||||
|
||||
private ComplementDate(Type type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public static ComplementDate any() {
|
||||
return new ComplementDate(Type.ANY);
|
||||
}
|
||||
|
||||
public static ComplementDate onlyRelative() {
|
||||
return new ComplementDate(Type.ONLY_RELATIVE);
|
||||
}
|
||||
|
||||
public static ComplementDate onlyAbsolute() {
|
||||
return new ComplementDate(Type.ONLY_ABSOLUTE);
|
||||
}
|
||||
|
||||
public IRegex toRegex(String suffix) {
|
||||
switch (type) {
|
||||
case ONLY_ABSOLUTE:
|
||||
return new RegexOr(toRegexA(suffix), toRegexB(suffix), toRegexC(suffix));
|
||||
case ONLY_RELATIVE:
|
||||
return new RegexOr(toRegexD(suffix), toRegexE(suffix));
|
||||
}
|
||||
return new RegexOr(toRegexA(suffix), toRegexB(suffix), toRegexC(suffix), toRegexD(suffix), toRegexE(suffix));
|
||||
}
|
||||
|
||||
@ -98,21 +126,21 @@ public class ComplementDate implements Something {
|
||||
}
|
||||
|
||||
public Failable<Day> getMe(GanttDiagram system, RegexResult arg, String suffix) {
|
||||
if (arg.get("ADAY" + suffix, 0) != null) {
|
||||
if (arg.get("ADAY" + suffix, 0) != null)
|
||||
return Failable.ok(resultA(arg, suffix));
|
||||
}
|
||||
if (arg.get("BDAY" + suffix, 0) != null) {
|
||||
|
||||
if (arg.get("BDAY" + suffix, 0) != null)
|
||||
return Failable.ok(resultB(arg, suffix));
|
||||
}
|
||||
if (arg.get("CDAY" + suffix, 0) != null) {
|
||||
|
||||
if (arg.get("CDAY" + suffix, 0) != null)
|
||||
return Failable.ok(resultC(arg, suffix));
|
||||
}
|
||||
if (arg.get("DCOUNT" + suffix, 0) != null) {
|
||||
|
||||
if (arg.get("DCOUNT" + suffix, 0) != null)
|
||||
return Failable.ok(resultD(system, arg, suffix));
|
||||
}
|
||||
if (arg.get("ECOUNT" + suffix, 0) != null) {
|
||||
|
||||
if (arg.get("ECOUNT" + suffix, 0) != null)
|
||||
return Failable.ok(resultE(system, arg, suffix));
|
||||
}
|
||||
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
|
||||
|
@ -44,7 +44,7 @@ import net.sourceforge.plantuml.project.time.Day;
|
||||
public class SentenceHappensDate extends SentenceSimple {
|
||||
|
||||
public SentenceHappensDate() {
|
||||
super(SubjectTask.ME, Verbs.happens, new ComplementDate());
|
||||
super(SubjectTask.ME, Verbs.happens, ComplementDate.any());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -43,7 +43,7 @@ import net.sourceforge.plantuml.project.time.Day;
|
||||
public class SentencePausesDate extends SentenceSimple {
|
||||
|
||||
public SentencePausesDate() {
|
||||
super(SubjectTask.ME, Verbs.pauses, new ComplementDate());
|
||||
super(SubjectTask.ME, Verbs.pauses, ComplementDate.any());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -43,7 +43,7 @@ import net.sourceforge.plantuml.project.time.Day;
|
||||
public class SentenceTaskEndsAbsolute extends SentenceSimple {
|
||||
|
||||
public SentenceTaskEndsAbsolute() {
|
||||
super(SubjectTask.ME, Verbs.ends2, new ComplementDate());
|
||||
super(SubjectTask.ME, Verbs.ends2, ComplementDate.any());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -43,7 +43,7 @@ import net.sourceforge.plantuml.project.time.Day;
|
||||
public class SentenceTaskStartsAbsolute extends SentenceSimple {
|
||||
|
||||
public SentenceTaskStartsAbsolute() {
|
||||
super(SubjectTask.ME, Verbs.starts3, new ComplementDate());
|
||||
super(SubjectTask.ME, Verbs.starts3, ComplementDate.any());
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -52,7 +52,7 @@ public class SentenceTaskStartsAbsolute extends SentenceSimple {
|
||||
final Day start = (Day) complement;
|
||||
final Day startingDate = project.getStartingDate();
|
||||
if (startingDate.getAbsoluteDayNum() == 0)
|
||||
project.setProjectStartingDate(start);
|
||||
return CommandExecutionResult.error("No starting date for the project");
|
||||
|
||||
task.setStart(start);
|
||||
return CommandExecutionResult.ok();
|
||||
|
@ -0,0 +1,58 @@
|
||||
/* ========================================================================
|
||||
* PlantUML : a free UML diagram generator
|
||||
* ========================================================================
|
||||
*
|
||||
* (C) Copyright 2009-2024, Arnaud Roques
|
||||
*
|
||||
* Project Info: https://plantuml.com
|
||||
*
|
||||
* If you like this project or if you find it useful, you can support us at:
|
||||
*
|
||||
* https://plantuml.com/patreon (only 1$ per month!)
|
||||
* https://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 net.sourceforge.plantuml.command.CommandExecutionResult;
|
||||
import net.sourceforge.plantuml.project.GanttDiagram;
|
||||
import net.sourceforge.plantuml.project.core.Task;
|
||||
import net.sourceforge.plantuml.project.time.Day;
|
||||
|
||||
public class SentenceTaskStartsOnlyRelative extends SentenceSimple {
|
||||
|
||||
public SentenceTaskStartsOnlyRelative() {
|
||||
super(SubjectTask.ME, Verbs.starts3, ComplementDate.onlyRelative());
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandExecutionResult execute(GanttDiagram project, Object subject, Object complement) {
|
||||
final Task task = (Task) subject;
|
||||
final Day start = (Day) complement;
|
||||
|
||||
task.setStart(start);
|
||||
return CommandExecutionResult.ok();
|
||||
}
|
||||
|
||||
}
|
@ -68,7 +68,7 @@ public class SubjectProject implements Subject {
|
||||
class Starts extends SentenceSimple {
|
||||
|
||||
public Starts() {
|
||||
super(SubjectProject.this, Verbs.starts, new ComplementDate());
|
||||
super(SubjectProject.this, Verbs.starts, ComplementDate.onlyAbsolute());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -63,7 +63,8 @@ public class SubjectResource implements Subject {
|
||||
}
|
||||
|
||||
public Collection<? extends SentenceSimple> getSentences() {
|
||||
return Arrays.asList(new IsOffDate(), new IsOffDates(), new IsOffDayOfWeek(), new IsOnDate(), new IsOnDates());
|
||||
return Arrays.asList(new IsOffDate(), new IsOffDates(), new IsOffDayOfWeek(), new IsOnDate(), new IsOnDates(),
|
||||
new IsOffBeforeDate(), new IsOffAfterDate());
|
||||
}
|
||||
|
||||
public IRegex toRegex() {
|
||||
@ -72,10 +73,42 @@ public class SubjectResource implements Subject {
|
||||
);
|
||||
}
|
||||
|
||||
public class IsOffBeforeDate extends SentenceSimple {
|
||||
|
||||
public IsOffBeforeDate() {
|
||||
super(SubjectResource.this, Verbs.isOffBefore, ComplementDate.any());
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandExecutionResult execute(GanttDiagram project, Object subject, Object complement) {
|
||||
final Resource resource = (Resource) subject;
|
||||
final Day when = (Day) complement;
|
||||
resource.setOffBeforeDate(when);
|
||||
return CommandExecutionResult.ok();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public class IsOffAfterDate extends SentenceSimple {
|
||||
|
||||
public IsOffAfterDate() {
|
||||
super(SubjectResource.this, Verbs.isOffAfter, ComplementDate.any());
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandExecutionResult execute(GanttDiagram project, Object subject, Object complement) {
|
||||
final Resource resource = (Resource) subject;
|
||||
final Day when = (Day) complement;
|
||||
resource.setOffAfterDate(when);
|
||||
return CommandExecutionResult.ok();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public class IsOffDate extends SentenceSimple {
|
||||
|
||||
public IsOffDate() {
|
||||
super(SubjectResource.this, Verbs.isOff, new ComplementDate());
|
||||
super(SubjectResource.this, Verbs.isOff, ComplementDate.any());
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -123,7 +156,7 @@ public class SubjectResource implements Subject {
|
||||
public class IsOnDate extends SentenceSimple {
|
||||
|
||||
public IsOnDate() {
|
||||
super(SubjectResource.this, Verbs.isOn, new ComplementDate());
|
||||
super(SubjectResource.this, Verbs.isOn, ComplementDate.any());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -69,7 +69,7 @@ public class SubjectSeparator implements Subject {
|
||||
class JustBefore extends SentenceSimple {
|
||||
|
||||
public JustBefore() {
|
||||
super(SubjectSeparator.this, Verbs.justBefore, new ComplementDate());
|
||||
super(SubjectSeparator.this, Verbs.justBefore, ComplementDate.any());
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -85,7 +85,7 @@ public class SubjectSeparator implements Subject {
|
||||
class JustAfter extends SentenceSimple {
|
||||
|
||||
public JustAfter() {
|
||||
super(SubjectSeparator.this, Verbs.justAfter, new ComplementDate());
|
||||
super(SubjectSeparator.this, Verbs.justAfter, ComplementDate.any());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -81,11 +81,11 @@ public class SubjectTask implements Subject {
|
||||
|
||||
public Collection<? extends SentenceSimple> getSentences() {
|
||||
return Arrays.asList(new SentenceLasts(), new SentenceTaskStarts(), new SentenceTaskStartsWithColor(),
|
||||
new SentenceTaskStartsAbsolute(), new SentenceHappens(), new SentenceHappensDate(), new SentenceEnds(),
|
||||
new SentenceTaskEndsAbsolute(), new SentenceIsColored(), new SentenceIsColoredForCompletion(),
|
||||
new SentenceIsDeleted(), new SentenceIsForTask(), new SentenceLinksTo(), new SentenceOccurs(),
|
||||
new SentenceDisplayOnSameRowAs(), new SentencePausesDate(), new SentencePausesDates(),
|
||||
new SentencePausesDayOfWeek());
|
||||
new SentenceTaskStartsOnlyRelative(), new SentenceTaskStartsAbsolute(), new SentenceHappens(),
|
||||
new SentenceHappensDate(), new SentenceEnds(), new SentenceTaskEndsAbsolute(), new SentenceIsColored(),
|
||||
new SentenceIsColoredForCompletion(), new SentenceIsDeleted(), new SentenceIsForTask(),
|
||||
new SentenceLinksTo(), new SentenceOccurs(), new SentenceDisplayOnSameRowAs(), new SentencePausesDate(),
|
||||
new SentencePausesDates(), new SentencePausesDayOfWeek());
|
||||
}
|
||||
|
||||
public IRegex toRegex() {
|
||||
|
@ -90,7 +90,7 @@ public class SubjectToday implements Subject {
|
||||
class IsDate extends SentenceSimple {
|
||||
|
||||
public IsDate() {
|
||||
super(SubjectToday.this, Verbs.is, new ComplementDate());
|
||||
super(SubjectToday.this, Verbs.is, ComplementDate.any());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -70,17 +70,33 @@ public class Verbs {
|
||||
new RegexLeaf("off"), //
|
||||
RegexLeaf.spaceOneOrMore(), //
|
||||
new RegexOr(//
|
||||
new RegexLeaf("from"), //
|
||||
new RegexLeaf("on"), //
|
||||
new RegexLeaf("for"), //
|
||||
new RegexLeaf("the"), //
|
||||
new RegexLeaf("at") //
|
||||
));
|
||||
|
||||
public static IRegex isOffBefore = new RegexConcat(new RegexLeaf("is"), //
|
||||
RegexLeaf.spaceOneOrMore(), //
|
||||
new RegexLeaf("off"), //
|
||||
RegexLeaf.spaceOneOrMore(), //
|
||||
new RegexLeaf("before") //
|
||||
);
|
||||
|
||||
public static IRegex isOffAfter = new RegexConcat(new RegexLeaf("is"), //
|
||||
RegexLeaf.spaceOneOrMore(), //
|
||||
new RegexLeaf("off"), //
|
||||
RegexLeaf.spaceOneOrMore(), //
|
||||
new RegexLeaf("after") //
|
||||
);
|
||||
|
||||
public static IRegex isOn = new RegexConcat(new RegexLeaf("is"), //
|
||||
RegexLeaf.spaceOneOrMore(), //
|
||||
new RegexLeaf("on"), //
|
||||
RegexLeaf.spaceOneOrMore(), //
|
||||
new RegexOr(//
|
||||
new RegexLeaf("from"), //
|
||||
new RegexLeaf("on"), //
|
||||
new RegexLeaf("for"), //
|
||||
new RegexLeaf("the"), //
|
||||
|
@ -0,0 +1,44 @@
|
||||
/* ========================================================================
|
||||
* PlantUML : a free UML diagram generator
|
||||
* ========================================================================
|
||||
*
|
||||
* (C) Copyright 2009-2024, Arnaud Roques
|
||||
*
|
||||
* Project Info: https://plantuml.com
|
||||
*
|
||||
* If you like this project or if you find it useful, you can support us at:
|
||||
*
|
||||
* https://plantuml.com/patreon (only 1$ per month!)
|
||||
* https://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.solver;
|
||||
|
||||
public class ImpossibleSolvingException extends RuntimeException {
|
||||
|
||||
public ImpossibleSolvingException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
}
|
@ -54,12 +54,17 @@ public class SolverImpl extends AbstractSolver implements Solver {
|
||||
Day current = (Day) values.get(TaskAttribute.START);
|
||||
int fullLoad = ((Load) values.get(TaskAttribute.LOAD)).getFullLoad();
|
||||
int cpt = 0;
|
||||
final Day lastDayIfAny = loadPlanable.getLastDayIfAny();
|
||||
while (fullLoad > 0) {
|
||||
fullLoad -= loadPlanable.getLoadAt(current);
|
||||
current = current.increment();
|
||||
if (lastDayIfAny != null && current.compareTo(lastDayIfAny) > 0)
|
||||
throw new ImpossibleSolvingException(
|
||||
"Because all resources will be off at some point, we cannot compute any end date for "
|
||||
+ loadPlanable);
|
||||
cpt++;
|
||||
if (cpt > 100000)
|
||||
throw new IllegalStateException();
|
||||
throw new ImpossibleSolvingException("There is an issue in planning your tasks!");
|
||||
|
||||
}
|
||||
return current.decrement();
|
||||
@ -78,7 +83,7 @@ public class SolverImpl extends AbstractSolver implements Solver {
|
||||
|
||||
cpt++;
|
||||
if (cpt > 100000)
|
||||
throw new IllegalStateException();
|
||||
throw new ImpossibleSolvingException("There is an issue in planning your tasks!");
|
||||
|
||||
}
|
||||
return current.increment();
|
||||
|
@ -138,6 +138,7 @@ public enum SName {
|
||||
undone, //
|
||||
unstarted, //
|
||||
usecase, //
|
||||
verticalSeparator, //
|
||||
|
||||
visibilityIcon, //
|
||||
private_, //
|
||||
|
@ -46,7 +46,7 @@ public class Version {
|
||||
|
||||
// Warning, "version" should be the same in gradle.properties and Version.java
|
||||
// Any idea anyone how to magically synchronize those :-) ?
|
||||
private static final String version = "1.2023.13beta2";
|
||||
private static final String version = "1.2023.13beta3";
|
||||
|
||||
public static String versionString() {
|
||||
return version;
|
||||
|
Loading…
Reference in New Issue
Block a user