如何夸大 SVG 图的 Y 轴?
How to exaggerate the Y axis of an SVG plot?
在此 SVG 图表中,线条太平了。如何夸大点的 Y 值差异,使其看起来更“之字形”,线的最低点在图形底部,最高点在顶部?
svg {
display: flex;
width: calc(100% + 4em);
transform: translateX(-2em);
clip-path: polygon(2em 0, calc(100% - 2em) 0, calc(100% - 2em) 100%, 2em 100%);
}
polyline {
transform: scaleY(-1);
}
<svg viewBox="0 -100 900 100" class="chart" style="height: 100vh; width: 100vw;">
<defs>
<marker id="red-circle" viewBox="0 0 10 10" refX="5" refY="5" orient="auto">
<circle fill="red" cx="5" cy="5" r="5" />
</marker>
</defs>
<polyline fill="#FEF9CC" stroke="#FED225" stroke-width="2" points="
0, 0
100, 23
200, 21
300, 20
400, 20
500, 23
600, 28
700, 30
800, 30
900, 30
0, -99999
0, 0
" marker-start="url(#red-circle)" marker-end="url(#red-circle)" marker-mid="url(#red-circle)" />
</svg>
我在 Reddit 上收到了公式 here。以下是我的实现方式:
const exaggerate = function () {
const polyline = document.querySelector('polyline');
const points = [...polyline.points].slice(2, -2);
// slice off (ignore) first 2 and last 2 because
// they are purely for closing the loop
// so that it can be filled with a color
const ys = points.map(({ y }) => y);
const y_min = Math.min(...ys);
const y_max = Math.max(...ys);
points.forEach((point) => {
point.y = (point.y - y_min) * 100 / (y_max - y_min);
});
}
exaggerate();
svg {
display: flex;
width: calc(100% + 4em);
transform: translateX(-2em);
clip-path: polygon(2em 0, calc(100% - 2em) 0, calc(100% - 2em) 100%, 2em 100%);
}
polyline {
transform: scaleY(-1);
}
<svg viewBox="0 -100 900 100" class="chart" style="height: 100vh; width: 100vw;">
<defs>
<marker id="red-circle" viewBox="0 0 10 10" refX="5" refY="5" orient="auto">
<circle fill="red" cx="5" cy="5" r="5" />
</marker>
</defs>
<polyline fill="#FEF9CC" stroke="#FED225" stroke-width="2" points="
0, 0
100, 23
200, 21
300, 20
400, 20
500, 23
600, 28
700, 30
800, 30
900, 30
0, -99999
0, 0
" marker-start="url(#red-circle)" marker-end="url(#red-circle)" marker-mid="url(#red-circle)" />
</svg>
编辑:
也遇到了 个问题和答案,供任何感兴趣的人参考。
在此 SVG 图表中,线条太平了。如何夸大点的 Y 值差异,使其看起来更“之字形”,线的最低点在图形底部,最高点在顶部?
svg {
display: flex;
width: calc(100% + 4em);
transform: translateX(-2em);
clip-path: polygon(2em 0, calc(100% - 2em) 0, calc(100% - 2em) 100%, 2em 100%);
}
polyline {
transform: scaleY(-1);
}
<svg viewBox="0 -100 900 100" class="chart" style="height: 100vh; width: 100vw;">
<defs>
<marker id="red-circle" viewBox="0 0 10 10" refX="5" refY="5" orient="auto">
<circle fill="red" cx="5" cy="5" r="5" />
</marker>
</defs>
<polyline fill="#FEF9CC" stroke="#FED225" stroke-width="2" points="
0, 0
100, 23
200, 21
300, 20
400, 20
500, 23
600, 28
700, 30
800, 30
900, 30
0, -99999
0, 0
" marker-start="url(#red-circle)" marker-end="url(#red-circle)" marker-mid="url(#red-circle)" />
</svg>
我在 Reddit 上收到了公式 here。以下是我的实现方式:
const exaggerate = function () {
const polyline = document.querySelector('polyline');
const points = [...polyline.points].slice(2, -2);
// slice off (ignore) first 2 and last 2 because
// they are purely for closing the loop
// so that it can be filled with a color
const ys = points.map(({ y }) => y);
const y_min = Math.min(...ys);
const y_max = Math.max(...ys);
points.forEach((point) => {
point.y = (point.y - y_min) * 100 / (y_max - y_min);
});
}
exaggerate();
svg {
display: flex;
width: calc(100% + 4em);
transform: translateX(-2em);
clip-path: polygon(2em 0, calc(100% - 2em) 0, calc(100% - 2em) 100%, 2em 100%);
}
polyline {
transform: scaleY(-1);
}
<svg viewBox="0 -100 900 100" class="chart" style="height: 100vh; width: 100vw;">
<defs>
<marker id="red-circle" viewBox="0 0 10 10" refX="5" refY="5" orient="auto">
<circle fill="red" cx="5" cy="5" r="5" />
</marker>
</defs>
<polyline fill="#FEF9CC" stroke="#FED225" stroke-width="2" points="
0, 0
100, 23
200, 21
300, 20
400, 20
500, 23
600, 28
700, 30
800, 30
900, 30
0, -99999
0, 0
" marker-start="url(#red-circle)" marker-end="url(#red-circle)" marker-mid="url(#red-circle)" />
</svg>
编辑:
也遇到了