{label}

{#if latest}
{formatMetric(metric, latest.y)} {#if delta !== null} {delta > 0 ? '▲' : delta < 0 ? '▼' : '•'} {Math.abs(delta).toFixed(1)}% {/if} {#if rangeDelta !== null} {rangeDelta > 0 ? '▲' : rangeDelta < 0 ? '▼' : '•'} {Math.abs(rangeDelta).toFixed(1)}% over range {/if}
{/if}
{#if allPoints.length === 0}
No data for current filters
{:else}
{ tip = null highlight = null }} > {#each domain.ticks as tick (tick)} {formatTick(metric, tick, domain.step)} {/each} {#each xTicks as tick (tick)} {fmtDate(tick)} {/each} {#each series as s (s.name)} {@const color = colorFor(s.name)} (highlight = s.name)} onmouseleave={() => (highlight = null)} > {#if s.points.length > 1} {/if} {#each s.points as p, j (p.t)} showTip(e, s, p, j)} onmousemove={(e) => showTip(e, s, p, j)} onmouseleave={() => (tip = null)} > {s.name} — {p.date}: {formatMetric(metric, p.y)}{p.commits ? ` @ ${p.commits.join(', ')}` : ''} {/each} {/each} {#each endLabels as el (el.name)} {el.text} {/each} {#if tip} {/if}
{#each series as s (s.name)} {@const last = s.points[s.points.length - 1]} {@const prev = s.points[s.points.length - 2]} {@const d = last && prev && prev.y !== 0 ? ((last.y - prev.y) / prev.y) * 100 : null} (highlight = s.name)} onmouseleave={() => (highlight = null)} > {s.name} {#if last} {formatMetric(metric, last.y)} {#if d !== null} 0)} class:bad={d !== 0 && (lowerIsBetter ? d > 0 : d < 0)} >{d > 0 ? '▲' : d < 0 ? '▼' : '•'}{Math.abs(d).toFixed(1)}% {/if} {/if} {/each}
{/if}