Index
Data binding means automatically synchronizing the data model information of the Data
with the visual parameters of the graphics of the user interface, such as color, size and angle. The internal graphical components of HT
have been bound to Data
in DataModel
. For example, if the user modifies the positional value of Node
, the positions of the corresponding data of GraphView
and Graph3dView
will change synchronously and automatically.
Traditional data binding includes one-way binding and two-way binding. But the design pattern of the HT
system makes the binding simpler and more comprehensible. HT
has only one DataModel
. The graphical components bound to it have no other data model within them, so the components present the interface strictly according to the DataModel
. When the user drags and moves the data, which essentially modifies the positional value of Node
in the data model, the event triggered by the changes of the properties will be distributed to the graphical components again through the model, initiating the reloading of the interface according to the new model information.
The predefined data of HT
have already achieved the data binding automatically. What this handbook introduces are mainly aimed at the data binding mechanism of the three scalable graphics’ display effects, namely user-defined vectors, icons and 3d models. The three user-defined graphics are bound to the data in the same way. Users only need to describe the Data
property bound to the parameters of the data according to the specified rules and format of HT
. When the data of Data
are updated, the graphical interface will be reloaded automatically so that the real-time display of the data will be achieved.
Binding format is very easy. Just replace the former parameter values with an object with the func
property. As for the contents of func
, there are several types, which are as follows:
function
Type, invoke the function directly, pass in the objects Data
and view
, and determine the parameter values according to the return values of the function, namely func(data, view);
call. string
Type:style@***
, return the value of data.getStyle(***)
, in which ***
stands for the property name of style
.attr@***
, return the value of data.getAttr(***)
, in which ***
stands for the property name of attr
.field@***
, return the value of data.***
, in which ***
stands for the property name of data
.style@***
, attr@***
or field@***
, directly take the string
type as the function name of the data
object calling data.***(view)
, and take the return value as the parameter value.Apart from the func
property, the value
property can also be set as the default value. If the value of the corresponding func
is undefined
or null
, the default value defined for the value
property will be taken. Take the following codes as an example. If the attr
property of the corresponding Data
object, stateColor
, is undefined
or null
, the color yellow
will be taken.
color: {
func: 'attr@stateColor',
value: 'yellow'
}
Data binding is an important factor which makes the description format of the vectors in the HT
system more flexible and powerful than that of the traditional vectors, such as SVG. The properties of all the vector components mentioned above can be set to dynamically bound to the properties of the Data
model. Therefore, the general workflow is as follows: generate the information of the vector json
manually or by adopting the vector editing tools, and then the parameters needing dynamic changes should be designed to the format of data binding. During the run, users just need to modify the relevant properties of the graphics bound in Data
, and then the vectors will automatically convert the property value bindings to the corresponding graphic information, such as color, size and angle, and finally the loosely coupled workflow framework of data visualization can be achieved.
hollow: { func: 'style@isHollow' }
Bind the hollow
property of pieChart
to the style
property of the Node
object isHollow
startAngle: { func: 'attr@angle' }
Bind the startAngle
property of pieChart
to the attr
property of the Node
object angle
height: { func: 'field@_height' }
Bind the height
property of pieChart
to the field
property of the Node
object _height
width: { func: 'getWidth' }
Bind the width
property of pieChart
to the method getWidth
of the Node
objectrect: { func: function (data) { return [5, 5, 190, 190]; } }
Bind the rect
property of pieChart
to the specified method of the func
property The following example shows the data binding between several types of properties, like background
, borderWidth
, rotation
and visible
, and the attr
property of the Data
.
background: {
value: '#2C3E50',
func: 'attr@switch.background'
},
visible: {
value: true,
func: 'attr@switch.visible'
}
borderWidth: {
value: 8,
func: 'attr@switch.thickness'
},
rotation: {
value: -Math.PI/4,
func: 'attr@switch.angle'
}
Icons are used as the presentation of appendages around the data. Refer to Introduction and 3D handbook. All the parameters defining icons can achieve the dynamic changes through data binding.
node.addStyleIcon('alarm', {
names: ['alarm-star', 'alarm-triangle', 'alarm-circle'],
position: {func: 'attr@alarm.position'},
direction: { func: 'attr@alarm.direction' },
gap: { func: 'attr@alarm.gap' },
width: { func: 'attr@alarm.width' },
height: { func: 'attr@alarm.height' },
visible: { func: 'attr@alarm.visible' },
rotation: { func: 'attr@alarm.rotation' },
stretch: { func: 'attr@alarm.stretch' },
opacity: { func: 'attr@alarm.opacity' },
transparent: { func: function (data){ return data.a('alarm.opacity') < 1; } },
light: { func: 'attr@alarm.light' },
textureScale: { func: 'attr@alarm.texture.scale' },
discardSelectable: { func: 'attr@alarm.discard.selectable' },
r3: { func: function (data) { return [0, 0, -data.a('alarm.rotation')]; } },
face: { func: 'attr@alarm.face' },
reverseFlip: { func: 'attr@alarm.reverse.flip' },
reverseCull: { func: 'attr@alarm.reverse.cull' },
reverseColor: { func: 'attr@alarm.reverse.color' },
autorotate: { func: 'attr@alarm.autorotate' }
});
User-defined 3D
models introduced in the Modeling Handbook also support the mechanism of data binding. Data binding is a characteristic function which makes the modeling of HT
far more powerful than the traditional 3D
modeling tools. All the parameters constructing models, like color, size and rotation, can be bound to the properties of the Data
model. After modeling in such a way, users just need to update the property values of the Data
object, and then the display effect of the corresponding data in the 3D
interface will be renewed constantly and synchronously.
The ems-block
model registered in the above example is constructed by a cube and a cylinder. The colors of the two models are bound to the attr
property value, circleColor
and rectColor
, respectively.
ht.Default.setShape3dModel('ems-block', [
{
shape3d: ht.Default.createCylinderModel(32, 0, 32, false, false, true, true),
r3: [Math.PI/2, 0, 0],
color: {
func: 'attr@circleColor',
value: '#3498DB'
}
},
{
shape3d: 'box',
s3: [1, 0.2, 1],
t3: [0, -0.7, 0],
color: {
func: 'attr@rectColor',
value: '#3498DB'
}
}
]);
All the common components of HT
also support the data binding of the vector images. TreeView
on the left side of this example exactly shows the vector icons which have achieved the data binding. The components of Graph3dView
and TreeView
are bound to the same data source. Therefore, modifying circleColor
and rectColor
of the attr
property can drive the different view components simultaneously.
ht.Default.setImage('ems-block', {
width: 18,
height: 18,
comps: [
{
type: 'circle',
rect: [0, 2, 18, 10],
background: {
func: 'attr@circleColor',
value: '#3498DB'
}
},
{
type: 'rect',
rect: [4, 14, 10, 3],
background: {
func: 'attr@rectColor',
value: '#3498DB'
}
}
]});
Icons can not only display planar graphs, but also support the arrangement of registered models as icons. The above example puts the icon of a 3d
model on the top of the Node
data.
This model is an alarm composed of three parts, whose colors are bound to the all.blend
value of the style
property. The rotation angle of the model is bound to alarm.rotation.*
.
var array = [
{
shape3d: ringModel,
color: { func: 'style@all.blend' },
r3: [Math.PI/2, 0, 0]
},
{
shape3d: sphereModel,
color: { func: 'style@all.blend' },
t3: [0, 30, 0]
},
{
shape3d: cylinderModel,
color: { func: 'style@all.blend' },
t3: [0, -10, 0]
}
];
ht.Default.setShape3dModel('alarm', {
shape3d: array,
t3: [0, 50, 0],
r3: {func: function (data){
return [
data.a('alarm.rotation.x'),
data.a('alarm.rotation.y'),
data.a('alarm.rotation.z')];
}}
});
The icons of 3d
models are different from those, whose arrays are defined by names
. At present, only one model name is allowed, and arrays are not supported yet. Several icons of 3d
models can be added through calling addStyleIcon
repeatedly.
node.addStyleIcon('alarm', {
position: 3,
face: 'center',
shape3d: 'alarm'
});