我正在像这样进行数据可视化:
,使用viewBox
缩放SVG以便将图形的宽度缩放为数据范围的宽度将很方便。
在此示例中,我的数据点为12,549,因此我希望范围从0到14,000,并使用宽度为12,549的viewBox
在宽度为14,000的rect
中进行渲染。换句话说,要对我的数据使用自然单位。
但是,当我这样做时,轴上的字体也会缩放 ,并且10px字体也会缩放,并且变得太小以至于无法看到。
所以我需要的是在不缩放字体单位的情况下缩放图形单位的方法,但是我看不到这样做的方法。
这是有问题的代码:
<svg width="960" height="50" class="bullet2" style="margin-top: 10px;">
<svg viewBox="0 0 14000 25" preserveAspectRatio="none" width="100%" height="25" class="bars">
<rect x="0" y="0" width="14000" height="25" class="background"/>
<rect x="0" y="0" height="12.5" width="12549" class="item player"/>
<rect x="0" y="12.5" height="12.5" width="3750" class="item team-average"/>
<line x1="2000" x2="2000" y1="0" y2="25" class="marker" style="stroke-width: 29.1667px;"/>
</svg>
<g class="axis">
<g transform="translate(0, 25)" class="tick" style="opacity: 1;">
<line y1="0" y2="5"/>
<text text-anchor="middle" dy="1em" y="6">0</text>
</g>
<g transform="translate(140, 25)" class="tick" style="opacity: 1;">
<line y1="0" y2="5"/>
<text text-anchor="middle" dy="1em" y="6">2000</text>
</g>
<g transform="translate(280, 25)" class="tick" style="opacity: 1;">
<line y1="0" y2="5"/>
<text text-anchor="middle" dy="1em" y="6">4000</text>
</g>
<g transform="translate(420, 25)" class="tick" style="opacity: 1;">
<line y1="0" y2="5"/>
<text text-anchor="middle" dy="1em" y="6">6000</text>
</g>
<g transform="translate(560, 25)" class="tick" style="opacity: 1;">
<line y1="0" y2="5"/>
<text text-anchor="middle" dy="1em" y="6">8000</text>
</g>
<g transform="translate(700, 25)" class="tick" style="opacity: 1;">
<line y1="0" y2="5"/>
<text text-anchor="middle" dy="1em" y="6">10000</text>
</g>
<g transform="translate(840, 25)" class="tick" style="opacity: 1;">
<line y1="0" y2="5"/>
<text text-anchor="middle" dy="1em" y="6">12000</text>
</g>
<g transform="translate(980, 25)" class="tick" style="opacity: 1;">
<line y1="0" y2="5"/>
<text text-anchor="middle" dy="1em" y="6">14000</text>
</g>
</g>
</svg>
请注意,内部viewBox
元素上的svg
按比例缩放。我在外部svg
元素(也包括轴)上以相同的比例进行了尝试,但是当我这样做时,图像看起来像这样:
轴标签在那里,但是它们也被缩放,在14000像素缩放比例中,10px字体很小,以至于看不到。
答案 0 :(得分:1)
这是我对您问题的解决方案。我建议阅读有关SVGPoint和createSVGPoint
的内容。我认为本书中的信息特别有用:Using SVG with CSS3 and HTML5: Vector Graphics for Web Design
function init(){
// a function called on resize
// the function get the new font-size and set the new value of the "font-size"
let fontSize = 25;
let newSize = getValue(fontSize);
// reset the font size
theText.setAttributeNS(null,"font-size",newSize.x)
}
setTimeout(function() {
init();
addEventListener('resize', init, false);
}, 15);
// a function used to recalculate the font size on resize
function getValue(size){
var p = svg.createSVGPoint();
p.x = size;
p.y = 0;
p = p.matrixTransform(svg.getScreenCTM().inverse());
return p
}
svg{border:1px solid;}
<svg id="svg" viewBox="0 0 1000 100">
<line x1="50" x2="950" y1="50" y2="50" stroke-width="20" stroke="skyblue" />
<line x1="500" x2="500" y1="30" y2="70" stroke-width="1" stroke="#999" />
<text id="theText" dominant-baseline="middle" text-anchor="middle" x="500" y="85" font-size="16" >middle</text>
</svg>
您能解释一下该解决方案如何工作吗?
代码中有注释。我还在Using SVG with CSS3 and HTML5: Vector Graphics for Web Design中加了引号:
每个可以进行转换[....]的SVG元素都有一个getScreenCTM()方法。 CMT代表累积转换矩阵。屏幕CMT [...]定义了如何将元素坐标系中的点转换回文档窗口的原始,未缩放,未转换的坐标系。它包括对该元素及其祖先的转换以及viewBox缩放。
我希望这是有用的。但是我认为您需要阅读本书的第18章以完全理解代码。
答案 1 :(得分:0)
有两种方法可以解决模糊/一般的缩放问题:
1)将缩放后的SVG放入容器SVG中吗?堆叠;绝对不要缩放容纳字体的容器相对于其中的 child SVG的百分比。
2)states here可以使用绝对px
或相对em
单位缩放字体。请参阅here for valid length。
我看不到是否可以设置rem
单位,但是如果可以,请尝试设置是否有效?
(我经常在SVG和CSS上使用SVG,因此我的建议中可能会有空白)