1

I am working with a JS charting library that I did not write and I would like to add some functionality to insert HTML content in the element of an SVG graphic. The reason is that it contains a mix of RTL and LTR text:

<text class="tc-data-layout-2 tc-data-text tc-data-text-1 tc-price-chart-text-color tc-price-chart-font-size" transform="translate(13,0)" opacity="1" y="15.6875" x="5" text-anchor="start">صعود, 58 %</text>

Notice that the % symbol is at the wrong end of the string. To fix this, I'd like to add a tspan element with the LTR content:

<text class="tc-data-layout-2 tc-data-text tc-data-text-1 tc-price-chart-text-color tc-price-chart-font-size" transform="translate(13,0)" opacity="1" y="15.6875" x="5" text-anchor="start"><tspan direction="ltr" unicode-bidi="embed" xml:lang="en">% 58 </tspan>,صعود</text>

I have located the code that adds the text element:

var textElement = document.createElementNS("http://www.w3.org/2000/svg", "text");
svgElement.appendChild(textElement);
if (classStr) {
   textElement.setAttribute("class", classStr);
}
textElement.textContent = text;

EDIT: One of my goals is to keep the percentage figure as one unit so that it's expressed as "99 %" or "% 99" in the markup itself.

Thanks!

Rob

4

2 回答 2

3

以下是翻译曾经向我解释过的,所以它不是真正的语言知识。请在发布之前,如果您自己不会说波斯语,请与翻译检查翻译是否正确。

出现该错误是因为在文本运行过程中,文本方向的自动识别失败。在字节顺序中,阿拉伯字母具有它们的发音顺序。每个知道 RTL 脚本及其 Unicode 编码的程序都会正确地呈现它,并在右侧显示第一个字节顺序的字母。

表示逗号和拉丁数字的字节被认为是“方向中立的”,因此如果它们出现在阿拉伯文字旁边,则进一步使用 RTL 方向。如果您想知道,在阿拉伯文字中,较低值的数字写在较高值的右侧,所以对于只知道拉丁文字的人来说,它看起来好像是从左到右写的,但这只是我们的无知。在数字末尾,程序仍然认为它正在处理阿拉伯文字。

但似乎百分比符号被解释为绝对 LTR,因此渲染错误地在右侧进行。

SVG 支持一个可继承的direction属性,以在拉丁字母和阿拉伯字母混合使其不明确的情况下强制正确的文本运行方向。下面的示例设置<text>元素的属性。我按照您提供的方式将您的字符串复制到标签中,但将数字部分分隔为一个单独的<tspan>元素。现在百分比符号呈现在左侧。无论您是否划分内容,结果都保持不变。

var svg = document.querySelector('svg');

var text = document.createElementNS("http://www.w3.org/2000/svg", "text");
text.setAttribute("x", 90);
text.setAttribute("y", 20);
text.style.fontSize = 15;
text.style.direction = "rtl";
text.textContent = "صعود, ";

var numeral = document.createElementNS("http://www.w3.org/2000/svg", "tspan");
numeral.textContent = "58 %";
text.appendChild(numeral);

svg.appendChild(text);
<svg viewBox="0 0 100 25"></svg>

于 2020-11-11T02:01:04.787 回答
2

我刚刚注意到我的答案与 ccprog 基本相同。我暂时将其留在这里,因为代码示例可能对您有用。


尝试添加direction="rtl"到您的<text>元素。

<svg viewBox="0 0 150 50">

  <text class="tc-data-layout-2 tc-data-text tc-data-text-1 tc-price-chart-text-color tc-price-chart-font-size"
        transform="translate(13,0)" opacity="1" y="15.6875" x="5"
        text-anchor="end" direction="rtl">صعود, 58 %</text>

</svg>

请注意,这direction="rtl"也会翻转text-anchor属性的行为,因此您可能还想更改text-anchor="start"text-anchor="end". 正如我在上面的示例中所做的那样。

这是你想要的吗?

如果您需要更改代码,那么它看起来像这样:

var textElement = document.createElementNS("http://www.w3.org/2000/svg", "text");
svgElement.appendChild(textElement);
if (classStr) {
   textElement.setAttribute("class", classStr);
}
textElement.setAttribute("direction", "rtl");
textElement.textContent = text;

在代码中的某处,它也会设置text-anchor. 你也需要改变它。

于 2020-11-11T03:30:31.340 回答