правки по графикам
Gitea Actions Demo / build_and_push (push) Failing after 23s
Details
Gitea Actions Demo / build_and_push (push) Failing after 23s
Details
This commit is contained in:
parent
43354ecaed
commit
2cfd863dbf
|
|
@ -50,14 +50,31 @@ export class ChartGroup {
|
|||
) {
|
||||
continue;
|
||||
}
|
||||
// Event position must be the real pixel coordinates of the data
|
||||
// point: with a fake (0, 0) position the tooltip box on receiver
|
||||
// charts is positioned from the corner and flips/clamps near the
|
||||
// chart edges, so the hover line lagged and got stuck at borders.
|
||||
const el = chart.getDatasetMeta(0).data[dataIndex] as
|
||||
{ x?: number; y?: number } | undefined;
|
||||
const px = el?.x;
|
||||
const py = el?.y;
|
||||
const pos =
|
||||
px !== undefined &&
|
||||
py !== undefined &&
|
||||
Number.isFinite(px) &&
|
||||
Number.isFinite(py)
|
||||
? { x: px, y: py }
|
||||
: { x: 0, y: 0 };
|
||||
chart.tooltip.setActiveElements(
|
||||
[{ datasetIndex: 0, index: dataIndex }],
|
||||
{
|
||||
x: 0,
|
||||
y: 0,
|
||||
},
|
||||
pos,
|
||||
);
|
||||
chart.draw();
|
||||
// update("none") = full recompute + render without animations; the
|
||||
// animator does not start, so tooltip.opacity/position apply
|
||||
// synchronously and the blue line is visible on "cold" charts
|
||||
// immediately (with chart.draw() the opacity stayed 0 until the
|
||||
// first animation tick).
|
||||
chart.update("none");
|
||||
}
|
||||
} finally {
|
||||
this.hovering = false;
|
||||
|
|
@ -81,7 +98,9 @@ export class ChartGroup {
|
|||
continue;
|
||||
}
|
||||
chart.tooltip.setActiveElements([], { x: 0, y: 0 });
|
||||
chart.draw();
|
||||
// Same as in setHover: opacity -> 0 must apply synchronously,
|
||||
// otherwise the lines would linger until the animator starts.
|
||||
chart.update("none");
|
||||
}
|
||||
} finally {
|
||||
this.hovering = false;
|
||||
|
|
|
|||
|
|
@ -119,8 +119,8 @@ export const GetWorkout = (url: string) => {
|
|||
yAxisID: "logAxis",
|
||||
radius: 0,
|
||||
label: "Мощность",
|
||||
borderColor: "#cccccc",
|
||||
backgroundColor: "#cccccc",
|
||||
borderColor: "#00bcd4",
|
||||
backgroundColor: "#00bcd4",
|
||||
data: power,
|
||||
},
|
||||
],
|
||||
|
|
|
|||
|
|
@ -3,8 +3,6 @@ import { Ref } from "vue";
|
|||
import { createTypedChart } from "vue-chartjs";
|
||||
import { LineController } from "chart.js";
|
||||
|
||||
const lineAlign = 8;
|
||||
|
||||
type GetMapPlugin = {
|
||||
mapX: Ref<Array<number>>;
|
||||
};
|
||||
|
|
@ -55,21 +53,28 @@ class LineWithLineController extends LineController {
|
|||
ctx.stroke();
|
||||
ctx.restore();
|
||||
}
|
||||
// Draw the vertical hover line at the pixel X of the active tooltip
|
||||
// element (the data point itself), not at the tooltip box position:
|
||||
// the box has a fixed size and flips/clamps near the chart edges, so
|
||||
// using tooltip.x would lag and get stuck at the borders.
|
||||
if (this.chart?.tooltip && this.chart.tooltip.opacity > 0) {
|
||||
let x = this.chart.tooltip.x - lineAlign;
|
||||
if (this.chart.tooltip.xAlign === "right") {
|
||||
x = this.chart.tooltip.x + this.chart.tooltip.width + lineAlign;
|
||||
const active = this.chart.tooltip.getActiveElements();
|
||||
const point = active[0]
|
||||
? (this.chart.getDatasetMeta(active[0].datasetIndex).data[
|
||||
active[0].index
|
||||
] as { x?: number } | undefined)
|
||||
: undefined;
|
||||
const x = point?.x ?? NaN;
|
||||
if (Number.isFinite(x)) {
|
||||
ctx.save();
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(x, topY);
|
||||
ctx.lineTo(x, bottomY);
|
||||
ctx.lineWidth = 1;
|
||||
ctx.strokeStyle = "#07C";
|
||||
ctx.stroke();
|
||||
ctx.restore();
|
||||
}
|
||||
|
||||
// draw line
|
||||
ctx.save();
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(x, topY);
|
||||
ctx.lineTo(x, bottomY);
|
||||
ctx.lineWidth = 1;
|
||||
ctx.strokeStyle = "#07C";
|
||||
ctx.stroke();
|
||||
ctx.restore();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -129,6 +129,15 @@
|
|||
{{ Math.floor(workoutItem.power) }} Вт
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="workout-item-params"
|
||||
v-if="workoutItem.power && workoutNP !== null"
|
||||
>
|
||||
<div class="workout-item-params-name">Нормализованная мощность:</div>
|
||||
<div class="workout-item-params-value">
|
||||
{{ Math.floor(workoutNP) }} Вт
|
||||
</div>
|
||||
</div>
|
||||
<div class="workout-item-params" v-if="workoutItem.max_power">
|
||||
<div class="workout-item-params-name">Максимальная мощность:</div>
|
||||
<div class="workout-item-params-value">
|
||||
|
|
@ -311,6 +320,7 @@ import {
|
|||
|
||||
import LineWithLineChart from "./LineWithLineChart.js";
|
||||
import ChartGroup from "./ChartGroup.js";
|
||||
import { normalizedPower } from "./NormalizedPower.js";
|
||||
import {
|
||||
PowerZonesPlugin,
|
||||
ftpToZones,
|
||||
|
|
@ -440,6 +450,13 @@ const computeAreaData = (start: number, end: number) => {
|
|||
Math.floor(sum / present.length).toString() +
|
||||
getUnit(config.data.datasets[0].label);
|
||||
}
|
||||
if (data.power?.datasets[0].data && end - start >= 2) {
|
||||
const np = normalizedPower(times, data.power.datasets[0].data, start, end);
|
||||
if (np !== null) {
|
||||
avgData["Нормализованная мощность"] =
|
||||
Math.floor(np).toString() + getUnit("Мощность");
|
||||
}
|
||||
}
|
||||
areaAvgData.value = avgData;
|
||||
};
|
||||
/** Splits the points into sections: 10-minute steps in time mode, 5-km steps in distance mode. */
|
||||
|
|
@ -889,6 +906,11 @@ const times: Array<string | number> =
|
|||
data.power?.labels ??
|
||||
data.elevation?.labels ??
|
||||
[];
|
||||
// Normalized power for the whole workout (data is static after load, so a
|
||||
// plain computed is memoized automatically).
|
||||
const workoutNP = computed<number | null>(() =>
|
||||
normalizedPower(times, data.power?.datasets[0].data ?? [], 0, times.length),
|
||||
);
|
||||
// Rebuilt per x-axis mode: labels switch between times and distances and
|
||||
// options get a fresh x-scale, so every canvas must remount on mode change.
|
||||
const chartConfigs = computed<Array<ChartConfig>>(() => {
|
||||
|
|
|
|||
Loading…
Reference in New Issue