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 6scalable 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_draggersetDraggerImageWidth, 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 falseExample:
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});
}
});
}
}