Index
ht.Node
supports rendering with pictures, vectors, but for some applications (such as SCADA), it is often necessary to insert some interactive elements (text fields, buttons, etc.) into the interface, and the normal Node
is a little overwhelmed at this time. For this, the HT
expand the ht.HtmlNode
, it can render HTML
elements to the topology, both to maintain the HTML
elements of interactivity, but also to achieve the normal Node
scaling rotation and other functions.
HtmlNode
provides the following API
:
html
Is operated by setHtml
and getHtml
, which represents the HTML
content to render, which can be an HTML
text string, DOM
object, or HT
component (such as GraphView
)context
Is operated by setContext
and getContext
for data bindingpadding
Is operated by setPadding
and getPadding
, represents the distance between the HTML
content border and the Node
selected border, the default is 6
scalable
Is operated by setScalable
and getScalable
, represents whether the content of HTML
can be stretched. Value is boolean
type (the default is true
):true
Represents scaling of HTML
content with transform
style when adjusting HtmlNode
width and heightfalse
Represents that when adjusting the width and height of HtmlNode
, change the width
and height
of the first element of the HTML
content to fit the size of HtmlNode
. This means that if this parameter is set to false
, the user-set HTML
content should have only one root elementsetDraggerImage
, getDraggerImage
are used to set or get the drag icon in the upper-right corner of HtmlNode
, which must be the name of picture that registered by ht.Default.setImage
, the default is node_dragger
setDraggerImageWidth
, getDraggerImageWidth
are used to set or get the width of the HtmlNode
drag icon in the upper-right cornersetDraggerImageHeight
, getDraggerImageHeight
are used to set or get the height of the HtmlNode
drag icon in the upper-right cornerThe API
expands on GraphView
:
adjustHtmlNodeIndex
, the default is true
, which represents automatically adjusts the z-index
of HTML
content so that it can displayed on top when selected; set to false
can improve performanceHtmlNode
html
attribute can be set to HTML
text, and then you can set the position
, width
, height
and other attributes in the way of operating the general Node
.
For example:
var node = new ht.HtmlNode();
node.setPosition(200, 100);
node.setHtml("<div class='wrapper'>\n\
<img width='20' height='24' src='data:image/png;base64,'>\n\
Hello, I can <i>render</i> any HTML!</div>");
dataModel.add(node);
In the example above, HtmlNode
renders a piece of HTML
text to the topology, and the HTML
element can not only respond to user actions, but also use the topology component to scale and rotate it. Note: In order for the HTML
element to respond to user action, HtmlNode
shielding the drag-and-drop function on the body
, when HtmlNode
is selected, a cross direction tag will appears in the upper right corner, dragging it to achieve drag-and-drop HtmlNode
.
How to modify the HTML
content that has been displayed? The most straightforward way is to assign id
to the HTML
element, get the DOM
object through document.getElementById('id')
, and then operate it.
In addition, HtmlNode
provides simple bidirectional data binding:
Update data from HtmlNode
properties to HTML
elements:
The HtmlNode
integration Handlebars framework enables you to update the HtmlNode
properties to the HTML
element. Handlebars
can replace the keyword in the template with the property value at run time, Handlebars
for a detailed reference here: http://handlebarsjs.com/
Update the values in the HTML
element to the HtmlNode
attribute:
HtmlNode
at the root node of the HTML
element listens to the change
event and, based on the bind
attribute of the event target, fills its value
back into the HtmlNode
context
attribute, as in the following example:
Example:
<!--Introduce handlebars-->
<script src="../../../lib/handlebars.js"></script>
<!--Create an HTML template, {{}} can synchronize properties on HtmlNode to HTML elements, and the bind property of HTML elements is used to synchronize value to HtmlNode-->
<script id="controlpanel-template" type="text/x-handlebars-template">
<div class="panel">
<div class="title">Dashboard</div>
<div class="content">
<p><span class="label">KPI: </span><span class="value">{{value}}</span></p>
<p>
<span class="label">Stop: </span>
<span class="value"><input type="checkbox" {{#if isStopped}}checked{{/if}} bind="isStopped"></span>
</p>
</div>
</div>
</script>
......
var node = new ht.HtmlNode();
node.setPosition(200, 100);
node.setHtml(document.getElementById("controlpanel-template").innerHTML);
node.setContext(context);
dataModel.add(node);
/*
* Refreshes the HtmlNode context property every second, HtmlNode automatically synchronizes it to an
* HTML element
*/
setInterval(function () {
if(!context.isStopped){
context.value=parseInt(100*Math.random());
graphView.invalidateData(node);
}
}, 1000);
The setHtml
parameter can be of the following three types:
HTML
Text string, such as setHtml("<div>html text</div>")
DOM
Object, developers can create HTML
elements through DOM API
and then rendering HtmlNode
by setHtml
HT
Object, HtmlNode
can also render GraphView
, TablePane
and other HT
components, it is necessary to note: If the HT
component is rendered, it is best to set scalable
to false
Example:
var htmlNode = new ht.HtmlNode();
htmlNode.setPosition(200, 50);
htmlNode.setName("Rendering HTML text");
htmlNode.setHtml("<div class='htmlWrapper'>Node's new name: <input type='text' value='{{value}}' bind='value'>\n\
<input type='button' value='Modify' nodeid='{{nodeid}}' onclick='modifyNodeName(event)'/></div>");
htmlNode.setContext({
value:htmlNode.getName(),
nodeid:htmlNode.getId()
});
dataModel.add(htmlNode);
var div=document.createElement("div");
div.className="domWrapper";
div.innerHTML="Rendering DOM";
var domNode = new ht.HtmlNode();
domNode.setHtml(div);
domNode.setPosition(200, 150);
dataModel.add(domNode);
var htNode = new ht.HtmlNode();
htNode.setHtml(createTable());
htNode.setPosition(500,100);
htNode.setName("Alarm Statistics(TablePane)");
htNode.setScalable(false);
dataModel.add(htNode);
Next look at a comprehensive application, some applications need to display some subsidiary information around the datas, such as status icons, statistics, or Chart
, etc. The following example has two Node
, one as the actual display of Node
, and the other as a statistical table stand right by the first Node
. To save space, the statistics table should be able to expand and merge, let's see the following example:
First define two templates as the HTML
contents that merging and expanding by HtmlNode
:
<script id="table-template" type="text/x-handlebars-template">
<div class="wrapper" nodeid="{{id}}" onclick="tableIconClickHandler(event)">
<div class="table_title">Real-time monitoring<span class="shrink"></span></div>
<table class="list_table">
{{#each rows}}
<tr>
<td>{{id}}</td>
<td>{{temperature}}</td>
<td>{{pressure}}</td>
<td>{{time}}</td>
</tr>
{{/each}}
</table>
</div>
</script>
<script id="table-min-template" type="text/x-handlebars-template">
<span class="open" nodeid="{{id}}" onclick="tableIconClickHandler(event)"></span>
</script>
Next declare the Host
node and the statistics node:
var host = new ht.Node();
host.setName("This is Host");
dataModel.add(host);
var tableNode = new ht.HtmlNode();
tableNode.setHtml(document.getElementById("table-template").innerHTML);
tableNode.setPosition(230, 100);
tableNode.setContext({
id: tableNode.getId(),
rows: [
{
id: 1,
temperature: 23.3,
pressure: 231.6,
time: "18:12"
},
{
id: 2,
temperature: 29.3,
pressure: 231,
time: "18:13"
},
{
id: 3,
temperature: 25,
pressure: 211.6,
time: "18:14"
},
{
id: 4,
temperature: 22.4,
pressure: 111.6,
time: "18:15"
},
{
id: 5,
temperature: 37.4,
pressure: 171.6,
time: "18:19"
}
]
});
tableNode.setWidth(300);
tableNode.setHeight(200);
dataModel.add(tableNode);
tableNode.setPosition({x: host.getPosition().x + host.getWidth() / 2 + tableNode.getWidth() / 2 + 10,
y: host.getPosition().y - host.getHeight() / 2 + tableNode.getHeight() / 2});
Finally, there is a function to handle the user's click event in the upper-right corner of the statistical graph:
function tableIconClickHandler(e) {
var maxInnerHTML = document.getElementById("table-template").innerHTML,
minInnerHTML = document.getElementById("table-min-template").innerHTML;
if (e.target.className === "shrink") {
var nodeid = e.currentTarget.getAttribute("nodeid"),
node = dataModel.getDataById(nodeid),
host = node.getHost(),
newWidth = 16 + node._padding,
newHeight = 16 + node._padding,
originWidth = node._originWidth,
originHeight = node._originHeight,
differenceWidth = originWidth - newWidth,
differenceHeight = originHeight - newHeight;
ht.Default.startAnim({
finishFunc: function () {//Called at the end of the animation execution, changing the
//content and location of the statistics
node.setHtml(minInnerHTML);
node.setPosition({x: host.getPosition().x + host.getWidth() / 2 + node.getWidth() / 2 + 10,
y: host.getPosition().y - host.getHeight() / 2 + node.getHeight() / 2});
},
action: function (t) {//The animation calls this function every frame, where the size of
//the tables is adjusted
node.setWidth(originWidth - differenceWidth * t);
node.setHeight(originHeight - differenceHeight * t);
node.setPosition({x: host.getPosition().x + host.getWidth() / 2 + node.getWidth() / 2 + 10,
y: host.getPosition().y - host.getHeight() / 2 + node.getHeight() / 2});
}
});
} else if (e.target.className === "expand") {
var nodeid = e.currentTarget.getAttribute("nodeid"),
node = dataModel.getDataById(nodeid),
host = node.getHost(),
originWidth = node._originWidth,
originHeight = node._originHeight;
node.setHtml(maxInnerHTML);
var newWidth = node.getWidth(),
newHeight = node.getHeight(),
differenceWidth = newWidth - originWidth,
differenceHeight = newHeight - originHeight;
node.setWidth(originWidth);
node.setHeight(originHeight);
ht.Default.startAnim({
action: function (t) {
node.setWidth(originWidth + differenceWidth * t);
node.setHeight(originHeight + differenceHeight * t);
node.setPosition({x: host.getPosition().x + host.getWidth() / 2 + node.getWidth() / 2 + 10,
y: host.getPosition().y - host.getHeight() / 2 + node.getHeight() / 2});
}
});
}
}