[]
        
(Showing Draft Content)

自定义脚本

1.功能概述

通过自定义脚本可以实现很多定制功能,Wyn 3D场景是基于 Babylon.js 框架开发的,我们会在自定义脚本中将 Babylon.js 对象暴露出来。

例如我们可以通过自定义脚本实现这样一个场景:动态切换3D场景的中的房子隐藏或者呈现。

3D-JS脚本

具体操作步骤如下:

2. 3D场景中添加自定义脚本

单击场景设定,在属性设置中找到数据交互,打开以后可以看到自定义脚本,单击右侧加号。

image

自定义脚本包含三部分:

  • 脚本名称

  • 脚本执行时机

  • 脚本内容

2.1脚本名称

自定义脚本名称不能为空,全局不能重复,在选择自定义脚本的时候,名字会作为候选项出现。

2.2脚本执行时机

执行脚本的时机,支持场景加载完成、数据图层加载完成、数据图层数据改变和手动触发四种执行时机。

脚本执行时机

描述

方法接口声明

场景加载完成

整个3D场景的物理模型在浏览器中加载完成

function (BABYLON, engine, scene, sceneData) {

}

数据图层加载完成

3D场景的所有数据图层数据加载完成

function (BABYLON, engine, scene, sceneData) {

}

数据图层数据改变

3D场景中某一个数据图层的数据发生改变,通常发生在

数据图层的自动刷新数据时,或者其他图表产生交叉过滤时。

function (BABYLON, engine, scene, sceneData, dataLayerData) {

}

手动触发

手动触发这个自定脚本,通常通过3D场景中节点的点击,

或者仪表板中的对象点击触发

function (BABYLON, engine, scene, sceneData, args) {

}

2.3脚本内容

在脚本中可以引用方法接口上的参数,参数列表如下:

sceneData是一个JavaScript对象,提供了一些辅助的方法,来实现一些特殊的效果,这里介绍一些常用的方法和属性,完整的API文档参见 ISceneData

成员

描述

示例

parameters

参数属性


focusNode("nodeName")

聚焦模型节点方法

sceneData.focusNode("nodeName")

highlightNode("nodeName")

高亮模型节点方法

sceneData.highlightNode("nodeName")

updateDataLayer()

更新所有的数据图层


enableDataLayer("dataLayerName")

显示数据图层

sceneData.enableDataLayer("模型数据标注")

disableDataLayer("dataLayerName")

隐藏数据图层

sceneData.disableDataLayer("模型数据标注")

playPathTravel(pathTravelName:string, loopMode: 'once'|'repeat')

开始路径漫游


switchPathTravel()

暂停/恢复路径漫游


stopPathTravel()

停止路径漫游


playDataPointsTravel()

开始数据点漫游


switchDataPointsTravel()

暂停/恢复数据点漫游


stopDataPointsTravel()

停止数据点漫游


playAnimation(animationName: string)

开始动画


switchAnimation(animationName: string)

暂停/恢复动画


stopAnimation(animationName: string)

停止动画


dataLayerData是一个JavaScript对象,包含了指定的数据图层的数据信息,完整的API文档参见 IPlainDataView

成员

描述

数据绑定

示例

dataView

数据图层的绑定数据

image

通过 dataLayerData.dataView.data 接口获取绑定数据,示例中包含了6个数据点,可以通过绑定的名字获取到。

image

args 是一个JavaScript对象,包含了选中的数据以及扩展数据,接口如下:

{    
    selections: [],   // 图表上选中的数据
    extendedData: {}  // 自定义扩展数据
}

2.4示例脚本

示例脚本1:控制四个小房子的隐藏和出现,最后单击确定:

['house1', 'house2', 'house3', 'house4'].forEach((house) => {
    const houseNode = scene.getTransformNodeByName(house);
    houseNode.getChildMeshes().forEach(mesh => mesh.isVisible = !mesh.isVisible);
});

示例脚本2:通过args来获取selection,最后聚焦该节点:

sceneData.focusNode(args.selections[0]['客户地区'])

示例脚本3:显示刷新帧率:

var instrumentation = new BABYLON.EngineInstrumentation(engine);
instrumentation.captureGPUFrameTime = true;
instrumentation.captureShaderCompilationTime = true;

