MathJax внутри SVG
Я делаю некоторые записи, где я использую MathJax для визуализации математики. Я также иногда включаю диаграммы SVG, которые генерируются динамически javascript. Эти диаграммы SVG иногда включают математику.
Я хотел бы, чтобы текстовые элементы в этих SVG-диаграммах отображались с помощью MathJax. Я знаю, как!--6-->причина динамической математики для визуализации. Однако выход mathjax находится в <span>
s, которые не являются допустимыми SVG и не отображаются.
Это сохраняется, когда я настройте MathJax для использования режима вывода SVG, хотя это, возможно, связано с неправильным использованием режима вывода SVG. Я изменил ссылку MathJax CDN на http://cdn.mathjax.org/mathjax/2.1-latest/MathJax.js?config=TeX-AMS-MML_SVG
, который не произвел вывод SVG. Я еще не смог уговорить MathJax фактически выводить элементы SVG.
я рассмотрел возможность использования SVG <foreignObject>
тег, который не идеален, потому что (насколько мне известно) я должен указать ширину и высоту, что неудобно.
есть ли лучший способ включить текст MathJax внутри SVG внутри HTML?
3 ответов
В настоящее время единственный способ включить MathJax в диаграмму SVG-через <foreignObject>
. Да, это не идеально, не только потому, что вам нужно предоставить размер, но и потому, что IE9+ не поддерживает <foreignObject>
.
Что касается вывода SVG, если вы использовали контекстное меню MathJax для выбора математического рендеринга, который переопределит выбор рендеринга в документе, поэтому вы все еще можете видеть вывод HTML-CSS по этой причине. Значение хранится в файле cookie, так что это будет вспоминается от сеанса к сеансу. Вы можете удалить файл cookie, чтобы удалить настройку, или снова использовать меню MathJax для выбора рендеринга SVG.
обратите внимание, однако, что это тоже не поможет вам, так как SVG-выход MathJax-это не просто фрагмент SVG, который может быть включен в больший SVG-файл, но включает некоторый HTML и элемент. Кроме того, MathJax нуждается в окружающем HTML для определения таких вещей, как размер шрифта для использования и некоторые другие факторы, поэтому это не сможете помещаются прямо на схеме СВГ.
на <foreignObject>
подход-это действительно единственный надежный способ на данный момент.
редактировать: вот полный пример:
<!DOCTYPE html>
<html>
<head>
<title>MathJax in SVG diagram</title>
<script type="text/javascript" src="http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_SVG"></script>
</head>
<body>
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="1000" height="500">
<circle cx="100" cy="100" r="99" fill="yellow" stroke="red" />
<circle cx="100" cy="100" r="3" fill="blue" />
<foreignObject x="100" y="100" width="100" height="100">
<div xmlns="http://www.w3.org/1999/xhtml" style="font-family:Times; font-size:15px">
\(\displaystyle{x+1\over y-1}\)
</div>
</foreignObject>
</svg>
</body>
</html>
существует способ включить элементы MathJax SVG в диаграмму SVG, не требуя foreignObject
.
Полную демонстрацию техники на http://puzlet.com/m/b00b3.
скажем, у вас есть SVG-диаграмма (и содержащая любые элементы SVG) на вашей веб-странице:
<svg id="diagram" xmlns='http://www.w3.org/2000/svg'
xmlns:xlink="http://www.w3.org/1999/xlink"
version='1.1' width='720' height='100'>
</svg>
и следующий MathJax:
<div id="mathjaxSource">
$\Omega$
</div>
используйте этот CoffeeScript (плюс jQuery) для интеграции элемента MathJax в SVG диаграмма:
diagram = $("#diagram") # SVG diagram
obj = new MathJaxObject "mathjaxSource" # MathJax object (see class definition below)
obj.appendTo diagram # Append MathJax object to diagram
obj.translate 100, 200 # Position MathJax object within diagram
вы также можете использовать width()
и height()
методы центрирования и выравнивания по вертикали.
class MathJaxObject
constructor: (@divId, @scale=0.02) ->
@source = $("##{@divId}").find ".MathJax_SVG"
@svg = @source.find "svg"
g = @svg.find "g"
@group = $(g[0]).clone()
@translate 0, 0
viewBox: -> @svg[0].viewBox
width: -> @scale * @viewBox().baseVal.width
height: -> @scale * @viewBox().baseVal.height
translate: (@dx, @dy) ->
dy = @dy + (-@scale * @viewBox().baseVal.y)
@group[0].setAttribute "transform",
"translate(#{@dx} #{dy}) scale(#{@scale}) matrix(1 0 0 -1 0 0)"
appendTo: (diagram) ->
diagram.append @group
я использовал следующее, которое определяет функцию, которая принимает код latex в качестве входных данных и добавляет обработанный MathJax svg к целевому элементу SVG.
// First create a new element to hold the initial Latex code
// and eventual MathJax generated SVG. This element isn't added
// to the main docuemnt, so it's never seen.
let mathBuffer = document.createElement("div");
// Then define a function that takes LaTeX source code
// and places the resulting generated SVG in a target SVG element.
mathSVG = function (latex, target) {
// Update the buffer with the source latex.
mathBuffer.textContent = latex;
// Get MathJax to process and typeset.
MathJax.Hub.Queue(["Typeset", MathJax.Hub, mathBuffer]);
// Queue a callback function that will execute once it's finished typesetting.
MathJax.Hub.Queue(function () {
// This (svg) is the generated graphics.
const svg = mathBuffer.childNodes[1].childNodes[0];
// The next line is optional, play with positioning as you see fit.
svg.setAttribute("y", "-11pt");
// Move the generated svg from the buffer to the target element.
target.appendChild(svg);
// Clear the buffer.
mathBuffer.textContent = "";
});
};
в приведенном выше, я предполагаю, что хост-документ html с элементами svg внутри. Он также должен работать в документе хоста svg.