I am currently trying to use Three.js to visualise meshes in microsoft Power BI. The PowerBI template uses an interface called IVisual, I have as yet been unable to make three.js objects appear within the PowerBI window though. Code is below, any help would be much appreciated
code:
"use strict";
import "core-js/stable";
import "./../style/visual.less";
import powerbi from "powerbi-visuals-api";
import VisualConstructorOptions = powerbi.extensibility.visual.VisualConstructorOptions;
import VisualUpdateOptions = powerbi.extensibility.visual.VisualUpdateOptions;
import IVisual = powerbi.extensibility.visual.IVisual;
import EnumerateVisualObjectInstancesOptions = powerbi.EnumerateVisualObjectInstancesOptions;
import VisualObjectInstance = powerbi.VisualObjectInstance;
import DataView = powerbi.DataView;
import VisualObjectInstanceEnumerationObject = powerbi.VisualObjectInstanceEnumerationObject;
import * as THREE from 'three'
import { VisualSettings } from "./settings";
export class Visual implements IVisual {
private target: HTMLElement;
private updateCount: number;
private settings: VisualSettings;
private textNode: Text;
private camera: THREE.PerspectiveCamera;
private renderer: THREE.WebGLRenderer;
private geometry: THREE.PolyhedronGeometry;
private materials: THREE.MeshStandardMaterial;
private mesh: THREE.Mesh;
private light: THREE.PointLight;
constructor(options: VisualConstructorOptions) {
let scene = new THREE.Scene();
console.log('Visual constructor', options);
this.target = options.element;
this.updateCount = 0;
if (document) {
const new_p: HTMLElement = document.createElement("p");
new_p.appendChild(document.createTextNode("Updates: "));
const new_em: HTMLElement = document.createElement("em");
this.textNode = document.createTextNode(this.updateCount.toString());
const new_m: HTMLElement = document.createElement("M");
new_em.appendChild(this.textNode);
new_p.appendChild(new_em);
this.target.appendChild(new_p);
this.camera = new THREE.PerspectiveCamera(100,window.innerWidth/window.innerHeight,0.1,1000);
this.camera.position.z=5;
this.renderer = new THREE.WebGLRenderer();
this.renderer.setSize(window.innerWidth,window.innerHeight);
this.renderer.setClearColor('#D13D1D');
window.addEventListener('resize',()=>{
this.renderer.setSize(window.innerWidth,window.innerHeight);
this.camera.aspect = window.innerWidth/window.innerHeight;
this.camera.updateProjectMatrix();
})
this.geometry = new THREE.SphereGeometry(1.5,10,10);
this.materials = new THREE.MeshStandardMaterial({color: 0xFFFFFF})
this.mesh = new THREE.Mesh(this.geometry,this.materials);
this.mesh.material.color.set("green");
this.light = new THREE.PointLight(0xFFFFFF,1,500);
this.light.position.set(10,0,40);
scene.add(this.light);
scene.add(this.mesh);
document.appendChild(new_m);
this.renderer.render(scene,this.camera);
this.target.append(this.renderer);
}
}
public update(options: VisualUpdateOptions) {
this.settings = Visual.parseSettings(options && options.dataViews && options.dataViews[0]);
console.log('Visual update', options);
if (this.textNode) {
this.textNode.textContent = (this.updateCount++).toString();
}
}
private static parseSettings(dataView: DataView): VisualSettings {
return <VisualSettings>VisualSettings.parse(dataView);
}
/**
* This function gets called for each of the objects defined in the capabilities files and allows you to select which of the
* objects and properties you want to expose to the users in the property pane.
*
*/
public enumerateObjectInstances(options: EnumerateVisualObjectInstancesOptions): VisualObjectInstance[] | VisualObjectInstanceEnumerationObject {
return VisualSettings.enumerateObjectInstances(this.settings || VisualSettings.getDefault(), options);
}
}