var advancedTexture = BABYLON.GUI.AdvancedDynamicTexture.CreateFullscreenUI("UI");

var stackPanel = new BABYLON.GUI.StackPanel();
stackPanel.verticalAlignment = BABYLON.GUI.Control.VERTICAL_ALIGNMENT_TOP;
stackPanel.isVertical = true;

function createRenderText() {
  var textBlock = new BABYLON.GUI.TextBlock();
  textBlock.text = "";
  textBlock.color = "white";
  textBlock.fontSize = 16;
  textBlock.height = "30px";
  return textBlock;
}

var text1 = createRenderText();

stackPanel.addControl(text1);

advancedTexture.addControl(stackPanel);

scene.registerBeforeRender(function () {
  text1.text = "帧数: " + engine.getFps().toFixed(2) + " FPS";
});

image


示例脚本4:为指定节点添加高亮颜色:

let highlightLayer = scene.getHighlightLayerByName('myHighlightLayer');
if(highlightLayer){
  return;
}
const house = scene.getTransformNodeByName('house5');
const color = '#ff6347';
highlightLayer= new BABYLON.HighlightLayer('myHighlightLayer', scene);
house.getChildMeshes().forEach((mesh) => {
  highlightLayer.addMesh(mesh, BABYLON.Color3.FromHexString(color));
});

image


示例脚本5:为指定节点移除高亮颜色:

const house = scene.getTransformNodeByName('house5');
const highlightLayer = scene.getHighlightLayerByName('myHighlightLayer');
if(!highlightLayer){
  return;
}
house.getChildMeshes().forEach((mesh) => {
  highlightLayer.removeMesh(mesh);
});
highlightLayer.dispose();

示例脚本6:动画隐藏节点:

// helper methods
const hideMeshesWithAnimation = (scene, meshNameList) => {
  const animationGroup = new BABYLON.AnimationGroup('visible', scene);
  meshNameList.forEach((meshName) => {
    const animation = new BABYLON.Animation(
      'animation-' + meshName,
      'visibility',
      60,
      BABYLON.Animation.ANIMATIONTYPE_FLOAT,
      BABYLON.Animation.ANIMATIONLOOPMODE_CONSTANT,
    );
    animation.setKeys([
      {
        frame: 0,
        value: 1,
      },
      {
        frame: 60,
        value: 0,
      },
    ]);
    const mesh = scene.getMeshByName(meshName);
    animationGroup.addTargetedAnimation(animation, mesh);
  })
  animationGroup.start();
};

showMeshesWithAnimation(scene, ['house1_primitive0', 'house1_primitive1'])

meshAnimation

3.模型节点点击调用自定义脚本

选中一个模型节点,在右侧的属性面板上

  • 将支持点击设定为允许

  • 将点击行为设定为自定义脚本

  • 在自定义脚本中选择需要执行的脚本

  • 预览3D场景,点击模型节点,该脚本会被执行

  • 扩展数据属性,会被作为参数传递到自定义脚本中去,通过 args.extendedData 可以访问到

image

4.数据图层节点点击调用自定义脚本

选中一个数据图层,在右侧的属性面板上

  • 将点击行为设定为自定义脚本

  • 在自定义脚本中选择需要执行的脚本

  • 预览3D场景,点击该数据图层的任意模型节点,该脚本会被执行

  • 这个时候该节点的绑定数据,会作为参数传入到自定义脚本中,通过 args.selections 可以访问到

  • 扩展数据属性,会被作为参数传递到自定义脚本中去,通过 args.extendedData 可以访问到

image

5.仪表板组件调用调用自定义脚本

示例中是一个手动触发的JS脚本,所以这里我们添加一个图片,并为其设置左键选项为命令

image

添加一条命令,并设置命令。

image

image

扩展数据属性,会被作为参数传递到自定义脚本中去,通过 args.extendedData 可以访问到。

如果是数据图表点击触发的自定义脚本,该图表的选择数据会通过 args.selections 可以访问到。


预览即呈现预期的效果。

3D-JS脚本

同理,仪表板的其他可视化组件也支持调用自定义脚本,例如柱状图,步骤与上面一致,并且该图表的选择数据会作为参数传递到自定义脚本中,通过 args.selections 可以访问到。