Использование SVG в GWT
Мне было интересно, можно ли включать SVG-содержимое внутри панели (или что-то, что будет работать в GWT), иметь возможность добавлять к SVG (например, добавить круг или кривую) больше программ и обрабатывать события мыши ( это будет в SVG или GWT?). Я попытался создать объект HTML, добавляя что-то по строкам:
<svg xmlns="http://www.w3.org/2000/svg" version="1.1">
<circle cx="50" cy="50" r="30" />
</svg>
Это не сработало (ничего не видно на выходе), но я не уверен, было ли это потому, что я сделал это неправильно или не допустил.
Я смог сделать простой пример в GWT с помощью Google Visualization LineChart, но я бы хотел отойти от Google Visualization и сам сгенерировать SVG и настроить его дальше. Я огляделся, и многие ресурсы указывают на использование Canvas, но я не уверен, что это лучший маршрут.
Я также немного озадачен примером здесь. Я попробовал простую копию этого паттерна, чтобы попробовать локально, и он, похоже, не работает вообще. Тем не менее, я смог получить еще один образец, работающий только с HTM (встраивание с src, указывающим на SVG файл) L + отдельный SVG файл, но я не смог получить к нему доступ с использованием GWT с помощью RootPanel.get(...).
EDIT:
Я читал о том, что SVG не работает с Hosted Browser, и компиляция его действительно работает, но я не уверен, как обращаться к SVG (который я поместил в HTML через). Если я могу получить к нему доступ, то, предположительно, я могу добавить его в innerHTML. Я попытался в RootPanel.get( "привет" ). GetElement(). SetInnerHTML ( "..." ), но это не работает, или я испортил? Я предполагаю, что цель состоит в том, чтобы иметь возможность манипулировать SVG файлом, который я каким-то образом связал (будь то в GWT или в HTML), и иметь возможность изменять его на основе пользовательского ввода.
2nd EDIT
До сих пор я программировал функциональность внутри фактического файла SVG. В нашей установке наш SVG является внедренным объектом, и мы передали "документ" во встроенный SVG. Передача информации из встроенного объекта в HTML и из него вполне выполнима, поскольку HTML имеет доступ к нашим функциям SVG, и SVG имеет доступ к "документу".
Есть более прозрачные способы сделать это (Rapahel), где FireBug может видеть SVG напрямую, что приятно, но сейчас не совсем необходимо. До сих пор я не думаю, что любые решения, которые я рассматривал, были IFrames, но я мог ошибаться. Небольшое предупреждение, SVG может быть довольно медленным иногда.
Я бы сказал, что моя проблема решена (вроде?), но я не использую Raphael, jQuery и GWT в данный момент, но метод, который я описал в своем ответе, должен по-прежнему работать, если я хочу использовать GWT.
Ответы
Ответ 1
Немного поиграв, мне было очень приятно использовать Raphaël (который поддерживает кросс-браузерную совместимость), хотя я подозреваю что-либо по этим линиям будет работать нормально. В основном я делаю следующее в JavaScript:
var r = Raphael("someID", WND_WIDTH, WND_HEIGHT);
// additional configuration and setup if needed....
Тогда я сделал бы следующее в GWT:
public native JavaScriptObject getRaphael() /*-{
return $wnd.r;
}-*/;
// I now have access to the JavaScript object and could do the following:
public native void drawCircle(JavaScriptObject obj, int x, int y, int r) /*-{
obj.circle(x, y, r);
}-*/;
Я тоже читал, и кажется, что перенос Raphaël в GWT (эта статья является хорошим чтением) не только увеличит (в соответствии с некоторыми сообщениями, которые я читал в Google Groups, но не могу найти в данный момент - они упомянули, что компилятор выполняет довольно много работы), но также облегчает кодирование и отладку.
Итак, я достиг своей цели - напрямую управлять SVG (несколько до тех пор, пока я не порчу Raphaël в Java или, по крайней мере, не создаю обертки). Мне еще предстоит серьезно взглянуть на API визуализации Google, но я подозреваю, что это может сработать так же хорошо, но я не уверен, насколько он достаточно прочен для моих нужд.
Важная вещь, которую я считаю отсутствующей, как указано на сайте Рафаэля, была следующей:
Это означает, что каждый графический объект, который вы create также является объектом DOM, поэтому вы могут присоединять обработчики событий JavaScript или изменить их позже.
Ответ 2
Я не совсем понимаю, почему, но метод createElementNS JavaScript позволяет вам создавать и правильно форматировать xhtml внутри html.
Поскольку в проводнике нет эквивалента, GWT не реализует createElementNS, но вы можете использовать быстрый собственный метод:
private static native Element createElementNS(final String ns,
final String name)/*-{
return document.createElementNS(ns, name);
}-*/;
Имеет смысл включить это в класс SVGPanel.
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.ui.ComplexPanel;
public class SVGPanel extends ComplexPanel{
private static final String SVG_NAMESPACE = "http://www.w3.org/2000/svg";
public SVGPanel() {
setElement(createElementNS(SVG_NAMESPACE, "svg"));
showcaseSVG(); //Demonstrate that SVG works! Inexplicably!
}
private void showcaseSVG(){
Element svgElement = createElementNS(SVG_NAMESPACE, "circle");
svgElement.setAttribute("cx", "50");
svgElement.setAttribute("cy", "50");
svgElement.setAttribute("r", "30");
getElement().appendChild(svgElement);
}
}
Это должно привести к простому SVG при добавлении в вашу программу. Поздравления! Теперь вы прикрепляете его к человеку xhtml.
Ответ 3
Ого. Этот вопрос остался один на некоторое время. - Была выпущена фантастическая (окончательная?) Библиотека GWT SVG! см. lib-gwt-svg. Нет ничего такого, что было бы хорошо. Автор (Lukas Laag) очень отзывчивый и прилагает все усилия, чтобы библиотека обновлялась и находилась в отличной форме. Вышеупомянутая ссылка приведет вас к некоторым впечатляющим демонстрациям, и вы всегда можете участвовать в форуме lib-gwt-svg.
Ответ 4
Мы просто открываем виджет GWT, который позволяет вам интегрировать GWT с Raphael:
http://code.google.com/p/raphaelgwt/
Этот виджет был первоначально создан для Hydro4GE и упоминался в статье об официальном блоге GWT.
Ответ 5
Возможно, вы столкнулись с проблемой html vs xhtml: встроенный SVG должен интерпретироваться как XML/XHTML, но, по крайней мере, для меня, я не могу убедить GWT жить с applaton/xhtml + xml в качестве типа контента.
Для локального теста вы задаетесь вопросом: попытайтесь сохранить файл как .xhtml и загрузить его в Firefox - тогда он работает, потому что FF в этом случае интерпретирует его как XHTML.
Смотрите справочную информацию http://wiki.svg.org/Inline_SVG.
Если вы нашли решение проблемы, отправьте сообщение.
С Уважением,
Axel
Ответ 6
Если вы не видите свой SVG, это может быть из-за того, что ваш браузер видит ваш документ в виде HTML файла, но НЕ как файл XHTML. Попробуйте изменить расширение вашего файла (.xhtml), проверьте, что ваш html хорошо сформирован, добавьте тег html 'meta' и т.д.
FYI. Также есть модуль SVG для GWT: http://gwt-widget.sourceforge.net/
Пьер
Ответ 7
Следует предупредить, что SVG не будет работать в текущей оболочке GWT (режим Hosted) до 1,6 включительно, потому что:
1) на окнах, он использует компонент IE
2) в Linux, он использует Firefox 1.0 или равную среду исполнения Mozilla, которая не поддерживает SVG.
Скомпилированный код отлично работает в браузерах, отличных от IE.
Кроме того, он работает независимо от HTML/XHTML в браузерах, потому что в GWT вы используете createElementNS (вы можете самостоятельно кодировать метод с использованием JSNI). Кроме того, вашему тегу SVG могут понадобиться атрибуты width/height (см. Спецификацию SVG).
Ответ 8
Интересно!
Я пытался использовать Raphael через GWT/Java-код, но я не могу использовать трюк.
У меня есть следующий блок на моей странице HTML:
<script type="text/javascript" language="javascript" ><br/>
window.onload=function(){
var rr = Raphael(20,20, 200,200);
rr.circle(50,40,30);
}
</script>
Когда я компилирую/просматриваю страницу в Firefox, я получаю свой круг на своей странице, без проблем.
Затем я добавлю следующий родной java к модулю entrypoint и вызову его:
private native JavaScriptObject returnRaphael() /*-{
return $wnd.rr;
}-*/;
Отладка показывает, что возвращаемый объект всегда null
...
Кроме того, я не понимаю, почему я не мог просто сделать следующее в своем Java-коде:
public native void createRaphael()/*-{
Raphael("some_div", 200,200);
}-*/;
GWT продолжает говорить мне, что Рафаэль не существует, хотя, как я вижу через firebug, библиотека прекрасно включена.
Это также не работает:
public native void createRaphael()/*-{
$wnd.Raphael("some_div", 200,200);
}-*/;
Сюрпризно мне удается получить доступ к классам и функциям draw2d (openJacob draw2d) с помощью этого $wnd
, но не моих объектов Рафаэля... Должно быть, что-то я не получил...