From fadeece72f2709e84f7b7e5f4721dc53baee6f94 Mon Sep 17 00:00:00 2001 From: Sergej Riel Date: Tue, 27 Jan 2026 15:51:58 +0100 Subject: [PATCH 1/5] Feature: upgraded DataTimeline- classes with new gantt properties. --- Widgets/Gantt.php | 27 --- Widgets/Parts/DataTimeline.php | 66 ++++++- Widgets/Parts/DataTimelineHeader.php | 34 +++- Widgets/Parts/DataTimelineThicklines.php | 186 ++++++++++++++++++++ Widgets/Parts/DataTimelineView.php | 215 ++++++++++++++++++++--- 5 files changed, 462 insertions(+), 66 deletions(-) create mode 100644 Widgets/Parts/DataTimelineThicklines.php diff --git a/Widgets/Gantt.php b/Widgets/Gantt.php index 602f8fa44..fd14beb36 100644 --- a/Widgets/Gantt.php +++ b/Widgets/Gantt.php @@ -29,8 +29,6 @@ class Gantt extends DataTree private $keepScrollPosition = false; - private $autoRelayoutOnChange = false; - private $viewModeColumnWidthDay = null; private $viewModeColumnWidthWeek = null; @@ -272,31 +270,6 @@ public function setKeepScrollPosition(bool $value): Gantt return $this; } - /** - * @return bool - */ - public function getAutoRelayoutOnChange() : bool - { - return $this->autoRelayoutOnChange; - } - - /** - * Automatically rearrange when dragging/resizing the taskbars. - * It is necessary if multiple bars are at the same row: - * - * @uxon-property auto_relayout_on_change - * @uxon-type boolean - * @uxon-default true - * - * @param bool $value - * @return $this - */ - public function setAutoRelayoutOnChange(bool $value) : Gantt - { - $this->autoRelayoutOnChange = $value; - return $this; - } - /** * @return int|null */ diff --git a/Widgets/Parts/DataTimeline.php b/Widgets/Parts/DataTimeline.php index 86aaa4b11..e37327cf2 100644 --- a/Widgets/Parts/DataTimeline.php +++ b/Widgets/Parts/DataTimeline.php @@ -5,7 +5,7 @@ use exface\Core\Interfaces\Widgets\WidgetPartInterface; use exface\Core\Widgets\Traits\DataWidgetPartTrait; use exface\Core\Exceptions\Widgets\WidgetConfigurationError; - + //TODO: This doc contains future features that are not implemented yet. /** * DataTimeline configuration for data-widgets like Scheduler or certain Chart types. * @@ -98,6 +98,8 @@ class DataTimeline implements WidgetPartInterface use DataWidgetPartTrait; const GRANULARITY_DAYS = 'days'; + const GRANULARITY_QUARTER_DAYS = 'quarter_days'; + const GRANULARITY_HALF_DAYS = 'half_days'; const GRANULARITY_DAYS_PER_WEEK = 'days_per_week'; const GRANULARITY_DAYS_PER_MONTH = 'days_per_month'; const GRANULARITY_HOURS = 'hours'; @@ -110,6 +112,7 @@ class DataTimeline implements WidgetPartInterface const INTERVAL_WEEK = 'week'; const INTERVAL_MONTH = 'month'; const INTERVAL_YEAR = 'year'; + const INTERVAL_DECADE = 'decade'; private ?array $views = null; private ?UxonObject $viewsUxon = null; @@ -145,7 +148,7 @@ public function getGranularity(string $default = null) : ?string * Initial zoom level: `hours`, `days`, `weeks`, `months`, `years` or `all` * * @uxon-property granularity - * @uxon-type [hours,days,days_per_week,days_per_month,weeks,months,years,all] + * @uxon-type [hours,days,quarter_days,half_day,days_per_week,days_per_month,weeks,months,years,all] * @uxon-default hour * * @param string $value @@ -248,24 +251,71 @@ public function getViews() : array if ($this->viewsUxon === null) { $translator = $this->getWorkbench()->getCoreApp()->getTranslator(); // IDEA get defaults from widget? Different defaults for Gantt and Scheduler? + // Info: This defaults are similar to frappe-gantt defaults. $this->views = [ new DataTimelineView($this, new UxonObject([ 'name' => $translator->translate('WIDGET.GANTT_CHARD.VIEW_MODE_DAY'), - 'granularity' => DataTimelineView::GRANULARITY_DAYS, 'description' => $translator->translate('WIDGET.GANTT_CHARD.VIEW_MODE_DAY_DESCRIPTION'), - 'column_width' => 38 + 'granularity' => DataTimelineView::GRANULARITY_DAYS, + 'date_format' => 'yyyy-MM-dd', + 'padding' => '7d', + 'header_lines' => new UxonObject([ + [ + 'interval' => DataTimeline::INTERVAL_MONTH, + 'date_format' => '', + 'date_format_at_border' => 'MMMM' + ], [ + 'interval' => DataTimeline::INTERVAL_DAY, + 'date_format' => 'dd', + ] + ]), + 'thick_lines' => new UxonObject([[ + 'interval' => 'week', + 'value' => 1 + ]]) ])), new DataTimelineView($this, new UxonObject([ 'name' => $translator->translate('WIDGET.GANTT_CHARD.VIEW_MODE_WEEK'), - 'granularity' => DataTimelineView::GRANULARITY_WEEKS, 'description' => $translator->translate('WIDGET.GANTT_CHARD.VIEW_MODE_WEEK_DESCRIPTION'), - 'column_width' => 140 + 'granularity' => DataTimelineView::GRANULARITY_WEEKS, + 'date_format' => 'yyyy-MM-dd', + 'column_width' => 140, + 'padding' => '1m', + 'header_lines' => new UxonObject([ + [ + 'interval' => DataTimeline::INTERVAL_MONTH, + 'date_format' => '', + 'date_format_at_border' => 'MMMM' + ], [ + 'date_format' => '~weekRange', + ] + ]), + 'thick_lines' => new UxonObject([[ + 'interval' => 'month_range_in_days', + 'from' => 1, + 'to' => 7 + ]]) ])), new DataTimelineView($this, new UxonObject([ 'name' => $translator->translate('WIDGET.GANTT_CHARD.VIEW_MODE_MONTH'), - 'granularity' => DataTimelineView::GRANULARITY_MONTHS, 'description' => $translator->translate('WIDGET.GANTT_CHARD.VIEW_MODE_MONTH_DESCRIPTION'), - 'column_width' => 20 + 'granularity' => DataTimelineView::GRANULARITY_MONTHS, + 'date_format' => 'yyyy-MM', + 'column_width' => 120, + 'snap_at' => DataTimelineView::SNAP_AT_WEEKLY, + 'header_lines' => new UxonObject([ + [ + 'interval' => DataTimeline::INTERVAL_YEAR, + 'date_format_at_border' => 'yyyy' + ], [ + 'date_format' => 'MMMM', + ] + ]), + 'thick_lines' => new UxonObject([ + [ + 'interval' => DataTimelineThicklines::INTERVAL_YEAR_QUARTER, + ] + ]) ])), ]; } else { diff --git a/Widgets/Parts/DataTimelineHeader.php b/Widgets/Parts/DataTimelineHeader.php index 584a113a3..a51302560 100644 --- a/Widgets/Parts/DataTimelineHeader.php +++ b/Widgets/Parts/DataTimelineHeader.php @@ -9,23 +9,25 @@ /** * DataTimelineHeader configuration can set different date formats (ICU) for a DataTimeline header. + * The frist element in the header_lines array is rendered at the top, the next below etc. * * - `interval` - This sets an interval that covers a specific time period, such as a month. * - `date_format` - sets the date format. * - `date_format_at_border` - formats the borders of a chosen interval with different date format. * * ## Examples + * + * In frappe-gantt, to show a timeline with months at the top and days below: * ``` * "header_lines": [ * { * "interval": "month", * "date_format": "", - * "date_format_at_border": "MMM" + * "date_format_at_border": "MMMM" * }, * { - * "interval": "month", - * "date_format": "d", - * "date_format_at_border": "d MMM" + * "interval": "day", + * "date_format": "dd", * } * ] * ``` @@ -72,12 +74,12 @@ public function getInterval(string $default = null) : ?string { return $this->interval; } - + /** * Sets the interval of the header that is used for the border formats. * * @uxon-property interval - * @uxon-type [day,month,week,year] + * @uxon-type [day,month,week,year,decade] * @uxon-default day * * @param string $interval @@ -99,9 +101,22 @@ public function getDateFormat() : ?string /** * Sets the date format of the header. - * Example for 17.12.2025: 'M' -> '12' and 'MMM' -> 'Dez.'. + * Example for 08.02.2025: + * - 'd' -> 8, + * - 'dd' -> 08, + * - 'ddd' -> 39 (day of the year) + * - 'M' -> 2, + * - 'MM' -> '02', + * - 'MMM' -> 'Feb.', + * - 'MMMM' -> 'Februar', + * - 'yy' -> 25, + * - 'yyyy' -> 2025 * * Search for "ICU" to learn more about the format settings. + * + * Special tokens: + * - '~weekRange': shows the week range from Monday to Sunday. Example: 01.03 - 07.03 + * - '~decade': shows decades. Example: 2020, 2030, ... * * * @uxon-property date_format @@ -128,6 +143,8 @@ public function getDateFormatAtBorder() : ?string * Sets the border format of an interval. * Example: If Interval == month -> sets the date format only for the column where the month changes. * + * For more information, see 'date_format' documentation. + * * @uxon-property date_format_at_border * @uxon-type string * @@ -148,8 +165,9 @@ private function formatInterval(string $value) : string switch ($value) { case 'day': $value = DataTimeline::INTERVAL_DAY; break; case 'month': $value = DataTimeline::INTERVAL_MONTH; break; - case 'weer': $value = DataTimeline::INTERVAL_WEEK; break; + case 'week': $value = DataTimeline::INTERVAL_WEEK; break; case 'year': $value = DataTimeline::INTERVAL_YEAR; break; + case 'decade': $value = DataTimeline::INTERVAL_DECADE; break; } $const = DataTimeline::class . '::INTERVAL_' . strtoupper($value); diff --git a/Widgets/Parts/DataTimelineThicklines.php b/Widgets/Parts/DataTimelineThicklines.php new file mode 100644 index 000000000..13a6b3371 --- /dev/null +++ b/Widgets/Parts/DataTimelineThicklines.php @@ -0,0 +1,186 @@ +timelineView = $timelineView; + if ($uxon) { + $this->importUxonObject($uxon); + } + } + + public function getWidget(): WidgetInterface + { + return $this->timelineView->getWidget(); + } + + /** + * @inheritDoc + */ + public function getWorkbench() + { + return $this->timelineView->getWorkbench(); + } + + /** + * @param string|null $default + * @return string|null + */ + public function getInterval(string $default = null) : ?string + { + return $this->interval; + } + + /** + * Sets the interval of the thick line that is used for the chard formats. + * + * @uxon-property interval + * @uxon-type [week,year_quarter,month_range_in_days] + * @uxon-default week + * + * @param string $interval + * @return $this + */ + public function setInterval(string $interval) : DataTimelineThicklines + { + $this->interval = $this->isValidInterval($interval) ? $interval : null; + return $this; + } + + /** + * @return int|null + */ + public function getValue() : ?int + { + return $this->value; + } + + /** + * Is used with the combination of interval "week" to set the day of the week. + * Accepted Values are 0 to 6 (0 = Sunday, 1 = Monday, ..., 6 = Saturday). + * + * @uxon-property value + * @uxon-type int + * + * @param int $value + * @return $this + */ + public function setValue(int $value) : DataTimelineThicklines + { + $this->value = $value; + return $this; + } + + /** + * @return int|null + */ + public function getFrom() : ?int + { + return $this->from; + } + + /** + * Is used with the combination of interval "month_range_in_days" to set the starting day of the month. + * Accepted Values are 1 to 31. + * + * @uxon-property from + * @uxon-type int + * + * @param int $from + * @return $this + */ + public function setFrom(int $from) : DataTimelineThicklines + { + $this->from = $from; + return $this; + } + + /** + * @return int|null + */ + public function getTo() : ?int + { + return $this->to; + } + + /** + * Is used with the combination of interval "month_range_in_days" to set the ending day of the month. + * Accepted Values are 1 to 31. + * + * @uxon-property to + * @uxon-type int + * + * @param int $to + * @return $this + */ + public function setTo(int $to) : DataTimelineThicklines + { + $this->to = $to; + return $this; + } + + public function isValidInterval(string $interval) : bool + { + $const = 'self::INTERVAL_' . mb_strtoupper($interval); + if (! defined($const)) { + throw new WidgetConfigurationError($this->getWidget(), 'Invalid interval "' . $interval . '": please use week, year_quarter or month_range_in_days'); + } + return true; + } +} \ No newline at end of file diff --git a/Widgets/Parts/DataTimelineView.php b/Widgets/Parts/DataTimelineView.php index 8b9471573..c962b3652 100644 --- a/Widgets/Parts/DataTimelineView.php +++ b/Widgets/Parts/DataTimelineView.php @@ -16,31 +16,42 @@ * Widgets like the Gantt chart automatically adds the corresponding buttons for switching views to the toolbar. * * ## Examples - * - * ``` - * "views": [ - * { - * "name": "Tage", - * "description": "Tagesansicht", - * "granularity": "days", - * "column_width": 38, - * "header_lines": [ ... ] + * + * ``` + * "views": [ + * { + * "name": "Tage", + * "description": "Tagesansicht", + * "granularity": "days", + * "date_format": "YYYY-MM-dd", + * "padding": "7d", + * "header_lines": [ ... ], + * "thick_lines": [ ... ], + * }, + * { + * "name": "Wochen", + * "description": "Wochenansicht", + * "granularity": "weeks", + * "date_format": "YYYY-MM-dd", + * "column_width": 140, + * "padding": "1m", + * "upper_text_frequency": 4, + * "header_lines": [ ... ], + * "thick_lines": [ ... ], * }, * { - * "name": "Wochen", - * "description": "Wochenansicht", - * "granularity": "weeks", - * "column_width": 70, - * "header_lines": [ ... ] - * }, - * { - * "name": "Monate", - * "description": "Monatsansicht", - * "granularity": "months", - * "column_width": 20 - * } - * ] - * ``` + * "name": "Monate", + * "description": "Monatsansicht", + * "granularity": "months", + * "date_format": "YYYY-MM", + * "column_width": 120, + * "padding": "2m", + * "snap_at": "weekly", + * "header_lines": [ ... ], + * "thick_lines": [ ... ], + * } + * ] + * ``` * * * @author Andrej Kabachnik & Sergej Riel @@ -53,20 +64,32 @@ class DataTimelineView implements WidgetPartInterface, iHaveIcon use iHaveIconTrait; const GRANULARITY_DAYS = 'days'; + const GRANULARITY_QUARTER_DAYS = 'quarter_days'; + const GRANULARITY_HALF_DAYS = 'half_days'; const GRANULARITY_DAYS_PER_WEEK = 'days_per_week'; const GRANULARITY_DAYS_PER_MONTH = 'days_per_month'; const GRANULARITY_HOURS = 'hours'; const GRANULARITY_WEEKS = 'weeks'; const GRANULARITY_MONTHS = 'months'; const GRANULARITY_YEARS = 'years'; + const SNAP_AT_DAILY = 'daily'; + const SNAP_AT_WEEKLY = 'weekly'; + const SNAP_AT_MONTHLY = 'monthly'; + private $timeline; private ?string $name = null; private ?string $description = null; private $granularity = null; + private ?string $date_format = null; + private ?string $padding = null; + private ?string $snap_at = null; + private ?int $upper_text_frequency = null; private ?WidgetDimension $columnWidth = null; private ?array $headerLines = null; private ?UxonObject $headerLinesUxon = null; + private ?array $thick_lines = null; + private ?UxonObject $thickLinesUxon = null; public function __construct(DataTimeline $timeline, ?UxonObject $uxon = null) { @@ -160,6 +183,111 @@ public function setGranularity(string $value) : DataTimelineView return $this; } + /** + * @return string|null + */ + public function getDateFormat() : ?string + { + return $this->date_format; + } + + /** + * Sets the date format of the timeline view. + * Example: "YYYY-MM-dd" + * + * @uxon-property date_format + * @uxon-type string + * + * @param string $dateFormat + * @return $this + */ + public function setDateFormat(string $dateFormat) : DataTimelineView + { + $this->date_format = $dateFormat; + return $this; + } + + /** + * @return string|null + */ + public function getPadding() : ?string + { + return $this->padding; + } + + /** + * Sets the padding of the timeline view. + * In frappe-gantt, this is the extra space before the start of the first task and after the end date of the last task inside the timeline. + * Examples: + * - "7d" adds 7 days of padding on both sides. + * - "1m" adds 1 month of padding on both sides. + * - "2y" adds 2 years of padding on both sides. + * + * @uxon-property padding + * @uxon-type string + * + * @param string $padding + * @return $this + */ + public function setPadding(string $padding) : DataTimelineView + { + $this->padding = $padding; + return $this; + } + + /** + * @return string|null + */ + public function getSnapAt() : ?string + { + return $this->snap_at; + } + + /** + * Sets the snap_at of the timeline view. + * In frappe-gantt, this defines the snapping behavior when dragging tasks. + * Possible values: + * - "daily" (snaps to each day) + * - "weekly" (snaps to each week) + * - "monthly" (snaps to each month) + * + * @uxon-property snap_at + * @uxon-type [daily,weekly,monthly] + * + * @param string $snapAt + * @return $this + */ + public function setSnapAt(string $snapAt) : DataTimelineView + { + $this->snap_at = $this->isValidSnapAt($snapAt) ? $snapAt : null; + return $this; + } + + /** + * @return int|null + */ + public function getUpperTextFrequency() : ?int + { + return $this->upper_text_frequency; + } + + /** + * Sets the upper_text_frequency of the timeline view. + * In frappe-gantt, this defines how often the upper header text is displayed. + * For example, a value of 4 means the upper header text is shown every 4 units of the granularity. + * + * @uxon-property upper_text_frequency + * @uxon-type integer + * + * @param int $frequency + * @return $this + */ + public function setUpperTextFrequency(int $frequency) : DataTimelineView + { + $this->upper_text_frequency = $frequency; + return $this; + } + /** * @return WidgetDimension */ @@ -215,6 +343,38 @@ protected function setHeaderLines(UxonObject $arrayOfHeaderLines) : DataTimeline return $this; } + /** + * It gets the thick lines with its settings. + * + * @return array|null + */ + public function getThickLines() : ?array + { + if ($this->thick_lines === null) { + foreach ($this->thickLinesUxon as $uxon) { + $this->thick_lines[] = new DataTimelineThicklines($this, $uxon); + } + } + return $this->thick_lines; + } + + /** + * Thick lines settings + * + * @uxon-property thick_lines + * @uxon-type \exface\Core\Widgets\Parts\DataTimelineThicklines[] + * @uxon-template [{"interval": "week", "value": 1}] + * + * @param UxonObject $arrayOfThickLines + * @return $this + */ + protected function setThickLines(UxonObject $arrayOfThickLines) : DataTimelineView + { + $this->thickLinesUxon = $arrayOfThickLines; + $this->thick_lines = null; + return $this; + } + private function formatGranularity(string $value) : string { $value = mb_strtolower($value); @@ -234,4 +394,13 @@ private function formatGranularity(string $value) : string return $value; } + + public function isValidSnapAt(string $snap_at) : bool + { + $const = 'self::SNAP_AT_' . mb_strtoupper($snap_at); + if (! defined($const)) { + throw new WidgetConfigurationError($this->getWidget(), 'Invalid snap_at value: "' . $snap_at . '": please use daily, weekly,or monthly!'); + } + return true; + } } \ No newline at end of file From 412e20f7beedb4fa7a42fc2ca326f1de4571dba1 Mon Sep 17 00:00:00 2001 From: Sergej Riel Date: Mon, 2 Feb 2026 13:45:58 +0100 Subject: [PATCH 2/5] Feature: Added new "color" property for the "thick_lines". --- Widgets/Parts/DataTimelineThicklines.php | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/Widgets/Parts/DataTimelineThicklines.php b/Widgets/Parts/DataTimelineThicklines.php index 13a6b3371..4bf113488 100644 --- a/Widgets/Parts/DataTimelineThicklines.php +++ b/Widgets/Parts/DataTimelineThicklines.php @@ -56,6 +56,7 @@ class DataTimelineThicklines implements WidgetPartInterface private ?int $value = null; private ?int $from = null; private ?int $to = null; + private ?string $color = null; public function __construct(DataTimelineView $timelineView, ?UxonObject $uxon = null) { @@ -175,6 +176,29 @@ public function setTo(int $to) : DataTimelineThicklines return $this; } + /** + * @return string|null + */ + public function getColor() : ?string + { + return $this->color; + } + + /** + * Sets the color of the thick lines. + * + * @uxon-property color + * @uxon-type string + * + * @param string $color + * @return $this + */ + public function setColor(string $color) : DataTimelineThicklines + { + $this->color = $color; + return $this; + } + public function isValidInterval(string $interval) : bool { $const = 'self::INTERVAL_' . mb_strtoupper($interval); From 3d6481efb71586cf37edfcb8c0bd865c991fc012 Mon Sep 17 00:00:00 2001 From: Sergej Riel Date: Fri, 27 Feb 2026 10:57:15 +0100 Subject: [PATCH 3/5] feature: swapped the original gantt month view with the special weeks view. --- Widgets/Parts/DataTimeline.php | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/Widgets/Parts/DataTimeline.php b/Widgets/Parts/DataTimeline.php index e37327cf2..621e01584 100644 --- a/Widgets/Parts/DataTimeline.php +++ b/Widgets/Parts/DataTimeline.php @@ -297,6 +297,33 @@ public function getViews() : array ]]) ])), new DataTimelineView($this, new UxonObject([ + 'name' => $translator->translate('WIDGET.GANTT_CHARD.VIEW_MODE_MONTH'), + 'description' => $translator->translate('WIDGET.GANTT_CHARD.VIEW_MODE_MONTH_DESCRIPTION'), + 'granularity' => DataTimelineView::GRANULARITY_WEEKS, + 'date_format' => 'yyyy-MM-dd', + 'column_width' => 35, + 'upper_text_frequency' => 4, + 'header_lines' => new UxonObject([ + [ + 'interval' => DataTimeline::INTERVAL_MONTH, + 'date_format' => '', + 'date_format_at_border' => 'MMMM' + ], [ + 'date_format' => 'w', + ] + ]), + 'thick_lines' => new UxonObject([ + [ + 'interval' => DataTimelineThicklines::INTERVAL_MONTH_RANGE_IN_DAYS, + 'from' => 1, + 'to' => 7, + ] + ]) + ])), + //TODO: This is the original month view. Currently, month and the year view is not working properly. + // If the user starts no scroll inside the view, the bars will change its position randomly. + // Frappe-gantt authors know about this issue, so it may be fixed in the future. +/* new DataTimelineView($this, new UxonObject([ 'name' => $translator->translate('WIDGET.GANTT_CHARD.VIEW_MODE_MONTH'), 'description' => $translator->translate('WIDGET.GANTT_CHARD.VIEW_MODE_MONTH_DESCRIPTION'), 'granularity' => DataTimelineView::GRANULARITY_MONTHS, @@ -316,7 +343,7 @@ public function getViews() : array 'interval' => DataTimelineThicklines::INTERVAL_YEAR_QUARTER, ] ]) - ])), + ])),*/ ]; } else { foreach ($this->viewsUxon as $uxon) { From f8f1d933a23e4b94c93f95286878aa30abeb5798 Mon Sep 17 00:00:00 2001 From: Sergej Riel Date: Fri, 27 Feb 2026 11:24:44 +0100 Subject: [PATCH 4/5] feature: doc adjustment --- Widgets/Parts/DataTimeline.php | 1 + 1 file changed, 1 insertion(+) diff --git a/Widgets/Parts/DataTimeline.php b/Widgets/Parts/DataTimeline.php index 621e01584..3957ef56a 100644 --- a/Widgets/Parts/DataTimeline.php +++ b/Widgets/Parts/DataTimeline.php @@ -323,6 +323,7 @@ public function getViews() : array //TODO: This is the original month view. Currently, month and the year view is not working properly. // If the user starts no scroll inside the view, the bars will change its position randomly. // Frappe-gantt authors know about this issue, so it may be fixed in the future. + // See: https://github.com/frappe/gantt/issues/498 /* new DataTimelineView($this, new UxonObject([ 'name' => $translator->translate('WIDGET.GANTT_CHARD.VIEW_MODE_MONTH'), 'description' => $translator->translate('WIDGET.GANTT_CHARD.VIEW_MODE_MONTH_DESCRIPTION'), From 0efb280f4360ebe809b99f5ae176ea9311eaff72 Mon Sep 17 00:00:00 2001 From: Sergej Riel Date: Fri, 27 Feb 2026 14:24:46 +0100 Subject: [PATCH 5/5] feature: doc changes --- Widgets/Parts/DataTimelineThicklines.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Widgets/Parts/DataTimelineThicklines.php b/Widgets/Parts/DataTimelineThicklines.php index 4bf113488..e1dbd25ca 100644 --- a/Widgets/Parts/DataTimelineThicklines.php +++ b/Widgets/Parts/DataTimelineThicklines.php @@ -14,6 +14,7 @@ * - `interval` - This sets an interval that determines where thick lines are drawn. * - `value` - Used with the "week" interval to specify the day of the week for the thick line. * - `from` and `to` - Used with the "month_range_in_days" interval to specify the range of days in a month for the thick line. + * - `color` - sets the color of the thick lines. * * ## Examples * @@ -21,7 +22,7 @@ * ``` * "thick_lines": { * "interval": "week", - * "value": 1 + * "value": 1, * } * ``` * @@ -30,7 +31,7 @@ * "thick_lines": { * "interval": "month_range_in_days", * "from": 1, - * "to": 7 + * "to": 7, * } * ``` * @@ -38,6 +39,7 @@ * ``` * "thick_lines": { * "interval": "year_quarter", + * "color": "#7c7c7c", * } * ``` *