изменение интерфейса тренировок
Gitea Actions Demo / build_and_push (push) Successful in 44s Details

This commit is contained in:
artem 2026-09-05 23:42:04 +03:00
parent b4f3a762b0
commit 17120b4852
2 changed files with 66 additions and 19 deletions

View File

@ -8,6 +8,10 @@ import { resetZoom } from "chartjs-plugin-zoom";
export class ChartGroup { export class ChartGroup {
charts: Array<Chart>; charts: Array<Chart>;
private broadcasting = false; private broadcasting = false;
// Guards against re-entrant hover propagation: activating a tooltip on the
// source chart redraws it synchronously, which re-invokes its tooltip
// callbacks -> setHover -> infinite recursion.
private hovering = false;
constructor(charts: Array<Chart>) { constructor(charts: Array<Chart>) {
this.charts = charts; this.charts = charts;
@ -27,25 +31,60 @@ export class ChartGroup {
* the same point order (a common time axis), so the index is identical. * the same point order (a common time axis), so the index is identical.
*/ */
setHover(dataIndex: number): void { setHover(dataIndex: number): void {
for (const chart of this.charts) { if (this.hovering) {
if (!chart.tooltip) { return;
continue; }
this.hovering = true;
try {
for (const chart of this.charts) {
if (!chart.tooltip) {
continue;
}
// Optimization: skip charts whose tooltip is already active at the
// same index so the source chart is not redrawn twice per hover move.
const active = chart.tooltip.getActiveElements();
if (
active.length === 1 &&
active[0].index === dataIndex &&
active[0].datasetIndex === 0
) {
continue;
}
chart.tooltip.setActiveElements(
[{ datasetIndex: 0, index: dataIndex }],
{
x: 0,
y: 0,
},
);
chart.draw();
} }
chart.tooltip.setActiveElements([{ datasetIndex: 0, index: dataIndex }], { } finally {
x: 0, this.hovering = false;
y: 0,
});
chart.draw();
} }
} }
/**
* Clears the hover state on every chart. Idempotent; safe to call from
* mouseout at any time. Guarded by the same re-entrancy flag as setHover:
* if invoked while setHover is in progress, the caller's own setHover will
* have (re)established the correct state, so an early return loses nothing.
*/
clearHover(): void { clearHover(): void {
for (const chart of this.charts) { if (this.hovering) {
if (!chart.tooltip) { return;
continue; }
this.hovering = true;
try {
for (const chart of this.charts) {
if (!chart.tooltip) {
continue;
}
chart.tooltip.setActiveElements([], { x: 0, y: 0 });
chart.draw();
} }
chart.tooltip.setActiveElements([], { x: 0, y: 0 }); } finally {
chart.draw(); this.hovering = false;
} }
} }

View File

@ -231,12 +231,14 @@
</span> </span>
</span> </span>
</h4> </h4>
<LineWithLineChart <div class="workout-chart-canvas">
:ref="(el) => setChartRef(config.key, el)" <LineWithLineChart
:options="config.options" :ref="(el) => setChartRef(config.key, el)"
:plugins="chartPlugins" :options="config.options"
:data="config.data" :plugins="chartPlugins"
/> :data="config.data"
/>
</div>
</div> </div>
</div> </div>
<VaModal <VaModal
@ -646,6 +648,7 @@ const buildChartOptions = (
duration: 0, duration: 0,
}, },
responsive: true, responsive: true,
maintainAspectRatio: false,
scales: scales, scales: scales,
plugins: { plugins: {
tooltip: { tooltip: {
@ -1132,6 +1135,11 @@ h3 {
.workout-chart { .workout-chart {
width: 100%; width: 100%;
} }
.workout-chart-canvas {
position: relative;
width: 100%;
height: 160px;
}
.workout-chart-title { .workout-chart-title {
margin: 0 0 5px 0; margin: 0 0 5px 0;
font-size: 16px; font-size: 16px;