feat:增加点和数字切换,减小点最大尺寸,增加range配色方案

This commit is contained in:
lenn
2026-04-09 09:17:07 +08:00
parent 1c3a811154
commit a3cefc3c79
78 changed files with 786 additions and 296 deletions

View File

@@ -7,10 +7,13 @@
export let xValues: number[] | null = null;
export let yValues: number[] | null = null;
const viewportWidth = 100;
const viewportHeight = 36;
const horizontalInset = 2;
const verticalInset = 2;
const viewportWidth = 120;
const viewportHeight = 48;
const plotInsetLeft = 13;
const plotInsetRight = 4;
const plotInsetTop = 4;
const plotInsetBottom = 9;
const fixedYBounds = { min: 0, max: 25 };
interface CurveSample {
x: number;
@@ -50,12 +53,7 @@
return String(Math.round(value));
}
if (Math.abs(value) >= 1000) {
const compact = Math.round((value / 1000) * 10) / 10;
return Number.isInteger(compact) ? `${compact.toFixed(0)}k` : `${compact.toFixed(1)}k`;
}
return Math.abs(value) >= 100 ? Math.round(value).toString() : value.toFixed(1);
return `${Math.round(value)} N`;
}
function resolveDataBounds(values: number[]): { min: number; max: number } {
@@ -87,18 +85,18 @@
function mapXToViewport(value: number, bounds: { min: number; max: number }): number {
const span = bounds.max - bounds.min;
const chartWidth = viewportWidth - horizontalInset * 2;
const chartWidth = viewportWidth - plotInsetLeft - plotInsetRight;
const ratio = span <= 0 ? 0.5 : (value - bounds.min) / span;
const mappedX = horizontalInset + ratio * chartWidth;
return Math.round(clamp(mappedX, horizontalInset, viewportWidth - horizontalInset) * 100) / 100;
const mappedX = plotInsetLeft + ratio * chartWidth;
return Math.round(clamp(mappedX, plotInsetLeft, viewportWidth - plotInsetRight) * 100) / 100;
}
function mapYToViewport(value: number, bounds: { min: number; max: number }): number {
const span = bounds.max - bounds.min;
const chartHeight = viewportHeight - verticalInset * 2;
const chartHeight = viewportHeight - plotInsetTop - plotInsetBottom;
const ratio = span <= 0 ? 0.5 : (value - bounds.min) / span;
const mappedY = viewportHeight - verticalInset - ratio * chartHeight;
return Math.round(clamp(mappedY, verticalInset, viewportHeight - verticalInset) * 100) / 100;
const mappedY = viewportHeight - plotInsetBottom - ratio * chartHeight;
return Math.round(clamp(mappedY, plotInsetTop, viewportHeight - plotInsetBottom) * 100) / 100;
}
function buildSamples(rawYValues: number[], rawXValues: number[]): CurveSample[] {
@@ -137,16 +135,13 @@
function buildYAxisTicks(
yScaleBounds: { min: number; max: number },
yDataBounds: { min: number; max: number }
_yDataBounds: { min: number; max: number }
): AxisTick[] {
const hasRange = Math.abs(yDataBounds.max - yDataBounds.min) >= 0.001;
const tickValues = hasRange
? [yDataBounds.max, (yDataBounds.max + yDataBounds.min) / 2, yDataBounds.min]
: [yScaleBounds.max, (yScaleBounds.max + yScaleBounds.min) / 2, yScaleBounds.min];
const tickValues = [25, 20, 15, 10, 5, 0];
return tickValues.map((value) => ({
value,
label: formatAxisValue(value, "y"),
plotX: horizontalInset,
plotX: plotInsetLeft - 1.8,
plotY: mapYToViewport(value, yScaleBounds)
}));
}
@@ -164,7 +159,7 @@
value,
label: formatAxisValue(value, "x"),
plotX: mapXToViewport(value, xScaleBounds),
plotY: viewportHeight - 1.2
plotY: viewportHeight - 0.9
}));
}
@@ -185,7 +180,7 @@
const firstPoint = points[0];
const lastPoint = points[points.length - 1];
return `${linePath} L ${lastPoint.x} ${viewportHeight} L ${firstPoint.x} ${viewportHeight} Z`;
return `${linePath} L ${lastPoint.x} ${viewportHeight - plotInsetBottom} L ${firstPoint.x} ${viewportHeight - plotInsetBottom} Z`;
}
$: sourceYValues = yValues && yValues.length ? yValues : summary.points;
@@ -193,7 +188,7 @@
$: samples = buildSamples(sourceYValues, sourceXValues);
$: sampleCount = samples.length;
$: xScaleBounds = resolveBounds(samples.map((sample) => sample.x));
$: yScaleBounds = resolveBounds(samples.map((sample) => sample.y));
$: yScaleBounds = fixedYBounds;
$: xDataBounds = resolveDataBounds(samples.map((sample) => sample.x));
$: yDataBounds = resolveDataBounds(samples.map((sample) => sample.y));
$: plotPoints = convertPoints(samples, xScaleBounds, yScaleBounds);
@@ -215,7 +210,7 @@
>
<header class="panel-head">
<div class="head-text">
<p class="panel-code">TOT</p>
<p class="panel-code">RF</p>
<p class="panel-title">{summary.label}</p>
</div>
@@ -236,8 +231,8 @@
</defs>
<g class="grid-lines" aria-hidden="true">
{#each [6, 12, 18, 24, 30] as y}
<line x1="0" y1={y} x2={viewportWidth} y2={y}></line>
{#each yAxisTicks as tick (`grid-${tick.value}`)}
<line x1={plotInsetLeft} y1={tick.plotY} x2={viewportWidth - plotInsetRight} y2={tick.plotY}></line>
{/each}
</g>
@@ -255,7 +250,7 @@
<g class="axis-labels" aria-hidden="true">
{#each yAxisTicks as tick, index (`y-${index}`)}
<text class="axis-label y-axis-label" x={tick.plotX + 0.8} y={tick.plotY - 0.35} text-anchor="start">
<text class="axis-label y-axis-label" x={tick.plotX} y={tick.plotY + 1.1} text-anchor="end">
{tick.label}
</text>
{/each}
@@ -305,14 +300,14 @@
--enter-ms: 1800ms;
--fade-ms: 1000ms;
overflow: hidden;
inline-size: min(100%, clamp(16.8rem, 23vw, 22rem));
aspect-ratio: 1.44 / 1;
min-block-size: 11.8rem;
inline-size: min(100%, clamp(29rem, 38vw, 37rem));
aspect-ratio: 1.42 / 1;
min-block-size: 20.5rem;
justify-self: start;
display: grid;
grid-template-rows: auto auto auto;
gap: 0.4rem;
padding: 0.56rem 0.62rem 0.58rem;
gap: 0.68rem;
padding: 0.88rem 0.96rem 1rem;
border: 1px solid rgb(var(--hud-border-strong-rgb) / 0.42);
border-radius: 0.92rem;
background:
@@ -345,6 +340,10 @@
opacity: 0.82;
}
.summary-panel {
margin-block-end: clamp(0.8rem, 1.8vh, 1.4rem);
}
.panel-head {
display: flex;
justify-content: space-between;
@@ -367,7 +366,7 @@
.panel-title {
margin: 0.12rem 0 0;
font-size: 0.75rem;
font-size: 1.08rem;
color: rgb(var(--hud-text-main-rgb) / 0.96);
letter-spacing: 0.05em;
}
@@ -404,7 +403,7 @@
.chart-stage {
position: relative;
block-size: clamp(6.4rem, 9vw, 8.2rem);
block-size: clamp(12rem, 15.5vw, 15rem);
overflow: hidden;
border: 1px solid rgb(var(--hud-border-strong-rgb) / 0.32);
border-radius: 0.62rem;
@@ -444,8 +443,8 @@
.axis-label {
fill: rgb(var(--hud-text-main-rgb) / 0.88);
font-size: 2.8px;
font-weight: 500;
font-size: 3.2px;
font-weight: 600;
letter-spacing: 0.02em;
text-shadow:
0 1px 0 rgb(0 0 0 / 0.46),
@@ -487,7 +486,7 @@
align-items: center;
gap: 0.28rem;
color: rgb(var(--hud-text-main-rgb) / 0.9);
font-size: 0.62rem;
font-size: 0.76rem;
letter-spacing: 0.04em;
}
@@ -520,28 +519,28 @@
@media (max-width: 1180px) {
.signal-panel {
inline-size: min(100%, clamp(14rem, 30vw, 17rem));
aspect-ratio: 1.5 / 1;
min-block-size: 10.1rem;
inline-size: min(100%, clamp(24rem, 36vw, 31rem));
aspect-ratio: 1.48 / 1;
min-block-size: 17rem;
}
}
@media (max-height: 900px) {
.signal-panel {
inline-size: min(100%, clamp(15rem, 22vw, 18.5rem));
min-block-size: 10.6rem;
inline-size: min(100%, clamp(24rem, 33vw, 30rem));
min-block-size: 16.8rem;
}
.chart-stage {
block-size: clamp(5.7rem, 7.6vw, 6.9rem);
block-size: clamp(9.8rem, 12vw, 11.8rem);
}
}
@media (max-height: 760px) {
.signal-panel {
inline-size: min(100%, clamp(13.8rem, 20vw, 16.5rem));
min-block-size: 9.8rem;
padding: 0.46rem 0.5rem 0.5rem;
inline-size: min(100%, clamp(21rem, 29vw, 26rem));
min-block-size: 14.4rem;
padding: 0.7rem 0.76rem 0.8rem;
}
.panel-foot {
@@ -549,15 +548,15 @@
}
.chart-stage {
block-size: clamp(5rem, 6.6vw, 6rem);
block-size: clamp(8.3rem, 9.6vw, 9.8rem);
}
}
@media (max-height: 680px) {
.signal-panel {
inline-size: min(100%, clamp(12.8rem, 18vw, 15rem));
min-block-size: 8.7rem;
padding: 0.4rem 0.46rem 0.44rem;
inline-size: min(100%, clamp(18.5rem, 24vw, 22.5rem));
min-block-size: 12.4rem;
padding: 0.62rem 0.66rem 0.68rem;
}
.panel-head {
@@ -570,7 +569,7 @@
}
.chart-stage {
block-size: clamp(4.4rem, 5.6vw, 5.4rem);
block-size: clamp(7rem, 7.8vw, 8rem);
}
}