f9420e5848
Co-authored-by: Janis Eccarius <eccariusjanis@gmail.com> Reviewed-on: #11
74 lines
2.0 KiB
TypeScript
74 lines
2.0 KiB
TypeScript
import { Component, Input, OnChanges } from '@angular/core';
|
|
import { AnnotatedMove } from '../../models/analysis.models';
|
|
|
|
interface TimelinePoint {
|
|
x: number;
|
|
y: number;
|
|
eval: number;
|
|
san: string;
|
|
plyIndex: number;
|
|
}
|
|
|
|
const CLAMP = 5; // clamp eval to ±5 pawns for display
|
|
const HEIGHT = 80;
|
|
const WIDTH = 600;
|
|
|
|
@Component({
|
|
selector: 'app-eval-timeline',
|
|
standalone: true,
|
|
imports: [],
|
|
templateUrl: './eval-timeline.component.html',
|
|
styleUrl: './eval-timeline.component.css',
|
|
})
|
|
export class EvalTimelineComponent implements OnChanges {
|
|
@Input({ required: true }) moves: AnnotatedMove[] = [];
|
|
@Input() activePly: number | null = null;
|
|
|
|
points: TimelinePoint[] = [];
|
|
evalPolyline = '';
|
|
polylineWhite = '';
|
|
polylineBlack = '';
|
|
svgWidth = WIDTH;
|
|
svgHeight = HEIGHT;
|
|
|
|
ngOnChanges(): void {
|
|
this.buildChart();
|
|
}
|
|
|
|
activeX(): number | null {
|
|
if (this.activePly === null) return null;
|
|
const pt = this.points[this.activePly];
|
|
return pt ? pt.x : null;
|
|
}
|
|
|
|
private buildChart(): void {
|
|
if (this.moves.length === 0) {
|
|
this.points = [];
|
|
this.evalPolyline = '';
|
|
this.polylineWhite = '';
|
|
this.polylineBlack = '';
|
|
return;
|
|
}
|
|
|
|
const total = this.moves.length;
|
|
this.points = this.moves.map((m, i) => {
|
|
const evalValue = m.evalAfter ?? 0;
|
|
const clamped = Math.max(-CLAMP, Math.min(CLAMP, evalValue));
|
|
const x = (i / Math.max(total - 1, 1)) * WIDTH;
|
|
// y=0 => white winning (top), y=HEIGHT => black winning (bottom)
|
|
const y = ((CLAMP - clamped) / (CLAMP * 2)) * HEIGHT;
|
|
return { x, y, eval: evalValue, san: m.san, plyIndex: i };
|
|
});
|
|
|
|
const coordStr = this.points.map((p) => `${p.x.toFixed(1)},${p.y.toFixed(1)}`).join(' ');
|
|
this.evalPolyline = coordStr;
|
|
|
|
const mid = HEIGHT / 2;
|
|
const first = this.points[0];
|
|
const last = this.points[this.points.length - 1];
|
|
|
|
this.polylineWhite = `${first.x.toFixed(1)},${mid} ${coordStr} ${last.x.toFixed(1)},${mid}`;
|
|
this.polylineBlack = this.polylineWhite;
|
|
}
|
|
}
|