Skip to content

Commit

Permalink
Various fixes for the autoscaling
Browse files Browse the repository at this point in the history
It seems to work now, but there are still no unit tests. Cell widths are
now ensured with a min width instead of trying to calculate weird
percentages.
  • Loading branch information
splitbrain committed Jan 26, 2023
1 parent 1c68e51 commit b025725
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 47 deletions.
85 changes: 38 additions & 47 deletions meta/Gantt.php
Expand Up @@ -61,18 +61,17 @@ class Gantt
/** @var int number of days */
protected $daynum;

/** @var int the scaling to use */
protected $scale = 1;

/** @var bool do not show saturday and sunday */
protected $skipWeekends;

/** @var string[] interval formats used */
protected $interval = [
'header' => 'j',
'period' => 'P1D',
'short' => 'q',
'long' => 'Y-m-d',
'header' => 'j', // shown in header
'period' => 'P1D', // smallest shown interval
'next' => '+1 day', // one more interval
'short' => 'q', // interval label
'long' => 'Y-m-d', // interval long label
'comp' => 'Y-m-d', // sortable interval
];

/**
Expand All @@ -95,7 +94,7 @@ public function __construct($id, $mode, \Doku_Renderer $renderer, SearchConfig $
$this->resultCount = $this->searchConfig->getCount();

$conf = $searchConfig->getConf();
$this->skipWeekends = $conf['skipweekends'];
$this->skipWeekends = $conf['skipweekends'] ?? false;

$this->initColumnRefs();
$this->initMinMax();
Expand Down Expand Up @@ -184,37 +183,47 @@ protected function initMinMax()
$this->interval = [
'header' => 'j', // days
'period' => 'P1D',
'short' => 'q',
'next' => '+1 day',
'short' => '\\\\q',
'long' => 'Y-m-d',
'comp' => 'Y-m-d'
];
} elseif ($daynum < 52) {
$this->interval = [
'header' => '\wW', // week numbers
'period' => 'P1D',
'short' => 'q',
'next' => '+1 day',
'short' => '\\\\q',
'long' => 'Y-m-d',
'comp' => 'Y-m-d',
];
} elseif ($daynum < 360) {
$this->interval = [
'header' => 'F', // months
'period' => 'P1D',
'short' => 'q',
'next' => '+1 day',
'short' => '\\\\q',
'long' => 'Y-m-d',
'comp' => 'Y-m-d',
];
} elseif ($daynum < 600) {
$this->interval = [
'header' => 'M \'y', // months and year
'period' => 'P1W', // weeks
'next' => '+1 week',
'short' => '\wW',
'long' => '\wW Y',
'long' => '\wW o',
'comp' => 'o-W',
];
$this->skipWeekends = false;
} else {
$this->interval = [
'header' => '\\\\Q \'y', // quarter and year
'period' => 'P1M', // months
'next' => '+1 month',
'short' => 'M',
'long' => 'F Y',
'comp' => 'Y-m',
];
$this->skipWeekends = false;
}
Expand All @@ -223,8 +232,6 @@ protected function initMinMax()
$this->maxDate = $max;
$this->days = $this->listDays($min, $max);
$this->daynum = $daynum;
$this->scale = $daynum / 85; // each day should have at least 1% space, 15% for the header
if ($this->scale < 1) $this->scale = 1;
}

/**
Expand All @@ -237,10 +244,8 @@ public function render()
return;
}

$width = 100; //* $this->scale;
$this->renderer->doc .= '<div class="table">';
$this->renderer->doc .= '<table class="plugin_structgantt" style="width: ' . $width . '%">';
$this->renderColGroup();
$this->renderer->doc .= '<table class="plugin_structgantt">';
$this->renderer->doc .= '<thead>';
$this->renderHeaders();
$this->renderer->doc .= '</thead>';
Expand Down Expand Up @@ -289,24 +294,6 @@ protected function renderHeaders()
$this->renderDayRow();
}

/**
* Calculates how wide a day should be and creates an appropriate colgroup
*/
protected function renderColGroup()
{

$headwidth = 15;
$daywidth = (100 * $this->scale - $headwidth) / $this->daynum;

$this->renderer->doc .= '<colgroup>';
$this->renderer->doc .= '<col style="width:' . $headwidth . '%" />';
foreach ($this->days as $day) {
$this->renderer->doc .= '<col style="width:' . $daywidth . '%" />';
}
$this->renderer->doc .= '</colgroup>';

}

