gpt4 book ai didi

html - 按固定像素数移动 SVG

转载 作者:行者123 更新时间:2023-12-05 05:48:38 27 4
gpt4 key购买 nike

SVG 示例目前在视觉上看起来很完美,但我想在没有填充的情况下获得相同的结果。

填充的目的是迫使红/蓝线向右移动 40 像素,为轴腾出空间,同时防止它在图表的右侧溢出。

我正在尝试删除填充,但随后我需要找到一种新方法,在不使用 x="40px"width="calc(100% - 40px)"的情况下仅将“线”向右移动 40px因为此语法也不兼容 Sharp 或旧版浏览器。

有没有什么方法可以去除填充并将线条向右移动 40px,同时将其限制在 SVG 的盒子模型中?

(最后说明:我不想在任何移动线条的逻辑中使用“响应式”单元)

Line graph showing padding

折线图的 JSFiddle:https://jsfiddle.net/Lefsqo3j/14/

<div style="height:148px;width:300px;overflow:hidden;resize:both">
<svg overflow="visible" style="padding:24px 0px 24px 40px" height="100%" width="100%">
<svg role="img" viewBox="0 0 300 100" preserveAspectRatio="none">
<svg viewBox="0 0 300 100" preserveAspectRatio="none">
<line y1="0" y2="100" x1="0" x2="0" stroke-width="0.2" stroke="black"></line>
<line y1="0" y2="100" x1="75" x2="75" stroke-width="0.2" stroke="black"></line>
<line y1="0" y2="100" x1="150" x2="150" stroke-width="0.2" stroke="black"></line>
<line y1="0" y2="100" x1="225" x2="225" stroke-width="0.2" stroke="black"></line>
<line y1="0" y2="100" x1="300" x2="300" stroke-width="0.2" stroke="black"></line>
<line x1="0" x2="300" y1="0" y2="0" stroke-width="0.2" stroke="black"></line>
<line x1="0" x2="300" y1="25" y2="25" stroke-width="0.2" stroke="black"></line>
<line x1="0" x2="300" y1="50" y2="50" stroke-width="0.2" stroke="black"></line>
<line x1="0" x2="300" y1="75" y2="75" stroke-width="0.2" stroke="black"></line>
<line x1="0" x2="300" y1="100" y2="100" stroke-width="0.2" stroke="black"></line>
</svg>
</svg>
<svg x="100%" overflow="visible">
<text text-anchor="end" dy="-8px">
<tspan fill="red"> ⬤</tspan>
Line A<tspan fill="blue"> ⬤</tspan>
Line B
</text>
</svg>
<svg viewBox="0 0 300 100" preserveAspectRatio="none">
<path
d="M 0 75 M 0 75 L 75 50 L 150 15 L 225 67 L 300 67 L 300 67"
stroke-width="3"
stroke="red"
fill="transparent"
vector-effect="non-scaling-stroke"
></path>
<path
d="M 0 92 M 0 92 L 75 72 L 150 80 L 225 50 L 300 50 L 300 50"
stroke-width="3"
stroke="blue"
fill="transparent"
></path>
</svg>
<svg overflow="visible">
<text x="0%" text-anchor="end" y="0%">
40
</text>
<text x="0%" text-anchor="end" y="25%">
30
</text>
<text x="0%" text-anchor="end" y="50%">
20
</text>
<text x="0%" text-anchor="end" y="75%">
10
</text>
<text x="0%" text-anchor="end" y="100%">
0
</text>
<g style="transform: translateX(0%);">
<text y="100%" dy="16px">
5
</text>
</g>
<g style="transform: translateX(25%);">
<text y="100%" dy="16px">
10
</text>
</g>
<g style="transform: translateX(50%); ">
<text y="100%" dy="16px">
15
</text>
</g>
<g style="transform: translateX(75%); ">
<text y="100%" dy="16px">
20
</text>
</g>
<g text-anchor="end" style="transform: translateX(100%);">
<text y="100%" dy="16px">
25
</text>
</g>
</svg>
</svg>
</div>

最佳答案

我修改了 SVG 并将内容放入内容框中。尺寸统一缩放,保持纵横比。

<div style="height:148px;
width:300px;
overflow:hidden;
resize:both;
background-color: wheat;
">

<svg class="chart" overflow="visible">
<style>
.chart {
width: 100%;
height: 100%;
font-size: 14px;
padding-bottom: 24px;
}

/* background color for entire chart */
.chart-background {
fill: rgb(230, 249, 255);
}

/* styling for only the graph part */
.graph {
background-color: transparent;
}

/* grid lines style */
.chart .grid>line {
stroke-width: 0.5;
stroke: green;
}

.legend {
background-color: wheat;
}

.labels {
background-color: transparent !important;
}

.back {
background-color: wheat;
}

</style>
<rect class="chart-background" height="100%" width="100%" />
<svg viewBox="0 0 340 140" x="40" y="24" preserveAspectRatio="none">
<g class="grid">

<line y1="0" y2="100" x1="0" x2="0"></line>
<line y1="0" y2="100" x1="75" x2="75"></line>
<line y1="0" y2="100" x1="150" x2="150"></line>
<line y1="0" y2="100" x1="225" x2="225"></line>
<line y1="0" y2="100" x1="300" x2="300"></line>

<line x1="0" x2="300" y1="0" y2="0"></line>
<line x1="0" x2="300" y1="25" y2="25"></line>
<line x1="0" x2="300" y1="50" y2="50"></line>
<line x1="0" x2="300" y1="75" y2="75"></line>
<line x1="0" x2="300" y1="100" y2="100"></line>
</g>
</svg>

