mirror of
https://github.com/GothenburgBitFactory/timewarrior.git
synced 2025-06-26 10:54:28 +02:00
Extract creation of summary table into SummaryTableBuilder
Signed-off-by: Thomas Lauf <thomas.lauf@tngtech.com>
This commit is contained in:
parent
65985bcd37
commit
d74184f46b
6 changed files with 412 additions and 163 deletions
|
@ -27,6 +27,7 @@ set (timew_SRCS AtomicFile.cpp AtomicFile.h
|
|||
Journal.cpp Journal.h
|
||||
Range.cpp Range.h
|
||||
Rules.cpp Rules.h
|
||||
SummaryTable.cpp SummaryTable.h
|
||||
TagDescription.cpp TagDescription.h
|
||||
TagInfo.cpp TagInfo.h
|
||||
TagInfoDatabase.cpp TagInfoDatabase.h
|
||||
|
|
276
src/SummaryTable.cpp
Normal file
276
src/SummaryTable.cpp
Normal file
|
@ -0,0 +1,276 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright 2023, Gothenburg Bit Factory.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included
|
||||
// in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
//
|
||||
// https://www.opensource.org/licenses/mit-license.php
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <Datetime.h>
|
||||
#include <SummaryTable.h>
|
||||
#include <Table.h>
|
||||
#include <format.h>
|
||||
#include <timew.h>
|
||||
#include <utf8.h>
|
||||
#include <utility>
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
SummaryTable::Builder SummaryTable::builder ()
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
SummaryTable::Builder& SummaryTable::Builder::withWeekFormat (const std::string& format)
|
||||
{
|
||||
_week_fmt = format;
|
||||
return *this;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
SummaryTable::Builder& SummaryTable::Builder::withDateFormat (const std::string& format)
|
||||
{
|
||||
_date_fmt = format;
|
||||
return *this;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
SummaryTable::Builder& SummaryTable::Builder::withTimeFormat (const std::string& format)
|
||||
{
|
||||
_time_fmt = format;
|
||||
return *this;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
SummaryTable::Builder& SummaryTable::Builder::withAnnotations (const bool show)
|
||||
{
|
||||
_show_annotations = show;
|
||||
return *this;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
SummaryTable::Builder& SummaryTable::Builder::withIds (bool show, Color color)
|
||||
{
|
||||
_show_ids = show;
|
||||
_color_id = color;
|
||||
return *this;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
SummaryTable::Builder & SummaryTable::Builder::withTags (bool show, std::map <std::string, Color>& colors)
|
||||
{
|
||||
_show_tags = show;
|
||||
_color_tags = std::move (colors);
|
||||
return *this;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
SummaryTable::Builder& SummaryTable::Builder::withWeekdays (const bool show)
|
||||
{
|
||||
_show_weekdays = show;
|
||||
return *this;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
SummaryTable::Builder& SummaryTable::Builder::withWeeks (const bool show)
|
||||
{
|
||||
_show_weeks = show;
|
||||
return *this;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
SummaryTable::Builder& SummaryTable::Builder::withRange (const Range& range)
|
||||
{
|
||||
_range = range;
|
||||
return *this;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
SummaryTable::Builder & SummaryTable::Builder::withIntervals (const std::vector<Interval>& tracked)
|
||||
{
|
||||
_tracked = tracked;
|
||||
return *this;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
Table SummaryTable::Builder::build ()
|
||||
{
|
||||
const auto dates_col_offset = _show_weeks ? 1 : 0;
|
||||
const auto weekdays_col_offset = dates_col_offset;
|
||||
const auto ids_col_offset = weekdays_col_offset + (_show_weekdays ? 1: 0);
|
||||
const auto tags_col_offset = ids_col_offset + (_show_ids ? 1 : 0);
|
||||
const auto annotation_col_offset = tags_col_offset + (_show_tags ? 1 : 0);
|
||||
const auto start_col_offset = annotation_col_offset + (_show_annotations ? 1 : 0);
|
||||
|
||||
const auto weeks_col_index = 0;
|
||||
const auto dates_col_index = 0 + dates_col_offset;
|
||||
const auto weekdays_col_index = 1 + weekdays_col_offset;
|
||||
const auto ids_col_index = 1 + ids_col_offset;
|
||||
const auto tags_col_index = 1 + tags_col_offset;
|
||||
const auto annotation_col_index = 1 + annotation_col_offset;
|
||||
const auto start_col_index = 1 + start_col_offset;
|
||||
const auto end_col_index = 2 + start_col_offset;
|
||||
const auto duration_col_index = 3 + start_col_offset;
|
||||
const auto total_col_index = 4 + start_col_offset;
|
||||
|
||||
Table table;
|
||||
table.width (1024);
|
||||
table.colorHeader (Color ("underline"));
|
||||
|
||||
if (_show_weeks)
|
||||
{
|
||||
table.add ("Wk");
|
||||
}
|
||||
|
||||
table.add ("Date");
|
||||
|
||||
if (_show_weekdays)
|
||||
{
|
||||
table.add ("Day");
|
||||
}
|
||||
|
||||
if (_show_ids)
|
||||
{
|
||||
table.add ("ID");
|
||||
}
|
||||
|
||||
if (_show_tags)
|
||||
{
|
||||
table.add ("Tags");
|
||||
}
|
||||
|
||||
if (_show_annotations)
|
||||
{
|
||||
table.add ("Annotation");
|
||||
}
|
||||
|
||||
table.add ("Start", false);
|
||||
table.add ("End", false);
|
||||
table.add ("Time", false);
|
||||
table.add ("Total", false);
|
||||
|
||||
// Each day is rendered separately.
|
||||
time_t grand_total = 0;
|
||||
Datetime previous;
|
||||
|
||||
auto days_start = _range.is_started () ? _range.start : _tracked.front ().start;
|
||||
auto days_end = _range.is_ended () ? _range.end : _tracked.back ().end;
|
||||
|
||||
const auto now = Datetime ();
|
||||
|
||||
if (days_end == 0)
|
||||
{
|
||||
days_end = now;
|
||||
}
|
||||
|
||||
for (Datetime day = days_start.startOfDay (); day < days_end; ++day)
|
||||
{
|
||||
auto day_range = getFullDay (day);
|
||||
time_t daily_total = 0;
|
||||
|
||||
int row = -1;
|
||||
for (auto& track : subset (day_range, _tracked))
|
||||
{
|
||||
// Make sure the track only represents one day.
|
||||
if ((track.is_open () && day > now))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
row = table.addRow ();
|
||||
|
||||
if (day != previous)
|
||||
{
|
||||
if (_show_weeks)
|
||||
{
|
||||
table.set (row, weeks_col_index, format (_week_fmt, day.week ()));
|
||||
}
|
||||
|
||||
table.set (row, dates_col_index, day.toString (_date_fmt));
|
||||
|
||||
if (_show_weekdays)
|
||||
{
|
||||
table.set (row, weekdays_col_index, Datetime::dayNameShort (day.dayOfWeek ()));
|
||||
}
|
||||
|
||||
previous = day;
|
||||
}
|
||||
|
||||
// Intersect track with day.
|
||||
auto today = day_range.intersect (track);
|
||||
|
||||
if (track.is_open () && track.start > now)
|
||||
{
|
||||
today.end = track.start;
|
||||
}
|
||||
else if (track.is_open () && day <= now && today.end > now)
|
||||
{
|
||||
today.end = now;
|
||||
}
|
||||
|
||||
if (_show_ids)
|
||||
{
|
||||
table.set (row, ids_col_index, format ("@{1}", track.id), _color_id);
|
||||
}
|
||||
|
||||
if (_show_tags)
|
||||
{
|
||||
auto tags_string = join (", ", track.tags ());
|
||||
table.set (row, tags_col_index, tags_string, summaryIntervalColor (_color_tags, track.tags ()));
|
||||
}
|
||||
|
||||
if (_show_annotations)
|
||||
{
|
||||
auto annotation = track.getAnnotation ();
|
||||
|
||||
if (utf8_length (annotation) > 15)
|
||||
{
|
||||
annotation = utf8_substr (annotation, 0, 12) + "...";
|
||||
}
|
||||
|
||||
table.set (row, annotation_col_index, annotation);
|
||||
}
|
||||
|
||||
const auto total = today.total ();
|
||||
|
||||
table.set (row, start_col_index, today.start.toString (_time_fmt));
|
||||
table.set (row, end_col_index, (track.is_open () ? "-" : today.end.toString (_time_fmt)));
|
||||
table.set (row, duration_col_index, Duration (total).formatHours ());
|
||||
|
||||
daily_total += total;
|
||||
}
|
||||
|
||||
if (row != -1)
|
||||
{
|
||||
table.set (row, total_col_index, Duration (daily_total).formatHours ());
|
||||
}
|
||||
|
||||
grand_total += daily_total;
|
||||
}
|
||||
|
||||
// Add the total.
|
||||
table.set (table.addRow (), total_col_index, " ", Color ("underline"));
|
||||
table.set (table.addRow (), total_col_index, Duration (grand_total).formatHours ());
|
||||
|
||||
return table;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
77
src/SummaryTable.h
Normal file
77
src/SummaryTable.h
Normal file
|
@ -0,0 +1,77 @@
|
|||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright 2023, Gothenburg Bit Factory.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included
|
||||
// in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
//
|
||||
// https://www.opensource.org/licenses/mit-license.php
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef INCLUDED_SUMMARYTABLE
|
||||
#define INCLUDED_SUMMARYTABLE
|
||||
|
||||
#include <Color.h>
|
||||
#include <Interval.h>
|
||||
#include <Range.h>
|
||||
#include <Table.h>
|
||||
#include <map>
|
||||
|
||||
class SummaryTable
|
||||
{
|
||||
class Builder
|
||||
{
|
||||
public:
|
||||
Builder& withWeekFormat (const std::string &);
|
||||
Builder& withDateFormat (const std::string &);
|
||||
Builder& withTimeFormat (const std::string &);
|
||||
|
||||
Builder& withAnnotations (bool);
|
||||
Builder& withIds (bool, Color);
|
||||
Builder& withTags (bool, std::map <std::string, Color>&);
|
||||
Builder& withWeeks (bool);
|
||||
Builder& withWeekdays (bool);
|
||||
|
||||
Builder& withRange (const Range &);
|
||||
Builder& withIntervals (const std::vector <Interval>&);
|
||||
|
||||
Table build ();
|
||||
|
||||
private:
|
||||
std::string _week_fmt;
|
||||
std::string _date_fmt;
|
||||
std::string _time_fmt;
|
||||
|
||||
bool _show_annotations;
|
||||
bool _show_ids;
|
||||
bool _show_tags;
|
||||
bool _show_weekdays;
|
||||
bool _show_weeks;
|
||||
|
||||
Range _range;
|
||||
std::vector <Interval> _tracked;
|
||||
Color _color_id;
|
||||
std::map <std::string, Color> _color_tags;
|
||||
};
|
||||
|
||||
public:
|
||||
static Builder builder ();
|
||||
};
|
||||
|
||||
#endif // INCLUDED_SUMMARYTABLE
|
|
@ -24,10 +24,10 @@
|
|||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <Duration.h>
|
||||
#include <IntervalFilterAllInRange.h>
|
||||
#include <IntervalFilterAllWithTags.h>
|
||||
#include <IntervalFilterAndGroup.h>
|
||||
#include <SummaryTable.h>
|
||||
#include <Table.h>
|
||||
#include <commands.h>
|
||||
#include <format.h>
|
||||
|
@ -92,10 +92,7 @@ int CmdSummary (
|
|||
|
||||
// Map tags to colors.
|
||||
Color colorID (rules.getBoolean ("color") ? rules.get ("theme.colors.ids") : "");
|
||||
|
||||
const auto week_fmt = "W{1}";
|
||||
const auto date_fmt = "Y-M-D";
|
||||
const auto time_fmt = "h:N:S";
|
||||
auto tagColorMap = createTagColorMap (rules, tracked);
|
||||
|
||||
const auto show_weeks = rules.getBoolean ("reports.summary.weeks", true);
|
||||
const auto show_weekdays = rules.getBoolean ("reports.summary.weekdays", true);
|
||||
|
@ -104,162 +101,18 @@ int CmdSummary (
|
|||
const auto show_annotations = cli.getComplementaryHint ("annotations", rules.getBoolean ("reports.summary.annotations"));
|
||||
const auto show_holidays = cli.getComplementaryHint ("holidays", rules.getBoolean ("reports.summary.holidays"));
|
||||
|
||||
const auto dates_col_offset = show_weeks ? 1 : 0;
|
||||
const auto weekdays_col_offset = dates_col_offset;
|
||||
const auto ids_col_offset = weekdays_col_offset + (show_weekdays ? 1: 0);
|
||||
const auto tags_col_offset = ids_col_offset + (show_ids ? 1 : 0);
|
||||
const auto annotation_col_offset = tags_col_offset + (show_tags ? 1 : 0);
|
||||
const auto start_col_offset = annotation_col_offset + (show_annotations ? 1 : 0);
|
||||
|
||||
const auto weeks_col_index = 0;
|
||||
const auto dates_col_index = 0 + dates_col_offset;
|
||||
const auto weekdays_col_index = 1 + weekdays_col_offset;
|
||||
const auto ids_col_index = 1 + ids_col_offset;
|
||||
const auto tags_col_index = 1 + tags_col_offset;
|
||||
const auto annotation_col_index = 1 + annotation_col_offset;
|
||||
const auto start_col_index = 1 + start_col_offset;
|
||||
const auto end_col_index = 2 + start_col_offset;
|
||||
const auto duration_col_index = 3 + start_col_offset;
|
||||
const auto total_col_index = 4 + start_col_offset;
|
||||
|
||||
Table table;
|
||||
table.width (1024);
|
||||
table.colorHeader (Color ("underline"));
|
||||
|
||||
if (show_weeks)
|
||||
{
|
||||
table.add ("Wk");
|
||||
}
|
||||
|
||||
table.add ("Date");
|
||||
|
||||
if (show_weekdays)
|
||||
{
|
||||
table.add ("Day");
|
||||
}
|
||||
|
||||
if (show_ids)
|
||||
{
|
||||
table.add ("ID");
|
||||
}
|
||||
|
||||
if (show_tags)
|
||||
{
|
||||
table.add ("Tags");
|
||||
}
|
||||
|
||||
if (show_annotations)
|
||||
{
|
||||
table.add ("Annotation");
|
||||
}
|
||||
|
||||
table.add ("Start", false);
|
||||
table.add ("End", false);
|
||||
table.add ("Time", false);
|
||||
table.add ("Total", false);
|
||||
|
||||
// Each day is rendered separately.
|
||||
time_t grand_total = 0;
|
||||
Datetime previous;
|
||||
|
||||
auto days_start = range.is_started() ? range.start : tracked.front ().start;
|
||||
auto days_end = range.is_ended() ? range.end : tracked.back ().end;
|
||||
|
||||
const auto now = Datetime ();
|
||||
|
||||
if (days_end == 0)
|
||||
{
|
||||
days_end = now;
|
||||
}
|
||||
|
||||
for (Datetime day = days_start.startOfDay (); day < days_end; ++day)
|
||||
{
|
||||
auto day_range = getFullDay (day);
|
||||
time_t daily_total = 0;
|
||||
|
||||
int row = -1;
|
||||
for (auto& track : subset (day_range, tracked))
|
||||
{
|
||||
// Make sure the track only represents one day.
|
||||
if ((track.is_open () && day > now))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
row = table.addRow ();
|
||||
|
||||
if (day != previous)
|
||||
{
|
||||
if (show_weeks)
|
||||
{
|
||||
table.set (row, weeks_col_index, format (week_fmt, day.week ()));
|
||||
}
|
||||
|
||||
table.set (row, dates_col_index, day.toString (date_fmt));
|
||||
|
||||
if (show_weekdays)
|
||||
{
|
||||
table.set (row, weekdays_col_index, Datetime::dayNameShort (day.dayOfWeek ()));
|
||||
}
|
||||
|
||||
previous = day;
|
||||
}
|
||||
|
||||
// Intersect track with day.
|
||||
auto today = day_range.intersect (track);
|
||||
|
||||
if (track.is_open() && track.start > now)
|
||||
{
|
||||
today.end = track.start;
|
||||
}
|
||||
else if (track.is_open () && day <= now && today.end > now)
|
||||
{
|
||||
today.end = now;
|
||||
}
|
||||
|
||||
if (show_ids)
|
||||
{
|
||||
table.set (row, ids_col_index, format ("@{1}", track.id), colorID);
|
||||
}
|
||||
|
||||
if (show_tags)
|
||||
{
|
||||
std::string tags_string = join (", ", track.tags ());
|
||||
table.set (row, tags_col_index, tags_string, summaryIntervalColor (rules, track.tags ()));
|
||||
}
|
||||
|
||||
if (show_annotations)
|
||||
{
|
||||
auto annotation = track.getAnnotation ();
|
||||
|
||||
if (utf8_length (annotation) > 15)
|
||||
{
|
||||
annotation = utf8_substr (annotation, 0, 12) + "...";
|
||||
}
|
||||
|
||||
table.set (row, annotation_col_index, annotation);
|
||||
}
|
||||
|
||||
const auto total = today.total ();
|
||||
|
||||
table.set (row, start_col_index, today.start.toString (time_fmt));
|
||||
table.set (row, end_col_index, (track.is_open () ? "-" : today.end.toString (time_fmt)));
|
||||
table.set (row, duration_col_index, Duration (total).formatHours ());
|
||||
|
||||
daily_total += total;
|
||||
}
|
||||
|
||||
if (row != -1)
|
||||
{
|
||||
table.set (row, total_col_index, Duration (daily_total).formatHours ());
|
||||
}
|
||||
|
||||
grand_total += daily_total;
|
||||
}
|
||||
|
||||
// Add the total.
|
||||
table.set (table.addRow (), total_col_index, " ", Color ("underline"));
|
||||
table.set (table.addRow (), total_col_index, Duration (grand_total).formatHours ());
|
||||
auto table = SummaryTable::builder ()
|
||||
.withWeekFormat ("W{1}")
|
||||
.withDateFormat ("Y-M-D")
|
||||
.withTimeFormat ("h:N:S")
|
||||
.withWeeks (show_weeks)
|
||||
.withWeekdays (show_weekdays)
|
||||
.withIds (show_ids, colorID)
|
||||
.withTags (show_tags, tagColorMap)
|
||||
.withAnnotations (show_annotations)
|
||||
.withRange (range)
|
||||
.withIntervals (tracked)
|
||||
.build ();
|
||||
|
||||
std::cout << '\n'
|
||||
<< table.render ()
|
||||
|
@ -270,11 +123,11 @@ int CmdSummary (
|
|||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
std::string renderHolidays (const std::map<Datetime, std::string> &holidays)
|
||||
std::string renderHolidays (const std::map<Datetime, std::string>& holidays)
|
||||
{
|
||||
std::stringstream out;
|
||||
|
||||
for (auto &entry : holidays)
|
||||
for (auto& entry : holidays)
|
||||
{
|
||||
out << entry.first.toString ("Y-M-D")
|
||||
<< " "
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
#include <iomanip>
|
||||
#include <map>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <timew.h>
|
||||
#include <vector>
|
||||
|
||||
|
@ -50,6 +51,21 @@ Color summaryIntervalColor (
|
|||
return c;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
Color summaryIntervalColor (
|
||||
std::map <std::string, Color>& tagColors,
|
||||
const std::set <std::string>& tags)
|
||||
{
|
||||
Color c;
|
||||
|
||||
for (const auto& tag : tags)
|
||||
{
|
||||
c.blend (tagColors[tag]);
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Select a color to represent the interval on a chart.
|
||||
Color chartIntervalColor (
|
||||
|
@ -410,6 +426,30 @@ std::map <std::string, Color> createTagColorMap (
|
|||
return mapping;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
std::map <std::string, Color> createTagColorMap (const Rules& rules, const std::vector <Interval>& intervals)
|
||||
{
|
||||
std::set <std::string> tags;
|
||||
|
||||
for (const auto& interval : intervals)
|
||||
{
|
||||
tags.insert (interval.tags ().begin (), interval.tags ().end ());
|
||||
}
|
||||
|
||||
std::map <std::string, Color> mapping;
|
||||
|
||||
for (const auto& tag : tags)
|
||||
{
|
||||
std::string key = "tags." + tag + ".color";
|
||||
if (rules.has (key))
|
||||
{
|
||||
mapping[tag] = Color (rules.get (key));
|
||||
}
|
||||
}
|
||||
|
||||
return mapping;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
int quantizeToNMinutes (const int minutes, const int N)
|
||||
{
|
||||
|
|
|
@ -69,6 +69,7 @@ int dispatchCommand (const CLI&, Database&, Journal&, Rules&, const Extensions&)
|
|||
|
||||
// helper.cpp
|
||||
Color summaryIntervalColor (const Rules&, const std::set <std::string>&);
|
||||
Color summaryIntervalColor (std::map <std::string, Color>&, const std::set <std::string>&);
|
||||
Color chartIntervalColor (const std::set <std::string>&, const std::map <std::string, Color>&);
|
||||
Color tagColor (const Rules&, const std::string&);
|
||||
std::string intervalSummarize (const Rules&, const Interval&);
|
||||
|
@ -76,6 +77,7 @@ bool expandIntervalHint (const std::string&, Range&);
|
|||
std::string jsonFromIntervals (const std::vector <Interval>&);
|
||||
Palette createPalette (const Rules&);
|
||||
std::map <std::string, Color> createTagColorMap (const Rules&, Palette&, const std::vector <Interval>&);
|
||||
std::map <std::string, Color> createTagColorMap (const Rules& rules, const std::vector <Interval>& intervals);
|
||||
int quantizeToNMinutes (int, int);
|
||||
|
||||
bool findHint (const CLI&, const std::string&);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue