Skip to content

Instantly share code, notes, and snippets.

@wallabyway
Created May 16, 2023 06:12
Show Gist options
  • Save wallabyway/1b10c701a74a19d66b37032d1ddf3f1b to your computer and use it in GitHub Desktop.
Save wallabyway/1b10c701a74a19d66b37032d1ddf3f1b to your computer and use it in GitHub Desktop.
minimal powerBI visual component with three.js (spinning grid)
{
"name": "visual",
"description": "default_template_value",
"repository": {
"type": "default_template_value",
"url": "default_template_value"
},
"license": "MIT",
"scripts": {
"pbiviz": "pbiviz",
"start": "pbiviz start",
"package": "pbiviz package",
"lint": "tslint -c tslint.json -p tsconfig.json"
},
"dependencies": {
"@types/d3": "5.7.2",
"@types/three": "^0.134.0",
"d3": "5.12.0",
"powerbi-visuals-api": "~5.1.0",
"three": "^0.134.0"
},
"devDependencies": {
"ts-loader": "6.1.0",
"tslint": "^5.18.0",
"tslint-microsoft-contrib": "^6.2.0",
"typescript": "3.6.3"
}
}
import {PerspectiveCamera, WebGLRenderer, GridHelper, Scene} from "three";
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;
export class Visual implements IVisual {
private target: HTMLElement;
private scene: Scene;
private renderer: WebGLRenderer;
private camera: PerspectiveCamera;
private gridHelper: GridHelper;
constructor(options: VisualConstructorOptions) {
console.log('Visual constructor', options);
this.scene = new Scene();
this.target = options.element;
if (document) {
const new_div: HTMLElement = document.createElement("div");
new_div.id = "threejs-canvas";
this.target.appendChild(new_div);
this.initScene();
this.animate();
window.addEventListener('resize', this.resize)
}
}
private initScene() {
var camera = new PerspectiveCamera(75, 2.5, 0.1,1000);
camera.position.y = 1;
camera.position.z = 5;
this.camera = camera;
const renderer = new WebGLRenderer();
renderer.setPixelRatio(1.5);
renderer.setSize(window.innerWidth,window.innerHeight);
renderer.setClearColor('#FFFFFF');
this.target.append(renderer.domElement);
this.renderer = renderer;
this.gridHelper = new GridHelper( 13, 13 );
this.scene.add( this.gridHelper );
}
private animate = () => {
requestAnimationFrame(this.animate)
this.gridHelper.rotation.y += 0.75 * Math.PI / 360;
this.renderer.render( this.scene, this.camera );
}
private resize = () => {
this.renderer.setSize(window.innerWidth,window.innerHeight);
this.camera.aspect = window.innerWidth/window.innerHeight;
this.camera.updateProjectionMatrix();
this.renderer.render( this.scene, this.camera );
}
public update(options: VisualUpdateOptions) {
console.log('Visual update', options);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment