1

这是我的第一个 SVG 项目,我不是程序员,但我涉足交互式信息图表。我之前在这方面的经验来自于使用 ActionScript。

我正在使用纯 SVG(没有 Raphael、D3 等)并尝试创建交互式条形图。在 SVG 坐标系和缩放遇到一些初始困难之后,我在网上找到了一些处理后缩放转换的代码:

<text x="x_coord0" y="y_coord0" transform="scale(x_scale, y_scale) translate(-x_coord0*(x_scale-1)/x_scale, -y_coord0*(y_scale-1)/y_scale)" …&gt;text</text>

我把它转换成这个 JavaScript:

var translationfactor = ((0 - y_position)*(y_scalefactor - 1) / y_scalefactor);
var matrix = "scale(1," + y_scalefactor + ") translate(0," + Number(translationfactor) + ")";
targetbar.setAttribute("transform", matrix);

问题是我需要将条形“转换”回图表的基线,而不是它们最高点的原始位置。目前,正确缩放的条形图紧贴图表顶部:

http://billgregg.net/miscellany/upsidedown-barchart.png

我已经尝试了几种修复方法,包括将条形的“缺失高度”插入转换因子(条形从图表的整个高度开始并动态缩小)。没有任何效果。我的部分问题是,除了对 SVG 不熟悉之外,我可以整天盯着那个代码,但我的大脑仍然无法解析它。乘以负数太抽象了,从根本上说,我只是没有“得到”数学,这当然使修改代码变得困难。

我的问题:

(1) 上面的代码如何将条形图重新定位在图表的基线上?

(2) 有没有更透明、更通俗的方式来完成翻译?我的第一个想法是,如果条形图的高度减少到其原始值的 40%,那么将原始 Y 坐标值乘以 250% 应该将条形图重置为其原始位置(至少是其最高点),但是似乎不起作用。

(3) 有没有办法将条形的原点设置为其底部?在 Flash 中它是可能的,但据我所知,它是手册,而不是编程任务。

(4) 是否有类似于 ActionScript 中的 .localToGlobal() 的方法可以让我完全避免与局部坐标系发生冲突?

4

1 回答 1

0

在幕后进行矩阵数学运算,您可能很难理解数组的前后乘法。

尚不完全清楚您要实现的目标,但是在字里行间阅读,听起来您想以原始(ish)形式提供图形坐标并具有SVG比例并为您定位它们(​​?)

如果是这样的话,那么我认为解决方案比您想象的要简单。

假设我是对的,我们将从如下所示的内容开始:

<?xml version="1.0" standalone="no"?>
<svg xmlns="http://www.w3.org/2000/svg" version="1.1">

  <g transform="">

    <rect x="0" width="1" height="5" fill="red"/>
    <rect x="1" width="1" height="11" fill="green"/>
    <rect x="2" width="1" height="12" fill="orange"/>
    <rect x="3" width="1" height="8" fill="blue"/>

  </g>

</svg>

哪里x很明显,条的长度在height. y默认为 0,所以我们这里不需要它。

您基本上想知道在transform页面上缩放和定位条的内容。您的图表“颠倒”的事实有一点帮助。因为 SVG 中的原点位于左上角。

首先应用一个规模。让我们将条形设为 20 像素宽,并将长度放大 10。

  <g transform="scale(20,10)">

接下来,您要在页面上放置图表。让我们把左上角放在 (40,40)。在 SVG 中,转换按顺序连接(后乘),因此为了使转换成为您指定的内容而不是乘以比例,您应该将其放在首位。

  <g transform="translate(40,40) scale(20,10)">

所以最终的 SVG 看起来像这样:

<?xml version="1.0" standalone="no"?>
<svg xmlns="http://www.w3.org/2000/svg" version="1.1">

  <g transform="translate(40,40) scale(20,10)">

    <rect x="0" width="1" height="5" fill="red"/>
    <rect x="1" width="1" height="11" fill="green"/>
    <rect x="2" width="1" height="12" fill="orange"/>
    <rect x="3" width="1" height="8" fill="blue"/>

  </g>

</svg>

假设您已经从基数 20% 中减去了这些值,上述内容已得到简化。如果您想保留纯原始值,这是可能的,但事情变得有点棘手。您需要修改每个条的y height值,或者使用剪辑来隐藏条的 20% 以上部分。

对于“正确的方式”/正常图。您需要做的就是使 y 比例为负并平移图形,以便左下角是您想要的位置。

  <g transform="translate(40,140) scale(20,-10)">

希望这可以帮助。

于 2013-07-21T08:47:03.137 回答