feat:增加点和数字切换,减小点最大尺寸,增加range配色方案
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user