Make calendar cells clickable and improve mood heatmap colors
This commit is contained in:
+28
-2
@@ -417,11 +417,19 @@ button {
|
|||||||
width: 0.8rem;
|
width: 0.8rem;
|
||||||
height: 0.8rem;
|
height: 0.8rem;
|
||||||
border-radius: 6px;
|
border-radius: 6px;
|
||||||
background: rgba(255, 255, 255, 0.08);
|
background: rgba(132, 193, 208, 0.55);
|
||||||
|
}
|
||||||
|
|
||||||
|
.calendar-dot--bad {
|
||||||
|
background: rgba(255, 117, 117, 0.85);
|
||||||
|
}
|
||||||
|
|
||||||
|
.calendar-dot--warn {
|
||||||
|
background: rgba(255, 171, 122, 0.82);
|
||||||
}
|
}
|
||||||
|
|
||||||
.calendar-dot--1 {
|
.calendar-dot--1 {
|
||||||
background: rgba(126, 239, 205, 0.32);
|
background: rgba(116, 226, 183, 0.7);
|
||||||
}
|
}
|
||||||
|
|
||||||
.calendar-dot--2 {
|
.calendar-dot--2 {
|
||||||
@@ -444,6 +452,24 @@ button {
|
|||||||
font-size: 11px;
|
font-size: 11px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.calendar-link {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.calendar-cell--active {
|
||||||
|
transition: transform 140ms ease, filter 140ms ease, stroke 140ms ease, stroke-width 140ms ease;
|
||||||
|
transform-box: fill-box;
|
||||||
|
transform-origin: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.calendar-link:hover .calendar-cell--active,
|
||||||
|
.calendar-link:focus .calendar-cell--active,
|
||||||
|
.calendar-link:focus-visible .calendar-cell--active {
|
||||||
|
filter: brightness(1.08);
|
||||||
|
stroke: rgba(255, 255, 255, 0.8);
|
||||||
|
stroke-width: 1.1;
|
||||||
|
}
|
||||||
|
|
||||||
.line-chart,
|
.line-chart,
|
||||||
.bar-chart {
|
.bar-chart {
|
||||||
min-height: 17rem;
|
min-height: 17rem;
|
||||||
|
|||||||
+43
-9
@@ -366,6 +366,32 @@
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function calendarColor(entry) {
|
||||||
|
if (!entry) {
|
||||||
|
return "rgba(255, 255, 255, 0.06)";
|
||||||
|
}
|
||||||
|
|
||||||
|
const ratio = Math.max(0, Math.min(1, Number(entry.score) / Math.max(Number(entry.max || 1), 1)));
|
||||||
|
|
||||||
|
if (ratio <= 0.36) {
|
||||||
|
return `rgba(255, 117, 117, ${0.28 + (ratio * 0.8)})`;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ratio <= 0.52) {
|
||||||
|
return `rgba(255, 171, 122, ${0.28 + (ratio * 0.7)})`;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ratio <= 0.68) {
|
||||||
|
return `rgba(132, 193, 208, ${0.24 + (ratio * 0.55)})`;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ratio <= 0.84) {
|
||||||
|
return `rgba(116, 226, 183, ${0.28 + (ratio * 0.6)})`;
|
||||||
|
}
|
||||||
|
|
||||||
|
return `rgba(112, 240, 182, ${0.38 + (ratio * 0.52)})`;
|
||||||
|
}
|
||||||
|
|
||||||
const map = new Map(items.map(item => [item.date, item]));
|
const map = new Map(items.map(item => [item.date, item]));
|
||||||
const end = new Date();
|
const end = new Date();
|
||||||
const start = new Date(end);
|
const start = new Date(end);
|
||||||
@@ -386,12 +412,13 @@
|
|||||||
cursor.setDate(cursor.getDate() + 1);
|
cursor.setDate(cursor.getDate() + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
const width = Math.ceil(days.length / 7) * 17 + 56;
|
const totalWeeks = Math.floor((days.length - 1) / 7) + 1;
|
||||||
const height = 148;
|
const height = 148;
|
||||||
const cellSize = 12;
|
const cellSize = 12;
|
||||||
const cellGap = 5;
|
const cellGap = 5;
|
||||||
const xOffset = 34;
|
const xOffset = 34;
|
||||||
const yOffset = 24;
|
const yOffset = 24;
|
||||||
|
const width = xOffset + ((totalWeeks - 1) * (cellSize + cellGap)) + cellSize + 28;
|
||||||
const monthLabels = [];
|
const monthLabels = [];
|
||||||
let lastMonth = -1;
|
let lastMonth = -1;
|
||||||
|
|
||||||
@@ -400,10 +427,7 @@
|
|||||||
const row = item.weekday === 0 ? 6 : item.weekday - 1;
|
const row = item.weekday === 0 ? 6 : item.weekday - 1;
|
||||||
const x = xOffset + (week * (cellSize + cellGap));
|
const x = xOffset + (week * (cellSize + cellGap));
|
||||||
const y = yOffset + (row * (cellSize + cellGap));
|
const y = yOffset + (row * (cellSize + cellGap));
|
||||||
const level = item.entry ? Math.max(0, Math.min(1, Number(item.entry.score) / Math.max(Number(item.entry.max || 1), 1))) : 0;
|
const fill = calendarColor(item.entry);
|
||||||
const fill = item.entry
|
|
||||||
? `rgba(126, 239, 205, ${0.18 + (level * 0.72)})`
|
|
||||||
: "rgba(255, 255, 255, 0.06)";
|
|
||||||
|
|
||||||
if (item.day <= 7 && item.month !== lastMonth) {
|
if (item.day <= 7 && item.month !== lastMonth) {
|
||||||
monthLabels.push({
|
monthLabels.push({
|
||||||
@@ -417,7 +441,16 @@
|
|||||||
? `${item.date}: ${formatNumber(Number(item.entry.score))} Punkte · ${item.entry.label}`
|
? `${item.date}: ${formatNumber(Number(item.entry.score))} Punkte · ${item.entry.label}`
|
||||||
: `${item.date}: kein Eintrag`;
|
: `${item.date}: kein Eintrag`;
|
||||||
|
|
||||||
return `<rect x="${x}" y="${y}" width="${cellSize}" height="${cellSize}" rx="4" fill="${fill}"><title>${title}</title></rect>`;
|
if (!item.entry) {
|
||||||
|
return `<rect x="${x}" y="${y}" width="${cellSize}" height="${cellSize}" rx="4" fill="${fill}"><title>${title}</title></rect>`;
|
||||||
|
}
|
||||||
|
|
||||||
|
return `
|
||||||
|
<a class="calendar-link" href="/track?date=${encodeURIComponent(item.date)}" aria-label="${title}">
|
||||||
|
<rect class="calendar-cell calendar-cell--active" x="${x}" y="${y}" width="${cellSize}" height="${cellSize}" rx="4" fill="${fill}"></rect>
|
||||||
|
<title>${title}</title>
|
||||||
|
</a>
|
||||||
|
`;
|
||||||
}).join("");
|
}).join("");
|
||||||
|
|
||||||
container.innerHTML = `
|
container.innerHTML = `
|
||||||
@@ -429,14 +462,15 @@
|
|||||||
${cells}
|
${cells}
|
||||||
</svg>
|
</svg>
|
||||||
<div class="calendar-legend">
|
<div class="calendar-legend">
|
||||||
<span>weniger</span>
|
<span>schlecht</span>
|
||||||
<div class="calendar-scale">
|
<div class="calendar-scale">
|
||||||
|
<span class="calendar-dot calendar-dot--bad"></span>
|
||||||
|
<span class="calendar-dot calendar-dot--warn"></span>
|
||||||
<span class="calendar-dot"></span>
|
<span class="calendar-dot"></span>
|
||||||
<span class="calendar-dot calendar-dot--1"></span>
|
<span class="calendar-dot calendar-dot--1"></span>
|
||||||
<span class="calendar-dot calendar-dot--2"></span>
|
|
||||||
<span class="calendar-dot calendar-dot--3"></span>
|
<span class="calendar-dot calendar-dot--3"></span>
|
||||||
</div>
|
</div>
|
||||||
<span>mehr</span>
|
<span>gut</span>
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user