From 12e734a911779eae40ec26601363ebd19a9c258a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christopher=20M=C3=BChl?= Date: Thu, 9 Apr 2026 16:56:34 +0200 Subject: [PATCH] fix(07): uniform control sizing, min cell 13px, center week view Co-Authored-By: Claude Opus 4.6 --- Resources/public/heatmap.js | 171 ++++++++++++++++++----------------- assets/src/renderers/week.ts | 7 +- assets/src/renderers/year.ts | 2 +- assets/src/ui/controls.ts | 3 +- assets/test/controls.test.ts | 2 +- 5 files changed, 96 insertions(+), 89 deletions(-) diff --git a/Resources/public/heatmap.js b/Resources/public/heatmap.js index bd4cd68..ed9fba0 100644 --- a/Resources/public/heatmap.js +++ b/Resources/public/heatmap.js @@ -46,7 +46,7 @@ var KimaiHeatmap = (() => { return r; } - // ../../../node_modules/d3-selection/src/namespaces.js + // node_modules/d3-selection/src/namespaces.js var xhtml = "http://www.w3.org/1999/xhtml"; var namespaces_default = { svg: "http://www.w3.org/2000/svg", @@ -56,14 +56,14 @@ var KimaiHeatmap = (() => { xmlns: "http://www.w3.org/2000/xmlns/" }; - // ../../../node_modules/d3-selection/src/namespace.js + // node_modules/d3-selection/src/namespace.js function namespace_default(name) { var prefix = name += "", i = prefix.indexOf(":"); if (i >= 0 && (prefix = name.slice(0, i)) !== "xmlns") name = name.slice(i + 1); return namespaces_default.hasOwnProperty(prefix) ? { space: namespaces_default[prefix], local: name } : name; } - // ../../../node_modules/d3-selection/src/creator.js + // node_modules/d3-selection/src/creator.js function creatorInherit(name) { return function() { var document2 = this.ownerDocument, uri = this.namespaceURI; @@ -80,7 +80,7 @@ var KimaiHeatmap = (() => { return (fullname.local ? creatorFixed : creatorInherit)(fullname); } - // ../../../node_modules/d3-selection/src/selector.js + // node_modules/d3-selection/src/selector.js function none() { } function selector_default(selector) { @@ -89,7 +89,7 @@ var KimaiHeatmap = (() => { }; } - // ../../../node_modules/d3-selection/src/selection/select.js + // node_modules/d3-selection/src/selection/select.js function select_default(select) { if (typeof select !== "function") select = selector_default(select); for (var groups = this._groups, m = groups.length, subgroups = new Array(m), j = 0; j < m; ++j) { @@ -103,12 +103,12 @@ var KimaiHeatmap = (() => { return new Selection(subgroups, this._parents); } - // ../../../node_modules/d3-selection/src/array.js + // node_modules/d3-selection/src/array.js function array(x) { return x == null ? [] : Array.isArray(x) ? x : Array.from(x); } - // ../../../node_modules/d3-selection/src/selectorAll.js + // node_modules/d3-selection/src/selectorAll.js function empty() { return []; } @@ -118,7 +118,7 @@ var KimaiHeatmap = (() => { }; } - // ../../../node_modules/d3-selection/src/selection/selectAll.js + // node_modules/d3-selection/src/selection/selectAll.js function arrayAll(select) { return function() { return array(select.apply(this, arguments)); @@ -138,7 +138,7 @@ var KimaiHeatmap = (() => { return new Selection(subgroups, parents); } - // ../../../node_modules/d3-selection/src/matcher.js + // node_modules/d3-selection/src/matcher.js function matcher_default(selector) { return function() { return this.matches(selector); @@ -150,7 +150,7 @@ var KimaiHeatmap = (() => { }; } - // ../../../node_modules/d3-selection/src/selection/selectChild.js + // node_modules/d3-selection/src/selection/selectChild.js var find = Array.prototype.find; function childFind(match) { return function() { @@ -164,7 +164,7 @@ var KimaiHeatmap = (() => { return this.select(match == null ? childFirst : childFind(typeof match === "function" ? match : childMatcher(match))); } - // ../../../node_modules/d3-selection/src/selection/selectChildren.js + // node_modules/d3-selection/src/selection/selectChildren.js var filter = Array.prototype.filter; function children() { return Array.from(this.children); @@ -178,7 +178,7 @@ var KimaiHeatmap = (() => { return this.selectAll(match == null ? children : childrenFilter(typeof match === "function" ? match : childMatcher(match))); } - // ../../../node_modules/d3-selection/src/selection/filter.js + // node_modules/d3-selection/src/selection/filter.js function filter_default(match) { if (typeof match !== "function") match = matcher_default(match); for (var groups = this._groups, m = groups.length, subgroups = new Array(m), j = 0; j < m; ++j) { @@ -191,12 +191,12 @@ var KimaiHeatmap = (() => { return new Selection(subgroups, this._parents); } - // ../../../node_modules/d3-selection/src/selection/sparse.js + // node_modules/d3-selection/src/selection/sparse.js function sparse_default(update) { return new Array(update.length); } - // ../../../node_modules/d3-selection/src/selection/enter.js + // node_modules/d3-selection/src/selection/enter.js function enter_default() { return new Selection(this._enter || this._groups.map(sparse_default), this._parents); } @@ -223,14 +223,14 @@ var KimaiHeatmap = (() => { } }; - // ../../../node_modules/d3-selection/src/constant.js + // node_modules/d3-selection/src/constant.js function constant_default(x) { return function() { return x; }; } - // ../../../node_modules/d3-selection/src/selection/data.js + // node_modules/d3-selection/src/selection/data.js function bindIndex(parent, group, enter, update, exit, data) { var i = 0, node, groupLength = group.length, dataLength = data.length; for (; i < dataLength; ++i) { @@ -302,12 +302,12 @@ var KimaiHeatmap = (() => { return typeof data === "object" && "length" in data ? data : Array.from(data); } - // ../../../node_modules/d3-selection/src/selection/exit.js + // node_modules/d3-selection/src/selection/exit.js function exit_default() { return new Selection(this._exit || this._groups.map(sparse_default), this._parents); } - // ../../../node_modules/d3-selection/src/selection/join.js + // node_modules/d3-selection/src/selection/join.js function join_default(onenter, onupdate, onexit) { var enter = this.enter(), update = this, exit = this.exit(); if (typeof onenter === "function") { @@ -325,7 +325,7 @@ var KimaiHeatmap = (() => { return enter && update ? enter.merge(update).order() : update; } - // ../../../node_modules/d3-selection/src/selection/merge.js + // node_modules/d3-selection/src/selection/merge.js function merge_default(context) { var selection2 = context.selection ? context.selection() : context; for (var groups0 = this._groups, groups1 = selection2._groups, m0 = groups0.length, m1 = groups1.length, m = Math.min(m0, m1), merges = new Array(m0), j = 0; j < m; ++j) { @@ -341,7 +341,7 @@ var KimaiHeatmap = (() => { return new Selection(merges, this._parents); } - // ../../../node_modules/d3-selection/src/selection/order.js + // node_modules/d3-selection/src/selection/order.js function order_default() { for (var groups = this._groups, j = -1, m = groups.length; ++j < m; ) { for (var group = groups[j], i = group.length - 1, next = group[i], node; --i >= 0; ) { @@ -354,7 +354,7 @@ var KimaiHeatmap = (() => { return this; } - // ../../../node_modules/d3-selection/src/selection/sort.js + // node_modules/d3-selection/src/selection/sort.js function sort_default(compare) { if (!compare) compare = ascending; function compareNode(a, b) { @@ -374,7 +374,7 @@ var KimaiHeatmap = (() => { return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN; } - // ../../../node_modules/d3-selection/src/selection/call.js + // node_modules/d3-selection/src/selection/call.js function call_default() { var callback = arguments[0]; arguments[0] = this; @@ -382,12 +382,12 @@ var KimaiHeatmap = (() => { return this; } - // ../../../node_modules/d3-selection/src/selection/nodes.js + // node_modules/d3-selection/src/selection/nodes.js function nodes_default() { return Array.from(this); } - // ../../../node_modules/d3-selection/src/selection/node.js + // node_modules/d3-selection/src/selection/node.js function node_default() { for (var groups = this._groups, j = 0, m = groups.length; j < m; ++j) { for (var group = groups[j], i = 0, n = group.length; i < n; ++i) { @@ -398,19 +398,19 @@ var KimaiHeatmap = (() => { return null; } - // ../../../node_modules/d3-selection/src/selection/size.js + // node_modules/d3-selection/src/selection/size.js function size_default() { let size = 0; for (const node of this) ++size; return size; } - // ../../../node_modules/d3-selection/src/selection/empty.js + // node_modules/d3-selection/src/selection/empty.js function empty_default() { return !this.node(); } - // ../../../node_modules/d3-selection/src/selection/each.js + // node_modules/d3-selection/src/selection/each.js function each_default(callback) { for (var groups = this._groups, j = 0, m = groups.length; j < m; ++j) { for (var group = groups[j], i = 0, n = group.length, node; i < n; ++i) { @@ -420,7 +420,7 @@ var KimaiHeatmap = (() => { return this; } - // ../../../node_modules/d3-selection/src/selection/attr.js + // node_modules/d3-selection/src/selection/attr.js function attrRemove(name) { return function() { this.removeAttribute(name); @@ -464,12 +464,12 @@ var KimaiHeatmap = (() => { return this.each((value == null ? fullname.local ? attrRemoveNS : attrRemove : typeof value === "function" ? fullname.local ? attrFunctionNS : attrFunction : fullname.local ? attrConstantNS : attrConstant)(fullname, value)); } - // ../../../node_modules/d3-selection/src/window.js + // node_modules/d3-selection/src/window.js function window_default(node) { return node.ownerDocument && node.ownerDocument.defaultView || node.document && node || node.defaultView; } - // ../../../node_modules/d3-selection/src/selection/style.js + // node_modules/d3-selection/src/selection/style.js function styleRemove(name) { return function() { this.style.removeProperty(name); @@ -494,7 +494,7 @@ var KimaiHeatmap = (() => { return node.style.getPropertyValue(name) || window_default(node).getComputedStyle(node, null).getPropertyValue(name); } - // ../../../node_modules/d3-selection/src/selection/property.js + // node_modules/d3-selection/src/selection/property.js function propertyRemove(name) { return function() { delete this[name]; @@ -516,7 +516,7 @@ var KimaiHeatmap = (() => { return arguments.length > 1 ? this.each((value == null ? propertyRemove : typeof value === "function" ? propertyFunction : propertyConstant)(name, value)) : this.node()[name]; } - // ../../../node_modules/d3-selection/src/selection/classed.js + // node_modules/d3-selection/src/selection/classed.js function classArray(string) { return string.trim().split(/^|\s+/); } @@ -579,7 +579,7 @@ var KimaiHeatmap = (() => { return this.each((typeof value === "function" ? classedFunction : value ? classedTrue : classedFalse)(names, value)); } - // ../../../node_modules/d3-selection/src/selection/text.js + // node_modules/d3-selection/src/selection/text.js function textRemove() { this.textContent = ""; } @@ -598,7 +598,7 @@ var KimaiHeatmap = (() => { return arguments.length ? this.each(value == null ? textRemove : (typeof value === "function" ? textFunction : textConstant)(value)) : this.node().textContent; } - // ../../../node_modules/d3-selection/src/selection/html.js + // node_modules/d3-selection/src/selection/html.js function htmlRemove() { this.innerHTML = ""; } @@ -617,7 +617,7 @@ var KimaiHeatmap = (() => { return arguments.length ? this.each(value == null ? htmlRemove : (typeof value === "function" ? htmlFunction : htmlConstant)(value)) : this.node().innerHTML; } - // ../../../node_modules/d3-selection/src/selection/raise.js + // node_modules/d3-selection/src/selection/raise.js function raise() { if (this.nextSibling) this.parentNode.appendChild(this); } @@ -625,7 +625,7 @@ var KimaiHeatmap = (() => { return this.each(raise); } - // ../../../node_modules/d3-selection/src/selection/lower.js + // node_modules/d3-selection/src/selection/lower.js function lower() { if (this.previousSibling) this.parentNode.insertBefore(this, this.parentNode.firstChild); } @@ -633,7 +633,7 @@ var KimaiHeatmap = (() => { return this.each(lower); } - // ../../../node_modules/d3-selection/src/selection/append.js + // node_modules/d3-selection/src/selection/append.js function append_default(name) { var create = typeof name === "function" ? name : creator_default(name); return this.select(function() { @@ -641,7 +641,7 @@ var KimaiHeatmap = (() => { }); } - // ../../../node_modules/d3-selection/src/selection/insert.js + // node_modules/d3-selection/src/selection/insert.js function constantNull() { return null; } @@ -652,7 +652,7 @@ var KimaiHeatmap = (() => { }); } - // ../../../node_modules/d3-selection/src/selection/remove.js + // node_modules/d3-selection/src/selection/remove.js function remove() { var parent = this.parentNode; if (parent) parent.removeChild(this); @@ -661,7 +661,7 @@ var KimaiHeatmap = (() => { return this.each(remove); } - // ../../../node_modules/d3-selection/src/selection/clone.js + // node_modules/d3-selection/src/selection/clone.js function selection_cloneShallow() { var clone = this.cloneNode(false), parent = this.parentNode; return parent ? parent.insertBefore(clone, this.nextSibling) : clone; @@ -674,12 +674,12 @@ var KimaiHeatmap = (() => { return this.select(deep ? selection_cloneDeep : selection_cloneShallow); } - // ../../../node_modules/d3-selection/src/selection/datum.js + // node_modules/d3-selection/src/selection/datum.js function datum_default(value) { return arguments.length ? this.property("__data__", value) : this.node().__data__; } - // ../../../node_modules/d3-selection/src/selection/on.js + // node_modules/d3-selection/src/selection/on.js function contextListener(listener) { return function(event) { listener.call(this, event, this.__data__); @@ -742,7 +742,7 @@ var KimaiHeatmap = (() => { return this; } - // ../../../node_modules/d3-selection/src/selection/dispatch.js + // node_modules/d3-selection/src/selection/dispatch.js function dispatchEvent(node, type, params) { var window2 = window_default(node), event = window2.CustomEvent; if (typeof event === "function") { @@ -768,7 +768,7 @@ var KimaiHeatmap = (() => { return this.each((typeof params === "function" ? dispatchFunction : dispatchConstant)(type, params)); } - // ../../../node_modules/d3-selection/src/selection/iterator.js + // node_modules/d3-selection/src/selection/iterator.js function* iterator_default() { for (var groups = this._groups, j = 0, m = groups.length; j < m; ++j) { for (var group = groups[j], i = 0, n = group.length, node; i < n; ++i) { @@ -777,7 +777,7 @@ var KimaiHeatmap = (() => { } } - // ../../../node_modules/d3-selection/src/selection/index.js + // node_modules/d3-selection/src/selection/index.js var root = [null]; function Selection(groups, parents) { this._groups = groups; @@ -828,12 +828,12 @@ var KimaiHeatmap = (() => { [Symbol.iterator]: iterator_default }; - // ../../../node_modules/d3-selection/src/select.js + // node_modules/d3-selection/src/select.js function select_default2(selector) { return typeof selector === "string" ? new Selection([[document.querySelector(selector)]], [document.documentElement]) : new Selection([[selector]], root); } - // ../../../node_modules/d3-time/src/interval.js + // node_modules/d3-time/src/interval.js var t0 = /* @__PURE__ */ new Date(); var t1 = /* @__PURE__ */ new Date(); function timeInterval(floori, offseti, count, field) { @@ -894,7 +894,7 @@ var KimaiHeatmap = (() => { return interval; } - // ../../../node_modules/d3-time/src/duration.js + // node_modules/d3-time/src/duration.js var durationSecond = 1e3; var durationMinute = durationSecond * 60; var durationHour = durationMinute * 60; @@ -903,7 +903,7 @@ var KimaiHeatmap = (() => { var durationMonth = durationDay * 30; var durationYear = durationDay * 365; - // ../../../node_modules/d3-time/src/day.js + // node_modules/d3-time/src/day.js var timeDay = timeInterval( (date) => date.setHours(0, 0, 0, 0), (date, step) => date.setDate(date.getDate() + step), @@ -932,7 +932,7 @@ var KimaiHeatmap = (() => { }); var unixDays = unixDay.range; - // ../../../node_modules/d3-time/src/week.js + // node_modules/d3-time/src/week.js function timeWeekday(i) { return timeInterval((date) => { date.setDate(date.getDate() - (date.getDay() + 7 - i) % 7); @@ -982,7 +982,7 @@ var KimaiHeatmap = (() => { var utcFridays = utcFriday.range; var utcSaturdays = utcSaturday.range; - // ../../../node_modules/d3-time/src/month.js + // node_modules/d3-time/src/month.js var timeMonth = timeInterval((date) => { date.setDate(1); date.setHours(0, 0, 0, 0); @@ -1006,7 +1006,7 @@ var KimaiHeatmap = (() => { }); var utcMonths = utcMonth.range; - // ../../../node_modules/d3-time/src/year.js + // node_modules/d3-time/src/year.js var timeYear = timeInterval((date) => { date.setMonth(0, 1); date.setHours(0, 0, 0, 0); @@ -1048,17 +1048,17 @@ var KimaiHeatmap = (() => { }; var utcYears = utcYear.range; - // ../../../node_modules/d3-array/src/ascending.js + // node_modules/d3-array/src/ascending.js function ascending2(a, b) { return a == null || b == null ? NaN : a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN; } - // ../../../node_modules/d3-array/src/descending.js + // node_modules/d3-array/src/descending.js function descending(a, b) { return a == null || b == null ? NaN : b < a ? -1 : b > a ? 1 : b >= a ? 0 : NaN; } - // ../../../node_modules/d3-array/src/bisector.js + // node_modules/d3-array/src/bisector.js function bisector(f) { let compare1, compare2, delta; if (f.length !== 2) { @@ -1102,19 +1102,19 @@ var KimaiHeatmap = (() => { return 0; } - // ../../../node_modules/d3-array/src/number.js + // node_modules/d3-array/src/number.js function number(x) { return x === null ? NaN : +x; } - // ../../../node_modules/d3-array/src/bisect.js + // node_modules/d3-array/src/bisect.js var ascendingBisect = bisector(ascending2); var bisectRight = ascendingBisect.right; var bisectLeft = ascendingBisect.left; var bisectCenter = bisector(number).center; var bisect_default = bisectRight; - // ../../../node_modules/d3-array/src/ticks.js + // node_modules/d3-array/src/ticks.js var e10 = Math.sqrt(50); var e5 = Math.sqrt(10); var e2 = Math.sqrt(2); @@ -1164,7 +1164,7 @@ var KimaiHeatmap = (() => { return (reverse ? -1 : 1) * (inc < 0 ? 1 / -inc : inc); } - // ../../../node_modules/d3-array/src/max.js + // node_modules/d3-array/src/max.js function max(values, valueof) { let max2; if (valueof === void 0) { @@ -1204,7 +1204,7 @@ var KimaiHeatmap = (() => { tip.style.display = "none"; } - // ../../../node_modules/d3-scale/src/init.js + // node_modules/d3-scale/src/init.js function initRange(domain, range) { switch (arguments.length) { case 0: @@ -1219,7 +1219,7 @@ var KimaiHeatmap = (() => { return this; } - // ../../../node_modules/d3-format/src/formatDecimal.js + // node_modules/d3-format/src/formatDecimal.js function formatDecimal_default(x) { return Math.abs(x = Math.round(x)) >= 1e21 ? x.toLocaleString("en").replace(/,/g, "") : x.toString(10); } @@ -1232,12 +1232,12 @@ var KimaiHeatmap = (() => { ]; } - // ../../../node_modules/d3-format/src/exponent.js + // node_modules/d3-format/src/exponent.js function exponent_default(x) { return x = formatDecimalParts(Math.abs(x)), x ? x[1] : NaN; } - // ../../../node_modules/d3-format/src/formatGroup.js + // node_modules/d3-format/src/formatGroup.js function formatGroup_default(grouping, thousands) { return function(value, width) { var i = value.length, t = [], j = 0, g = grouping[0], length = 0; @@ -1251,7 +1251,7 @@ var KimaiHeatmap = (() => { }; } - // ../../../node_modules/d3-format/src/formatNumerals.js + // node_modules/d3-format/src/formatNumerals.js function formatNumerals_default(numerals) { return function(value) { return value.replace(/[0-9]/g, function(i) { @@ -1260,7 +1260,7 @@ var KimaiHeatmap = (() => { }; } - // ../../../node_modules/d3-format/src/formatSpecifier.js + // node_modules/d3-format/src/formatSpecifier.js var re = /^(?:(.)?([<>=^]))?([+\-( ])?([$#])?(0)?(\d+)?(,)?(\.\d+)?(~)?([a-z%])?$/i; function formatSpecifier(specifier) { if (!(match = re.exec(specifier))) throw new Error("invalid format: " + specifier); @@ -1295,7 +1295,7 @@ var KimaiHeatmap = (() => { return this.fill + this.align + this.sign + this.symbol + (this.zero ? "0" : "") + (this.width === void 0 ? "" : Math.max(1, this.width | 0)) + (this.comma ? "," : "") + (this.precision === void 0 ? "" : "." + Math.max(0, this.precision | 0)) + (this.trim ? "~" : "") + this.type; }; - // ../../../node_modules/d3-format/src/formatTrim.js + // node_modules/d3-format/src/formatTrim.js function formatTrim_default(s) { out: for (var n = s.length, i = 1, i0 = -1, i1; i < n; ++i) { switch (s[i]) { @@ -1315,7 +1315,7 @@ var KimaiHeatmap = (() => { return i0 > 0 ? s.slice(0, i0) + s.slice(i1 + 1) : s; } - // ../../../node_modules/d3-format/src/formatPrefixAuto.js + // node_modules/d3-format/src/formatPrefixAuto.js var prefixExponent; function formatPrefixAuto_default(x, p) { var d = formatDecimalParts(x, p); @@ -1324,7 +1324,7 @@ var KimaiHeatmap = (() => { return i === n ? coefficient : i > n ? coefficient + new Array(i - n + 1).join("0") : i > 0 ? coefficient.slice(0, i) + "." + coefficient.slice(i) : "0." + new Array(1 - i).join("0") + formatDecimalParts(x, Math.max(0, p + i - 1))[0]; } - // ../../../node_modules/d3-format/src/formatRounded.js + // node_modules/d3-format/src/formatRounded.js function formatRounded_default(x, p) { var d = formatDecimalParts(x, p); if (!d) return x + ""; @@ -1332,7 +1332,7 @@ var KimaiHeatmap = (() => { return exponent < 0 ? "0." + new Array(-exponent).join("0") + coefficient : coefficient.length > exponent + 1 ? coefficient.slice(0, exponent + 1) + "." + coefficient.slice(exponent + 1) : coefficient + new Array(exponent - coefficient.length + 2).join("0"); } - // ../../../node_modules/d3-format/src/formatTypes.js + // node_modules/d3-format/src/formatTypes.js var formatTypes_default = { "%": (x, p) => (x * 100).toFixed(p), "b": (x) => Math.round(x).toString(2), @@ -1349,12 +1349,12 @@ var KimaiHeatmap = (() => { "x": (x) => Math.round(x).toString(16) }; - // ../../../node_modules/d3-format/src/identity.js + // node_modules/d3-format/src/identity.js function identity_default(x) { return x; } - // ../../../node_modules/d3-format/src/locale.js + // node_modules/d3-format/src/locale.js var map = Array.prototype.map; var prefixes = ["y", "z", "a", "f", "p", "n", "\xB5", "m", "", "k", "M", "G", "T", "P", "E", "Z", "Y"]; function locale_default(locale3) { @@ -1428,7 +1428,7 @@ var KimaiHeatmap = (() => { }; } - // ../../../node_modules/d3-format/src/defaultLocale.js + // node_modules/d3-format/src/defaultLocale.js var locale; var format; var formatPrefix; @@ -1444,23 +1444,23 @@ var KimaiHeatmap = (() => { return locale; } - // ../../../node_modules/d3-format/src/precisionFixed.js + // node_modules/d3-format/src/precisionFixed.js function precisionFixed_default(step) { return Math.max(0, -exponent_default(Math.abs(step))); } - // ../../../node_modules/d3-format/src/precisionPrefix.js + // node_modules/d3-format/src/precisionPrefix.js function precisionPrefix_default(step, value) { return Math.max(0, Math.max(-8, Math.min(8, Math.floor(exponent_default(value) / 3))) * 3 - exponent_default(Math.abs(step))); } - // ../../../node_modules/d3-format/src/precisionRound.js + // node_modules/d3-format/src/precisionRound.js function precisionRound_default(step, max2) { step = Math.abs(step), max2 = Math.abs(max2) - step; return Math.max(0, exponent_default(max2) - exponent_default(step)) + 1; } - // ../../../node_modules/d3-scale/src/tickFormat.js + // node_modules/d3-scale/src/tickFormat.js function tickFormat(start, stop, count, specifier) { var step = tickStep(start, stop, count), precision; specifier = formatSpecifier(specifier == null ? ",f" : specifier); @@ -1487,7 +1487,7 @@ var KimaiHeatmap = (() => { return format(specifier); } - // ../../../node_modules/d3-scale/src/linear.js + // node_modules/d3-scale/src/linear.js function linearish(scale) { var domain = scale.domain; scale.ticks = function(count) { @@ -1534,7 +1534,7 @@ var KimaiHeatmap = (() => { return scale; } - // ../../../node_modules/d3-scale/src/quantize.js + // node_modules/d3-scale/src/quantize.js function quantize() { var x0 = 0, x1 = 1, n = 1, domain = [0.5], range = [0, 1], unknown; function scale(x) { @@ -1568,7 +1568,7 @@ var KimaiHeatmap = (() => { return initRange.apply(linearish(scale), arguments); } - // ../../../node_modules/d3-time-format/src/locale.js + // node_modules/d3-time-format/src/locale.js function localDate(d) { if (0 <= d.y && d.y < 100) { var date = new Date(-1, d.m, d.d, d.H, d.M, d.S, d.L); @@ -2109,7 +2109,7 @@ var KimaiHeatmap = (() => { return Math.floor(+d / 1e3); } - // ../../../node_modules/d3-time-format/src/defaultLocale.js + // node_modules/d3-time-format/src/defaultLocale.js var locale2; var timeFormat; var timeParse; @@ -2211,7 +2211,7 @@ var KimaiHeatmap = (() => { const numWeeks = (max(cells, (c) => c.week) ?? 0) + 1; const containerWidth = ctx.container.clientWidth || 800; const maxCellSize = 22; - const minCellSize = 10; + const minCellSize = 13; const cellSize = Math.min(maxCellSize, Math.max(minCellSize, Math.floor((containerWidth - marginLeft) / numWeeks) - cellGap)); const step = cellSize + cellGap; const svgWidth = marginLeft + numWeeks * step; @@ -2313,7 +2313,11 @@ var KimaiHeatmap = (() => { const labelHeight = 16; const totalWidth = labelWidth + 7 * (cellWidth + cellGap); const totalHeight = labelHeight + cellHeight; - const svg = select_default2(ctx.container).append("svg").attr("width", totalWidth).attr("height", totalHeight).attr("class", "heatmap-svg"); + const wrapper = document.createElement("div"); + wrapper.style.maxWidth = `${totalWidth}px`; + wrapper.style.margin = "0 auto"; + ctx.container.appendChild(wrapper); + const svg = select_default2(wrapper).append("svg").attr("width", totalWidth).attr("height", totalHeight).attr("class", "heatmap-svg"); const tooltip = this.tooltip; const metric = ctx.state.metric; aggregates.forEach((agg, i) => { @@ -2406,7 +2410,7 @@ var KimaiHeatmap = (() => { // assets/src/ui/controls.ts function createModeControl(activeMode, modes, onChange) { const nav = document.createElement("nav"); - nav.className = "nav nav-segmented"; + nav.className = "nav nav-segmented nav-sm"; nav.setAttribute("role", "tablist"); for (const m of modes) { const btn = document.createElement("button"); @@ -2432,7 +2436,6 @@ var KimaiHeatmap = (() => { { key: "hours", label: "Hours" }, { key: "count", label: "Count" } ], onChange); - nav.className = "nav nav-segmented nav-sm"; return nav; } diff --git a/assets/src/renderers/week.ts b/assets/src/renderers/week.ts index 50d3ec2..0bc6552 100644 --- a/assets/src/renderers/week.ts +++ b/assets/src/renderers/week.ts @@ -86,7 +86,12 @@ export class WeekModeRenderer implements ModeRenderer { const totalWidth = labelWidth + 7 * (cellWidth + cellGap); const totalHeight = labelHeight + cellHeight; - const svg = select(ctx.container) + const wrapper = document.createElement('div'); + wrapper.style.maxWidth = `${totalWidth}px`; + wrapper.style.margin = '0 auto'; + ctx.container.appendChild(wrapper); + + const svg = select(wrapper) .append('svg') .attr('width', totalWidth) .attr('height', totalHeight) diff --git a/assets/src/renderers/year.ts b/assets/src/renderers/year.ts index 6914805..b6ef048 100644 --- a/assets/src/renderers/year.ts +++ b/assets/src/renderers/year.ts @@ -45,7 +45,7 @@ export class YearModeRenderer implements ModeRenderer { // Compute cell size to fill available width, capped const containerWidth = ctx.container.clientWidth || 800; const maxCellSize = 22; - const minCellSize = 10; + const minCellSize = 13; const cellSize = Math.min(maxCellSize, Math.max(minCellSize, Math.floor((containerWidth - marginLeft) / numWeeks) - cellGap)); const step = cellSize + cellGap; const svgWidth = marginLeft + numWeeks * step; diff --git a/assets/src/ui/controls.ts b/assets/src/ui/controls.ts index bf67a9e..5fc45a3 100644 --- a/assets/src/ui/controls.ts +++ b/assets/src/ui/controls.ts @@ -4,7 +4,7 @@ export function createModeControl( onChange: (mode: string) => void, ): HTMLElement { const nav = document.createElement('nav'); - nav.className = 'nav nav-segmented'; + nav.className = 'nav nav-segmented nav-sm'; nav.setAttribute('role', 'tablist'); for (const m of modes) { @@ -38,6 +38,5 @@ export function createMetricControl( { key: 'hours', label: 'Hours' }, { key: 'count', label: 'Count' }, ], onChange); - nav.className = 'nav nav-segmented nav-sm'; return nav; } diff --git a/assets/test/controls.test.ts b/assets/test/controls.test.ts index 0a0f59f..72a627b 100644 --- a/assets/test/controls.test.ts +++ b/assets/test/controls.test.ts @@ -10,7 +10,7 @@ describe('createModeControl', () => { it('returns a nav element with nav-segmented class and tablist role', () => { const nav = createModeControl('year', modes, () => {}); expect(nav.tagName).toBe('NAV'); - expect(nav.className).toBe('nav nav-segmented'); + expect(nav.className).toBe('nav nav-segmented nav-sm'); expect(nav.getAttribute('role')).toBe('tablist'); });