<svg>
<g class="legend">
<text x="100%" text-anchor="end" dy="16">
<tspan fill="red"> ⬤</tspan>Line A<tspan fill="blue"> ⬤</tspan>Line B
</text>
</g>
</svg>

<svg overflow="visible" x="40" y="24" height="70%" width="88%" style="margin-bottom: 24px;">
<g class="labels" style="font-size: 12px;">
<text x="0%" text-anchor="end" y="0%">40</text>
<text x="0%" text-anchor="end" y="25%">30</text>
<text x="0%" text-anchor="end" y="50%">20</text>
<text x="0%" text-anchor="end" y="75%">10</text>
<text x="0%" text-anchor="end" y="100%">0</text>

<text y="100%" dy="16px">5</text>
<text y="100%" dy="16px" x="22%">10</text>
<text y="100%" dy="16px" x="48%">15</text>
<text y="100%" dy="16px" x="74%">20</text>
<text y="100%" dy="16px" dx="-20px" x="100%">25</text>
</g>
</svg>

<svg viewBox="0 0 340 140" x="40" y="24" preserveAspectRatio="none">
<g class="plot">
<path d="M 0 75 M 0 75 L 75 50 L 150 15 L 225 67 L 300 67 L 300 67" stroke-width="3" stroke="red"
fill="transparent" vector-effect="non-scaling-stroke"></path>
<path d="M 0 92 M 0 92 L 75 72 L 150 80 L 225 50 L 300 50 L 300 50" stroke-width="3" stroke="blue"
fill="transparent"></path>
</g>
</svg>
</svg>
</div>

Sharpjs:

const svgBuffer = Buffer.from(svgImage);

const image = await sharp(svgBuffer, {})
.resize({ width: 500, fit: sharp.fit.inside, position: 'centre' })
.toFile('e:/svg-image.png');

enter image description here


旧答案
我们可以将原始 svg 内容包装在一个新的 <svg> 中。标签。使用自定义样式,可以定位原始 svg,使溢出可见:

const sharp = require('sharp');

async function svgToImage(svgImage) {
try {
const wrapped = `<svg id='wrapper' width="600" height="400">
<style>
#wrapper > svg{
transform: scale(.9) translate(25px, 25px) ;
}
</style>
${svgImage}
</svg>`;

const svgBuffer = Buffer.from(wrapped);
//const image = await sharp(svgBuffer, {}).resize(500).toFile('e:/svg-image.png');

const image = await sharp({
create: {
width: 600,
height: 400,
channels: 4,
background: { r: 220, g: 255, b: 220, alpha: 1 },
},
})
.composite([{ input: svgBuffer, top: 0, left: 0 }])
.png()
.toFile('e:/svg-image.png');
} catch (error) {
console.log(error);
}
}

const svgImage = `
<svg overflow="visible" style="padding:24px 0px 24px 40px">
<svg role="img" viewBox="0 0 300 100" preserveAspectRatio="none">
<svg viewBox="0 0 300 100" preserveAspectRatio="none">
<line y1="0" y2="100" x1="0" x2="0" stroke-width="0.2" stroke="black"></line>
<line y1="0" y2="100" x1="75" x2="75" stroke-width="0.2" stroke="black"></line>
<line y1="0" y2="100" x1="150" x2="150" stroke-width="0.2" stroke="black"></line>
<line y1="0" y2="100" x1="225" x2="225" stroke-width="0.2" stroke="black"></line>
<line y1="0" y2="100" x1="300" x2="300" stroke-width="0.2" stroke="black"></line>
<line x1="0" x2="300" y1="0" y2="0" stroke-width="0.2" stroke="black"></line>
<line x1="0" x2="300" y1="25" y2="25" stroke-width="0.2" stroke="black"></line>
<line x1="0" x2="300" y1="50" y2="50" stroke-width="0.2" stroke="black"></line>
<line x1="0" x2="300" y1="75" y2="75" stroke-width="0.2" stroke="black"></line>
<line x1="0" x2="300" y1="100" y2="100" stroke-width="0.2" stroke="black"></line>
</svg>
</svg>
<svg x="100%" overflow="visible">
<text text-anchor="end" dy="-8px">
<tspan fill="red"> ⬤</tspan>
Line A<tspan fill="blue"> ⬤</tspan>
Line B
</text>
</svg>
<svg viewBox="0 0 300 100" preserveAspectRatio="none">
<path
d="M 0 75 M 0 75 L 75 50 L 150 15 L 225 67 L 300 67 L 300 67"
stroke-width="3"
stroke="red"
fill="transparent"
vector-effect="non-scaling-stroke"
></path>
<path
d="M 0 92 M 0 92 L 75 72 L 150 80 L 225 50 L 300 50 L 300 50"
stroke-width="3"
stroke="blue"
fill="transparent"
></path>
</svg>
<svg overflow="visible">
<text x="0%" text-anchor="end" y="0%">40</text>
<text x="0%" text-anchor="end" y="25%">30</text>
<text x="0%" text-anchor="end" y="50%">20</text>
<text x="0%" text-anchor="end" y="75%">10</text>
<text x="0%" text-anchor="end" y="100%">0</text>

<text y="100%" dy="16px">5</text>
<text y="100%" dy="16px" x="25%">10</text>
<text y="100%" dy="16px" x="50%">15</text>
<text y="100%" dy="16px" x="75%">20</text>
<text y="100%" dy="16px" x="100%">25</text>
</svg>
</svg>`;

svgToImage(svgImage);

输出:
enter image description here



由于 bug,在 x 轴上标签没有表现。和 bug与变换有关。所以我不得不修改 x label 标签。

关于html - 按固定像素数移动 SVG,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70779886/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com