Главная » XSLT » Создание интерактивных Web-страниц, включающих SVG

0

Задача

Требуется встроить в HTML-код куски на языке SVG, чтобы пользователь мог взаимодействовать со страницей.

Решение

В основе этого решения лежит код из статьи Дидье Мартина (Didier Martin) на сайте XML.com Integration by Parts: XSLT, XLink and SVG (http://www.xml.com/ lpt/a/2000/03/22/style/index.html). Таблица стилей встраивает в HTML-страни- цу SVG-графику вкупе с информацией, полученной из XML-документа. Для вза­имодействия с графикой включен также сценарий на языке JavaScript. Данный пример может служить прототипом для сайтов по торговле недвижимостью, по­зволяющих пользователю взаимодействовать с чертежом дома.

Входной XML-файл содержит информацию о доме. С каждой комнатой ассо­циирован атрибут id, который связывает данные об этой комнате с элементом g на SVG-диаграмме с тем же идентификатором.

<?xml version="1.0" encoding="UTF-8"?>

<?xml-stylesheet type="text/xsl" href="HouseLayout.xsl"?>

<House>

<Location>

<Address>12 34 Main St. </Address> <City>Pleasantville </City>

<State>NJ</State> </Location>

<Layout figure="HouseLayout.svg"> <Room id="bedroom1">

<Name>Cпальня</Name> <Length>10</Length> <Width>10</Width> <Windows>2</Windows> <Misc>Bид на помойку</Misc> </Room>

<Room id="bedroom2">

<Name>Cпальня</Name> <Length>10</Length> <Width>10</Width> <Windows>1</Windows> <Misc>Здесь спал Элвис</Misc> </Room>

<Room id="masterBedroom">

<Name>Xозяйская спальня</Name> <Length>18</Length> <Width>10</Width> <Windows>3</Windows> <Misc>Проход в кабинет</Misc> </Room>

<Room id="masterBath">

<Name>Xозяйская ванная</Name> <Length>5</Length> <Width>5</Width> <Windows>1</Windows>

<Misc>Полностью оборудованная ванная, включая биде</Misc> </Room>

<Room id="kitchen"> <Name>Kухня</Name> <Length>2 0</Length> <Width>18</Width> <Windows>2</Windows> <Misc>Hовые шкафчики</Misc> </Room>

<Room id="livingRoom"> <Name>Гостиная</Name> <Length>18</Length> <Width>18</Width> <Windows>2</Windows> <Misc>Bид на розовый сад</Misc>

</Room>

<Room id="bath1">

<Name>Bанная</Name> <Length>6</Length> <Width>5</Width> <Windows>1</Windows> <Misc>Bанна в форме сердца</Misc> </Room> </Layout> </House>

Показанная ниже таблица стилей включает SVG-файл, преобразует XML- данные в табличную форму и добавляет JavaScript-сценарий, делающий страницу интерактивной (рис. 11.18).

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.0"> <xsl:output method="html" version="4"/>

<xsl:template match="/">

<html>

<head>

<title><xsl:value-of select="concat(*/*/Address,*/*/City,*/*/State)"/></ title>

<script><![CDATA[

var item_selected = null;

// Эта функция вызывается в ответ на событие mouseover. // Для доступа к узлам дерева документа мы используем // SVGDOM и XML DOM. Конкретно, функция изменяет // элементы, идентифицируемые атрибутом id. // Отметим, что для изменения атрибута style в SVG DOM // не нужно заранее знать значение этого атрибута. // Напротив, в случае XML DOM необходимо знать все // содержимое атрибута style.

function on_mouse_over (ID) {

if (ID == item_selected) return true;

var obj_name = ID ;

// Изменить стиль SVG-элемента //    

Рис. 11.18. Интерактивный SVG-рисунок, сгенерированный из XML-документа

//    1 – получить документый элемент SVGDOM от программы просмотра

//    Adobe SVG viewer.

//    2 – получить элемент SVG-документа по идентификатору.

//    3 – получить атрибут style найденного элемента SVG DOM.

//    Функция getStyle ориентирована исключительно на SVG DOM.

//    Функция getStyle возвращает объект, описывающий стиль.

//    В возвращенном объекте мы изменяем атрибут стиля ‘fill’.

//    Отметим, что в отличие от XML DOM не нужно заранее знать

//    содержимое атрибута style, чтобы изменить одно из CSS-свойств.

var svgdoc = document.figure.getSVGDocument( ); var svgobj = svgdoc.getElementById(obj_name);

if (svgobj != null) {

var svgStyle = svgobj.getStyle( ); svgStyle.setProperty (‘fill’, ‘yellow’);

}

// Вот что должно было бы быть, если бы бpayзеp полностью // пoддеpживaл XML DOM. //       

// Получить элемент HTML-документа (из paзделa body) с известным // идентификaтopoм. Изменить aтpибyт style этого элемента с // помощью XML DOM. Отметим, что в отличие от SVG DOM aтpибyт // style изменяется целиком, а не только значение одного из // записанных в нем CSS-свойств. // НЕ РАБОТАЕТ…

var svgdesc = document.getElementById(obj_name); if (svgdesc != null)

svgdesc.setAttribute("style", "background-color:yellow; cursor:hand");

// Вот что мы делаем для IE 5 DHTML DOM

// ——————–

var DHTMLobj = document.all.item(obj_name) if (DHTMLobj != null)

DHTMLobj.style.backgroundColor = "yellow"; return true;

}

// Эта функция вызывается в ответ на событие mouseout. // Для доступа к узлам деpевa документа мы используем // SVGDOM и XML DOM. Кон^етно, функция изменяет // элементы, идентифициpyемые aтpибyтoм id. // Отметим, что для изменения aтpибyтa style в SVG DOM // не нужно зapaнее знать значение этого aтpибyтa. // Haпpoтив, в случае XML DOM необходимо знать все

function on_mouse_out (ID) {

if (ID = = item_selected) return true;

var obj_name = ID ;

// Изменить стиль элемента SVG //    

// 1 – получить документный элемент SVGDOM от программы просмотра // Adobe SVG viewer.

// 2 – получить элемент SVG-документа по идентификатору.

// 3 – получить атрибут style найденного элемента SVG DOM.

// Функция getStyle ориентирована исключительно на SVG DOM.

// Функция getStyle возвращает объект, описывающий стиль.

// B возвращенном объекте мы изменяем атрибут стиля ‘fill’.

// Отметим, что в отличие от XML DOM не нужно заранее знать

// содержимое атрибута style, чтобы изменить одно из CSS-свойств.

var svgdoc = document.figure.getSVGDocument( );

var svgobj = svgdoc.getElementById(obj_name);

if (svgobj != null) {

var svgStyle = svgobj.getStyle( ); svgStyle.setProperty (‘fill’, ‘white’); svgStyle.setProperty (‘stroke’, ‘white’);

}

// Вот что должно было бы быть, если бы браузер полностью // поддерживал XML DOM. //       

// Получить элемент HTML-документа (из раздела body) с известным // идентификатором. Изменить атрибут style этого элемента с // помощью XML DOM. Отметим, что в отличие от SVG DOM атрибут // style изменяется целиком, а не только значение одного из // записанных в нем CSS-свойств. // НЕ РАБОТАЕТ…

var svgdesc = document.getElementById(obj_name); if (svgdesc != null)

svgdesc.setAttribute("style", "background-color:white;");

// Вот что мы делаем для IE 5 DHTML DOM //  

var DHTMLobj = document.all.item(obj_name) if (DHTMLobj != null)

DHTMLobj.style.backgroundColor = "white";

return true;

}

function on_mouse_click(ID)

{

var obj_name = ID ;

// восстановить цвет ранее выбранной комнаты if (item_selected)

var svgdoc = document.figure.getSVGDocument( ) var svgobj = svgdoc.getElementById(obj_name);

if (svgobj != null) {

var svgStyle = svgobj.getStyle( ); svgStyle.setProperty (‘fill’, ‘white’);

}

var DHTMLobj = document.all.item(obj_name)

if (DHTMLobj != null)

{

DHTMLobj.style.backgroundColor = "white"; DHTMLobj.style.fontWeight = "normal";

}

}

// Выбрать новую комнату

if (item_selected != ID)

{

var svgdoc = document.figure.getSVGDocument( ) var svgobj = svgdoc.getElementById(obj_name);

if (svgobj != null) {

var svgStyle = svgobj.getStyle( ); svgStyle.setProperty (‘fill’, ‘#C0C0C0′);

}

var DHTMLobj = document.all.item(obj_name)

if (DHTMLobj != null) {

DHTMLobj.style.backgroundColor = "#C0C0C0′ DHTMLobj.style.fontWeight = "bolder";

}

item_selected = ID;

}

else

item selected = null;

return true;

}

]]></script> </head>

<body>

<xsl:apply-templates/>

</body>

</html>

</xsl:template>

<xsl:template match="Layout"> <div align="center">

<embed name="figure" width="540" height="540" type="image/svg" pluginspage="http://www.adobe.com/svg/viewer/install/"> <xsl:attribute name="src"><xsl:value-of select="@figure"/> </xsl:attribute> </embed> </div>

<table border="0" cellpadding="1" cellspacing="0" width="100%" bgcolor="black"> <tr>

<table border="0" cellpadding="5" cellspacing="0" width="100%" bgcolor="white">

<tr style="background-color:#9 90 0 33; color:white;"> <td>Room</td> <td align="right">Length</td> <td align="right">Width</td> <td align="right">Windows</td> <td>Miscelaneous</td>

</tr>

<xsl:apply-templates/> </table>

</tr> </table> </xsl:template>

<xsl:template match="Room">

<tr id="{@id}" style="’background-color:white;’" onmouseover="on_mouse_over(‘{@id}’)" onmouseout="on_mouse_out(‘{@id}’)" onclick="on_mouse_click(‘{@id}’)"> <td><xsl:value-of select="Name"/></td>

<td align="right"><xsl:value-of select="Length"/></td> <td align="right"><xsl:value-of select="Width"/></td> <td align="right"><xsl:value-of select="Windows"/></td> <td><xsl:value-of select="Misc"/></td> </tr> </xsl:template>

<xsl:template match="text( )"/> </xsl:stylesheet>

Обсуждение

В предыдущих примерах мы занимались получением SVG из XML, а в этом интегрировали SVG в приложение, включающее и другие Web-технологии. Мы лишь слегка коснулись того, что можно достичь в таких приложениях. В SVG есть средства для анимации и динамического создания контента. В сочетании с XSLT-преобразованиями результаты могут оказаться очень впечатляющими. Взгляните на следующую таблицу стилей, которая основана на графических примитивах из рецепта 11.2, но еще и позволяет пользователю взаимодейство­вать с графиком:

<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="1.0"

xmlns:svg="http://www.w3.org/2000/svg" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:svgu="http://www.ora.com/XSLTCookbook/ns/svg-utils" xmlns:test="http://www.ora.com/XSLTCookbook/ns/test" exclude-result-prefixes="svgu test">

<xsl:import href="svg-utils.xslt"/>

<xsl:output method="html"/>

<test:data>1.0</test:data>

<test:data>2.0</test:data>

<test:data>3.0</test:data>

<test:data>4.0</test:data>

<test:data>5.0</test:data>

<test:data>13.0</test:data>

<test:data>2.7</test:data>

<test:data>13.9</test:data>

<test:data>22.0</test:data>

<test:data>8.5</test:data>

<xsl:template match="/"> <html> <head>

<title>Интерактивная столбчатая диаграмма<^^^> <object id="AdobeSVG"

classid="clsid:78156a80-c6a1-4bbf-8e6a-3cd390eeb4e2"/> <xsl:processing-instruction name="import">

<xsl:text>namespace="svg" implementation="#AdobeSVG"</xsl:text> </xsl:processing-instruction> <script> <![CDATA[

function on_change (ID,VALUE)

{

// Получить SVG-документ

var svgDocument = document.all.item(‘figure’).getSVGDocument( );

// Идентификаторы столбцов устроены так: префикс контекста + _bar_ + ID

var barName = "interact_bar_" + ID ;

var barObj = svgDocument.getElementById(barName);

if (barObj != null)

{

barObj.setAttribute(‘y2′, VALUE);

}

return true;

}

]]></script>

</head>

<body>

<div align="center">

<svg:svg width="400" height="400" id="figure"> <xsl:call-template name="svgu:bars">

<xsl:with-param name="data" select="document(”)/*/test:data"/> <xsl:with-param name="width" select=" ‘300’ "/> <xsl:with-param name="height" select=" ‘350’ "/> <xsl:with-param name="offsetX" select=" ’50’ "/> <xsl:with-param name="offsetY" select=" ’25’ "/> <xsl:with-param name="boundingBox" select="1"/> <xsl:with-param name="max" select="25"/> <xsl:with-param name="context" select=" ‘interact’ "/> </xsl:call-template> </svg:svg>

</div>

<table border="1" cellspacing="1" cellpadding="1"> <tbody>

<xsl:for-each select="document(”)/*/test:data"> <xsl:variable name="pos" select="position( )"/> <xsl:variable name="last" select="last( )"/> <tr>

<td>Bar <xsl:value-of select="$pos"/></td> <td>

<input type="text">

<xsl:attribute name="value">

<xsl:value-of select="."/> </xsl:attribute>

<xsl:attribute name="onchange"> <xsl:text>on_change(</xsl:text> <!– Вертикально ориентированные столбцы –> <!– поворачиваются, поэтому идентификаторы нужно –> <!— обратить. Пояснения см. в реализации svgu:bars. —> <xsl:value-of select="$last – $pos + 1"/> <xsl:text>, this.value)</xsl:text> </xsl:attribute> </input> </td> </tr> </xsl:for-each> </tbody> </table> </body> </html>

</xsl:template> </xsl:stylesheet>

Эта таблица стилей генерирует Web-страницу, которая позволяет изменять данные, и при этом изменяется высота столбцов. Здесь же демонстрируется тех­ника внедрения SVG в HTML. К сожалению, работает этот пример только в брау­зерах IE 5.5 и более поздних и требует наличия надстройки Adobe SVG1.

Мангано Сэл  XSLT. Сборник рецептов. – М.: ДМК Пресс, СПБ.: БХВ-Петербург, 2008. – 864 с.: ил.

По теме:

  • Комментарии