[]
通过自定义脚本可以实现很多定制功能,Wyn 3D场景是基于 Babylon.js 框架开发的,我们会在自定义脚本中将 Babylon.js 对象暴露出来。
例如我们可以通过自定义脚本实现这样一个场景:动态切换3D场景的中的房子隐藏或者呈现。
具体操作步骤如下:
单击场景设定,在属性设置中找到数据交互,打开以后可以看到自定义脚本,单击右侧加号。
自定义脚本包含三部分:
脚本名称
脚本执行时机
脚本内容
自定义脚本名称不能为空,全局不能重复,在选择自定义脚本的时候,名字会作为候选项出现。
执行脚本的时机,支持场景加载完成、数据图层加载完成、数据图层数据改变和手动触发四种执行时机。
脚本执行时机 | 描述 | 方法接口声明 |
---|---|---|
场景加载完成 | 整个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) { } |
在脚本中可以引用方法接口上的参数,参数列表如下:
BABYLON: BABYLON 全局类型对象, API 文档参见 https://doc.babylonjs.com/typedoc/modules/BABYLON
engine: BABYLON Engine 实例对象, API 文档参见 https://doc.babylonjs.com/typedoc/classes/BABYLON.Engine
scene: BABYLON Scene 实例对象, API 文档参见 https://doc.babylonjs.com/typedoc/classes/BABYLON.Scene
sceneData:Wyn SceneData 实例对象,API 文档参见 ISceneData。
dataLayerData: Wyn数据图层实例对象,包含了数据图层绑定的数据,API文档参见 IPlainDataView。
args:点击3D模型节点对象或者仪表板图表,来执行自定义脚本时,传入的数据对象。
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 | 数据图层的绑定数据 | 通过 dataLayerData.dataView.data 接口获取绑定数据,示例中包含了6个数据点,可以通过绑定的名字获取到。 |
args 是一个JavaScript对象,包含了选中的数据以及扩展数据,接口如下:
{
selections: [], // 图表上选中的数据
extendedData: {} // 自定义扩展数据
}
示例脚本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";
});
示例脚本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));
});
示例脚本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'])
选中一个模型节点,在右侧的属性面板上
将支持点击设定为允许
将点击行为设定为自定义脚本
在自定义脚本中选择需要执行的脚本
预览3D场景,点击模型节点,该脚本会被执行
扩展数据属性,会被作为参数传递到自定义脚本中去,通过 args.extendedData 可以访问到
选中一个数据图层,在右侧的属性面板上
将点击行为设定为自定义脚本
在自定义脚本中选择需要执行的脚本
预览3D场景,点击该数据图层的任意模型节点,该脚本会被执行
这个时候该节点的绑定数据,会作为参数传入到自定义脚本中,通过 args.selections 可以访问到
扩展数据属性,会被作为参数传递到自定义脚本中去,通过 args.extendedData 可以访问到
示例中是一个手动触发的JS脚本,所以这里我们添加一个图片,并为其设置左键选项为命令。
添加一条命令,并设置命令。
扩展数据属性,会被作为参数传递到自定义脚本中去,通过 args.extendedData 可以访问到。
如果是数据图表点击触发的自定义脚本,该图表的选择数据会通过 args.selections 可以访问到。
预览即呈现预期的效果。
同理,仪表板的其他可视化组件也支持调用自定义脚本,例如柱状图,步骤与上面一致,并且该图表的选择数据会作为参数传递到自定义脚本中,通过 args.selections 可以访问到。