UNPKG

cione-comp-lib

Version:

`$ yarn add cione-comp-lib` 或者 `$ npm i cione-comp-lib -S`

197 lines (196 loc) 7.7 kB
import "../../../../echarts/lib/echarts.mjs"; import graphicGL from "../../util/graphicGL.mjs"; import retrieve from "../../util/retrieve.mjs"; import LinesGeometry from "../../util/geometry/Lines3D.mjs"; import Matrix4 from "../../../../claygl/src/math/Matrix4.mjs"; import Vector3 from "../../../../claygl/src/math/Vector3.mjs"; import { containStroke } from "../../../../zrender/lib/contain/line.mjs"; import glmatrix from "../../../../claygl/src/glmatrix/index.mjs"; import { getItemVisualColor, getItemVisualOpacity } from "../../util/visual.mjs"; import lines3DGLSL from "../../util/shader/lines3D.glsl.mjs"; import ChartView from "../../../../echarts/lib/view/Chart.mjs"; var vec3 = glmatrix.vec3; graphicGL.Shader.import(lines3DGLSL); var Line3DView = ChartView.extend({ type: "line3D", __ecgl__: true, init: function(ecModel, api) { this.groupGL = new graphicGL.Node(); this._api = api; }, render: function(seriesModel, ecModel, api) { var tmp = this._prevLine3DMesh; this._prevLine3DMesh = this._line3DMesh; this._line3DMesh = tmp; if (!this._line3DMesh) { this._line3DMesh = new graphicGL.Mesh({ geometry: new LinesGeometry({ useNativeLine: false, sortTriangles: true }), material: new graphicGL.Material({ shader: graphicGL.createShader("ecgl.meshLines3D") }), renderOrder: 10 }); this._line3DMesh.geometry.pick = this._pick.bind(this); } this.groupGL.remove(this._prevLine3DMesh); this.groupGL.add(this._line3DMesh); var coordSys = seriesModel.coordinateSystem; if (coordSys && coordSys.viewGL) { coordSys.viewGL.add(this.groupGL); var methodName = coordSys.viewGL.isLinearSpace() ? "define" : "undefine"; this._line3DMesh.material[methodName]("fragment", "SRGB_DECODE"); } this._doRender(seriesModel, api); this._data = seriesModel.getData(); this._camera = coordSys.viewGL.camera; this.updateCamera(); this._updateAnimation(seriesModel); }, updateCamera: function() { this._updateNDCPosition(); }, _doRender: function(seriesModel, api) { var data = seriesModel.getData(); var lineMesh = this._line3DMesh; lineMesh.geometry.resetOffset(); var points = data.getLayout("points"); var colorArr = []; var vertexColors = new Float32Array(points.length / 3 * 4); var colorOffset = 0; var hasTransparent = false; data.each(function(idx) { var color = getItemVisualColor(data, idx); var opacity = getItemVisualOpacity(data, idx); if (opacity == null) { opacity = 1; } graphicGL.parseColor(color, colorArr); colorArr[3] *= opacity; vertexColors[colorOffset++] = colorArr[0]; vertexColors[colorOffset++] = colorArr[1]; vertexColors[colorOffset++] = colorArr[2]; vertexColors[colorOffset++] = colorArr[3]; if (colorArr[3] < 0.99) { hasTransparent = true; } }); lineMesh.geometry.setVertexCount(lineMesh.geometry.getPolylineVertexCount(points)); lineMesh.geometry.setTriangleCount(lineMesh.geometry.getPolylineTriangleCount(points)); lineMesh.geometry.addPolyline(points, vertexColors, retrieve.firstNotNull(seriesModel.get("lineStyle.width"), 1)); lineMesh.geometry.dirty(); lineMesh.geometry.updateBoundingBox(); var material = lineMesh.material; material.transparent = hasTransparent; material.depthMask = !hasTransparent; var debugWireframeModel = seriesModel.getModel("debug.wireframe"); if (debugWireframeModel.get("show")) { lineMesh.geometry.createAttribute("barycentric", "float", 3); lineMesh.geometry.generateBarycentric(); lineMesh.material.set("both", "WIREFRAME_TRIANGLE"); lineMesh.material.set("wireframeLineColor", graphicGL.parseColor(debugWireframeModel.get("lineStyle.color") || "rgba(0,0,0,0.5)")); lineMesh.material.set("wireframeLineWidth", retrieve.firstNotNull(debugWireframeModel.get("lineStyle.width"), 1)); } else { lineMesh.material.set("both", "WIREFRAME_TRIANGLE"); } this._points = points; this._initHandler(seriesModel, api); }, _updateAnimation: function(seriesModel) { graphicGL.updateVertexAnimation([["prevPosition", "position"], ["prevPositionPrev", "positionPrev"], ["prevPositionNext", "positionNext"]], this._prevLine3DMesh, this._line3DMesh, seriesModel); }, _initHandler: function(seriesModel, api) { var data = seriesModel.getData(); var coordSys = seriesModel.coordinateSystem; var lineMesh = this._line3DMesh; var lastDataIndex = -1; lineMesh.seriesIndex = seriesModel.seriesIndex; lineMesh.off("mousemove"); lineMesh.off("mouseout"); lineMesh.on("mousemove", function(e) { var value = coordSys.pointToData(e.point.array); var dataIndex = data.indicesOfNearest("x", value[0])[0]; if (dataIndex !== lastDataIndex) { api.dispatchAction({ type: "grid3DShowAxisPointer", value: [data.get("x", dataIndex), data.get("y", dataIndex), data.get("z", dataIndex)] }); lineMesh.dataIndex = dataIndex; } lastDataIndex = dataIndex; }, this); lineMesh.on("mouseout", function(e) { lastDataIndex = -1; lineMesh.dataIndex = -1; api.dispatchAction({ type: "grid3DHideAxisPointer" }); }, this); }, _updateNDCPosition: function() { var worldViewProjection = new Matrix4(); var camera = this._camera; Matrix4.multiply(worldViewProjection, camera.projectionMatrix, camera.viewMatrix); var positionNDC = this._positionNDC; var points = this._points; var nPoints = points.length / 3; if (!positionNDC || positionNDC.length / 2 !== nPoints) { positionNDC = this._positionNDC = new Float32Array(nPoints * 2); } var pos = []; for (var i = 0; i < nPoints; i++) { var i3 = i * 3; var i2 = i * 2; pos[0] = points[i3]; pos[1] = points[i3 + 1]; pos[2] = points[i3 + 2]; pos[3] = 1; vec3.transformMat4(pos, pos, worldViewProjection.array); positionNDC[i2] = pos[0] / pos[3]; positionNDC[i2 + 1] = pos[1] / pos[3]; } }, _pick: function(x, y, renderer, camera, renderable, out) { var positionNDC = this._positionNDC; var seriesModel = this._data.hostModel; var lineWidth = seriesModel.get("lineStyle.width"); var dataIndex = -1; var width = renderer.viewport.width; var height = renderer.viewport.height; var halfWidth = width * 0.5; var halfHeight = height * 0.5; x = (x + 1) * halfWidth; y = (y + 1) * halfHeight; for (var i = 1; i < positionNDC.length / 2; i++) { var x0 = (positionNDC[(i - 1) * 2] + 1) * halfWidth; var y0 = (positionNDC[(i - 1) * 2 + 1] + 1) * halfHeight; var x1 = (positionNDC[i * 2] + 1) * halfWidth; var y1 = (positionNDC[i * 2 + 1] + 1) * halfHeight; if (containStroke(x0, y0, x1, y1, lineWidth, x, y)) { var dist0 = (x0 - x) * (x0 - x) + (y0 - y) * (y0 - y); var dist1 = (x1 - x) * (x1 - x) + (y1 - y) * (y1 - y); dataIndex = dist0 < dist1 ? i - 1 : i; } } if (dataIndex >= 0) { var i3 = dataIndex * 3; var point = new Vector3(this._points[i3], this._points[i3 + 1], this._points[i3 + 2]); out.push({ dataIndex, point, pointWorld: point.clone(), target: this._line3DMesh, distance: this._camera.getWorldPosition().dist(point) }); } }, remove: function() { this.groupGL.removeAll(); }, dispose: function() { this.groupGL.removeAll(); } }); export { Line3DView as default };