發現現在工業SCADA上或者電信網管方面用圖表的特別多,雖然絕大部分人在圖表製作方面用的是echarts,他確實好用,但是有些時候我們不能呼叫別的外掛,這個時候就得自己寫這些美麗的圖表了,然而圖表輕易做不成美麗的。。。看到有一個網站上在賣的圖表,感覺挺好看的,就用 HT for Web 3D 做了一個小例子,挺簡單的,也挺好看的,哈哈~
Demo 地址: http://www.hightopo.com/demo/WireframeAnim/index.html
動態效果圖如下:
這個例子用 HT 實現真的很容易,首先建立一個 HT 中最基礎的 dm 資料模型,然後將資料模型新增進 g3d 3d 元件中,再設定 3d 中的視角並把 3d 元件新增進 body 元素中:
dm = new ht.DataModel();
g3d = new ht.graph3d.Graph3dView(dm);
g3d.setEye(0, 185, 300);
g3d.addToDOM();
g3d.getView().style.background = '#000';
接著就是造這五個chart圖表條了,我的思路是這樣的,裡層有一個節點,外層一個透明的節點,底部一個 3d 的文字顯示當前的百分比。
裡層的節點非常容易,我直接用的 HT 封裝的 ht.Node 建立了一個新的節點物件,然後通過 node.s 方法來設定 node 節點的樣式:
var node = new ht.Node();
node.s({
'shape3d': cylinderModel,
'shape3d.color': color,
'3d.movable': false
});
node.a({
'myHeight': s3[1],
});
node.p3([p3[0], s3[1]/2, p3[2]]);
node.s3(s3);
dm.add(node);
其中要說明的是,'shape3d':cylinderModel 這個樣式的設定,首先,shape3d 屬性指定顯示為 3d 模型的圖示效果,cylinderModel 是用 HT 自定義的一個 3d 模型,可參考 HT for Web 建模手冊:
cylinderModel = ht.Default.createCylinderModel(1000, 0, 1000, false, false, true, true);
然後設定了一個動態變化的屬性 myHeight,在 HT 中,node.a 方法是預留給使用者儲存業務資料的,我們可以在這邊新增任意多個屬性。
接下來我們要建立的是外部的透明節點,這個節點的構造方式基本上與內部節點相同,就是多了一點“透明”的樣式設定:
var cNode = new ht.Node();
cNode.s({
'shape3d': cylinderModel,
'shape3d.transparent': true,
'shape3d.opacity': 0.2,
'label.color': '#fff',
'3d.movable': false
});
cNode.p3([p3[0], 50, p3[2]]);
cNode.s3(20, 100, 20);
dm.add(cNode);
要先設定 ‘shape3d.transparent’ 為true,再設定 ‘shape3d.opacity’ 透明度。
最後是 3d 文字,呈現 3d 文字需要一個 json 格式的 typeface 字型,然後通過 ht.Default.loadFontFace 來載入 json 格式的字型到記憶體中,詳情請參考 HT for Web 3D 手冊:
ht.Default.loadFontFace('./wenquanyi.json', function(){
//......
var text = new ht.Node();
text.s3([5, 5, 5]);
text.p3(cNode.p3()[0]-5, -10, 0);
dm.add(text);
text.s({
'shape3d' : 'text',
'shape3d.text': node.a('myHeight')+'%',
'shape3d.text.curveSegments': 1,
'3d.movable': false
});
});
因為我們用的 typeface 字型的繪製方式是無數個三角形構成的一個字,會佔用很大的記憶體,所以我把圖形的曲線的精細度調得較低,但是還是很清晰,如果你們能找到效能更好的字型,可以使用並且告知我一下,我們目前沒找到佔用記憶體小的字型。
最後,要動態的變化 chart 圖表中的柱形圖,我們得設定動畫,並且將 3d 字型也同步更新數值:
setInterval(function(){
if(node.a('myHeight') < 100){
node.a('myHeight', (node.getAttr('myHeight')+1));
node.s3(20, node.a('myHeight'), 20);
node.p3(p3[0], node.a('myHeight')/2, p3[2]);
}else{
node.a('myHeight', 0);
node.s3([20, 0, 20]);
node.p3([p3[0], 0, p3[2]]);
}
if (text) text.s('shape3d.text', node.a('myHeight')+'%');
}, 100);
這裡,我自定義的屬性 “myHeight” 就起到了決定性的作用,我用這個屬性來儲存變數,而且可以任意更改變數的值,這樣就能實現動態繫結的效果了。
還有不懂的可以留言,或者直接去我們官網上檢視手冊 HT for Web,有更多你想不到的效果能快速實現哦~