/**
* Render a row for the days and the today pointer
*/
Expand All @@ -321,8 +308,8 @@ protected function renderDayRow()
} else {
$class = '';
}
$text = $this->format($day, $this->interval['short']);
$title = $this->format($day, $this->interval['long']);
$text = $this->intervalFormat($day, 'short');
$title = $this->intervalFormat($day, 'long');
$this->renderer->doc .= '<td title="' . $title . '" class="' . $class . '">' . $text . '</td>';
}
$this->renderer->doc .= '</tr>';
Expand All @@ -343,9 +330,12 @@ protected function renderRow($row)
$r2 = $this->listDays($start, $end);
$r3 = $this->listDays($end, $this->maxDate);

if($r1) array_pop($r1); // last period is task
if($r3) array_shift($r3); // first period is task

while ($r1 && ($this->intervalFormat(end($r1), 'comp') >= $this->intervalFormat($r2[0], 'comp'))) {
array_pop($r1);
}
while ($r3 && ($this->intervalFormat($r3[0], 'comp') <= $this->intervalFormat(end($r2), 'comp'))) {
array_shift($r3);
}
} else {
$r1 = $this->days;
$r2 = 0;
Expand All @@ -360,7 +350,7 @@ protected function renderRow($row)

// period before the task
foreach ($r1 as $day) {
$this->renderer->doc .= '<td title="' . $this->format($day, $this->interval['long']) . '"></td>';
$this->renderer->doc .= '<td title="' . $this->intervalFormat($day, 'long') . '"></td>';
}

// the task itself
Expand All @@ -383,7 +373,7 @@ protected function renderRow($row)

// period after the task
foreach ($r3 as $day) {
$this->renderer->doc .= '<td title="' . $this->format($day, $this->interval['long']) . '"></td>';
$this->renderer->doc .= '<td title="' . $this->intervalFormat($day, 'long') . '"></td>';
}

$this->renderer->doc .= '</tr>';
Expand All @@ -406,7 +396,7 @@ protected function listDays($start, $end)
$period = new \DatePeriod(
new \DateTime($start),
new \DateInterval($this->interval['period']),
(new \DateTime($end))->modify('+1 day') // Include End Date
(new \DateTime($end))->modify($this->interval['next']) // Include End Date (flag is only available in PHP8)
);

/** @var \DateTime $date */
Expand Down Expand Up @@ -436,15 +426,15 @@ protected function makeHeaders($start, $end)
$period = new \DatePeriod(
new \DateTime($start),
new \DateInterval($this->interval['period']),
(new \DateTime($end))->modify('+1 day') // Include End Date
(new \DateTime($end))->modify($this->interval['next']) // Include End Date (flag is only available in PHP8)
);

/** @var \DateTime $date */
foreach ($period as $date) {
if ($this->skipWeekends && (int)$date->format('N') >= 6) {
continue;
} else {
$ident = $this->format($date, $this->interval['header']);
$ident = $this->intervalFormat($date, 'header');
if (!isset($headers[$ident])) {
$headers[$ident] = 1;
} else {
Expand All @@ -460,11 +450,12 @@ protected function makeHeaders($start, $end)
* Wrapper around DateTime->format() to implement our own placeholders
*
* @param \DateTime $date
* @param string $format
* @param string $formatname
* @return string
*/
protected function format(\DateTime $date, $format)
protected function intervalFormat(\DateTime $date, $formatname)
{
$format = $this->interval[$formatname];
$label = $date->format($format);
return str_replace(
[
Expand Down
8 changes: 8 additions & 0 deletions style.less
@@ -1,5 +1,6 @@
table.plugin_structgantt {
table-layout: fixed;
min-width: 100%;

th.today {
background-color: @ini_text;
Expand All @@ -19,6 +20,9 @@ table.plugin_structgantt {
tr.days td {
font-weight: normal;
font-size: 60%;
padding-left: 0.1em;
padding-right: 0.1em;
min-width: min-content;
cursor: default;
&.today {
background-color: @ini_text;
Expand All @@ -27,6 +31,10 @@ table.plugin_structgantt {
}

tbody {
th {
min-width: 5em;
max-width: 15%;
}

td {
padding: 0;
Expand Down

0 comments on commit b025725

Please sign in to comment.