UNPKG

@webviz/subsurface-viewer

Version:

3D visualization component for subsurface reservoir data

172 lines 6.96 kB
import { Layer, picking, project32 } from "@deck.gl/core"; import { GL } from "@luma.gl/constants"; import { Geometry, Model } from "@luma.gl/engine"; import { Vector2 } from "@math.gl/core"; import { createPropertyData } from "../utils/layerTools"; import { precisionForTests } from "../shader_modules/test-precision/precisionForTests"; import fragmentShader from "./piechart.fs.glsl"; import vertexShader from "./piechart.vs.glsl"; const defaultProps = { "@@type": "PieChartLayer", name: "Pie chart", id: "pie-layer", pickable: true, visible: true, selectedPie: "@@editedData.selectedPie", // used to get data from deckgl layer depthTest: true, }; export default class PieChartLayer extends Layer { initializeState() { return; } shouldUpdateState() { return true; } updateState({ context }) { var _a; if (!((_a = this.state) === null || _a === void 0 ? void 0 : _a["model"])) { const pieData = this.props.data; if (pieData === null || pieData === void 0 ? void 0 : pieData.pies) { this.setState(this.getModel(context.device, pieData)); } } } getModel(device, pieData) { var _a, _b; const vertexs = []; const colors = []; const mx = []; const my = []; const doScale = []; const pieInfo = []; const pieInfoIndex = []; const dA = 5; // delta angle let infoIndex = 0; for (const pie of pieData.pies) { const x = pie.x; const y = pie.y; const R = pie.R; // Normalize let sum = 0; for (const frac of pie.fractions) { sum += frac.value; } if (sum === 0) { continue; } let start_a = -90.0; for (let i = 0; i < pie.fractions.length; i++) { const frac = pie.fractions[i].value / sum; const end_a = start_a + frac * 360.0; const prop = pieData.properties[pie.fractions[i].idx]; let col = (_a = prop === null || prop === void 0 ? void 0 : prop.color) !== null && _a !== void 0 ? _a : [ 255, 0, 255, 255, ]; // magenta col = col.map((x) => (x !== null && x !== void 0 ? x : 0) / 255 // Normalize to [0,1] range. ); const name = (_b = prop === null || prop === void 0 ? void 0 : prop.label) !== null && _b !== void 0 ? _b : "no label"; const frac_string = (frac * 100).toFixed(1) + "%"; pieInfo.push([name, frac_string]); // Make triangles for one pie pice. for (let a = start_a; a < end_a; a += dA) { const a1 = a; const rad1 = (a1 * (2.0 * Math.PI)) / 360.0; const xx1 = R * Math.cos(rad1) + x; const yy1 = R * Math.sin(rad1) + y; const a2 = Math.min(a1 + dA, end_a); const rad2 = (a2 * (2.0 * Math.PI)) / 360.0; const xx2 = R * Math.cos(rad2) + x; const yy2 = R * Math.sin(rad2) + y; vertexs.push(x, y, 0); mx.push(x); my.push(y); colors.push(...col); pieInfoIndex.push(infoIndex); doScale.push(0); vertexs.push(xx1, yy1, 0); mx.push(x); my.push(y); colors.push(...col); pieInfoIndex.push(infoIndex); doScale.push(1); vertexs.push(xx2, yy2, 0); mx.push(x); my.push(y); colors.push(...col); pieInfoIndex.push(infoIndex); doScale.push(1); } infoIndex++; start_a = end_a; } } const model = new Model(device, Object.assign(Object.assign({ id: `${this.props.id}-pie` }, super.getShaders({ vs: vertexShader, fs: fragmentShader, modules: [project32, picking, precisionForTests], })), { geometry: new Geometry({ topology: "triangle-list", attributes: { positions: { value: new Float32Array(vertexs), size: 3 }, colors: { value: new Float32Array(colors), size: 3 }, pie_index: { value: new Int32Array(pieInfoIndex), size: 1 }, mx: { value: new Float32Array(mx), size: 1 }, my: { value: new Float32Array(my), size: 1 }, do_scale: { value: new Float32Array(doScale), size: 1 }, }, vertexCount: vertexs.length / 3, }), isInstanced: false })); return { model, pieInfo }; } // Signature from the base class, eslint doesn't like the any type. // eslint-disable-next-line draw(args) { var _a; if (!((_a = this.state) === null || _a === void 0 ? void 0 : _a["model"])) { return; } const { context } = args; const { gl } = context; const npixels = 100; const p1 = [0, 0]; const p2 = [npixels, 0]; const p1_unproj = this.context.viewport.unproject(p1); const p2_unproj = this.context.viewport.unproject(p2); const v1 = new Vector2(p1_unproj[0], p1_unproj[1]); const v2 = new Vector2(p2_unproj[0], p2_unproj[1]); const d = v1.distance(v2); // Factor to convert a length in pixels to a length in world space. const pixels2world = d / npixels; const scale = pixels2world; const model = this.state["model"]; if (!this.props.depthTest) { gl.disable(GL.DEPTH_TEST); } model.setUniforms({ scale }); model.draw(context.renderPass); if (!this.props.depthTest) { gl.enable(GL.DEPTH_TEST); } } decodePickingColor() { return this.nullPickingColor(); } getPickingInfo({ info }) { if (!info.color) { return info; } // Note these colors are in the 0-255 range. const r = info.color[0]; const g = info.color[1]; const b = info.color[2]; const pieIndex = 256 * 256 * r + 256 * g + b; const pieInfo = this.state["pieInfo"]; const [pie_label, pie_frac] = pieInfo[pieIndex]; const layer_properties = []; layer_properties.push(createPropertyData(pie_label, pie_frac)); return Object.assign(Object.assign({}, info), { properties: layer_properties }); } } PieChartLayer.layerName = "PieChartLayer"; PieChartLayer.defaultProps = defaultProps; //# sourceMappingURL=pieChartLayer.js.map