将拓扑图和图表绘制在 3D 六面体上

忽然有个想法,若是能把一些用到不一样的知识点放到同一个界面上,而且放到一个盒子里,这样我若是要看什么东西就能够很直接显示出来,并且这个盒子必定要能打开。我用 HT 实现了个人想法,代码一百多行,这么少的代码能实现这种效果我以为仍是牛的。javascript

先来看看效果图: 在这里插入图片描述 这个例子最基础的就是最外层的盒子了,因此咱们先来看看如何实现它:html

var box = new ht.CSGBox();
dataModel.add(box);

用 HT 能够很轻易地实现这个盒子,在 HT 中封装了不少基础图元类型,咱们常常用到的 ht.Node 也是其中一个,这样咱们能够不用反复地写相同的代码来完成基础的实现。java

这个例子中用的封装好的基础图元是 ht.CSGBox,一个盒子模型,能够参考 HT for Web 建模手册,咱们在手册中能够看到,在 CSGBox 中咱们只能操做这个盒子的各个面,若是你想要本身设置一些特殊的功能,只须要操做 ht.Style(HT for Web 风格手册)便可。json

要想实如今盒子上的一个面上添加贴图,我能想到的只有 HT 封装的 ht.Default.setImage 函数了。canvas

我想大家都注意到了盒子上有模型化的水泵,上面有扇叶在旋转,调用graphView.deserialize(json) 来将 json 文件导出成可视化的 2d 模型并设置 animation 动画,再当即刷新到这个水泵,不然就算设置了动画,水泵上的扇叶旋转也不会生效。echarts

ht.Default.xhrLoad('displays/demo/pump.json', function(text){
    const json = ht.Default.parse(text);
    pumpDM.deserialize(json);
    var currentRotation = 0;
    var lastTime = new Date().getTime();

    setInterval(function(){
        var time = new Date().getTime();
        var deltaTime = time - lastTime;
        currentRotation += deltaTime * Math.PI / 180 * 0.3;
        lastTime = time;

        pumpDM.getDataByTag('fan1').setRotation(currentRotation);
        pumpDM.getDataByTag('fan2').setRotation(currentRotation);
        box.iv();
        // g3d.iv();这边也能够刷新g3d,可是局部刷新更省
        pumpGV.validateImpl();
    }, 10);
}, 10);

这个时候我不能把水泵的 graphView 和 g3d 都加到底层div上,而且个人意图是把水泵的 graphView 加到 g3d 中的 CSGBox 中的一面上,因此为了让水泵显示出来 必须设置水泵所在的 graphView 的宽高,而这个宽高必须比我 json 画出来的图占的面积要大,否则显示不完整。若是想看这个宽高对显示的影响,能够本身改改看来玩玩。ide

pumpGV.getWidth = function() { return 600;}
pumpGV.getHeight = function(){ return 600;}
pumpGV.getCanvas().dynamic = true; // 设置这个是为了让 canvas 能动态显示

这边还要特别说明一个函数 getDataByTag(tagName) 这个函数是获取标识号,在 HT 中 tag 属性是惟一标识,虽然 HT 中也有 id,可是 id 是 HT 中 Data 类型对象构造时内部自动被赋予的一个 id 属性,能够经过 data.getId() 和 data.setId(id) 获取和设置,Data 对象添加到 DataModel 以后不容许修改 id 值,能够经过 dataModel.getDataById(id) 快速查找 Data 对象。函数

通常咱们建议 id 属性由 HT 自动分配,用户业务意义的惟一标示可存在于 tag 属性上,经过 data.setTag(tag) 函数容许任意动态改变 tag 值,经过 dataModel.getDataByTag(tag) 可查找到对应的 Data 对象,并支持经过 dataModel.removeDataByTag(tag) 删除 Data 对象。动画

你可能会好奇在代码中咱们并无提到 “fan1” 这个 tag 标识,这个标识是在水泵的 json 中设置的,关于扇叶的一个标识,咱们获取到扇叶,而后设置其旋转。ui

echarts 图表的显示也是很基础的,可是咱们会发现,在将 echarts 图表添加进 graphView 中它的动画效果会不显示,因此咱们首先要将这个 echarts 图表所在的图表的 dynamic 设置为 true,即将其设置为动态:

function charts(option){
    var info = {
        canvas: document.createElement('canvas')
    };
    info.canvas.dynamic = true; // 设置 info.canvas 为动态
    info.chart = echarts.init(info.canvas);
    info.chart.setOption(option);
    return info.canvas;
}

最后,只须要将这两个回传的 canvas 传入 ht.Default.setImage 中便可:

ht.Default.setImage('echart', charts(option));
ht.Default.setImage('pump', pumpGV.getCanvas());

ht.Default.drawImage 函数生成新的图实际上就是在 canvas 上画图,因此咱们只要把咱们已经画好的 canvas 传到 ht.Default.setImage 就能够生成图片了。

相关文章
相关标签/搜索