hefeihvac_java/node_modules/echarts-gl/lib/chart/bar3D/Bar3DView.js

299 lines
9.0 KiB
JavaScript

import * as echarts from 'echarts/lib/echarts';
import graphicGL from '../../util/graphicGL';
import retrieve from '../../util/retrieve';
import format from '../../util/format';
import BarsGeometry from '../../util/geometry/Bars3DGeometry';
import LabelsBuilder from '../../component/common/LabelsBuilder';
import glmatrix from 'claygl/src/dep/glmatrix';
import { getItemVisualColor, getItemVisualOpacity } from '../../util/visual';
var vec3 = glmatrix.vec3;
export default echarts.ChartView.extend({
type: 'bar3D',
__ecgl__: true,
init: function (ecModel, api) {
this.groupGL = new graphicGL.Node();
this._api = api;
this._labelsBuilder = new LabelsBuilder(256, 256, api);
var self = this;
this._labelsBuilder.getLabelPosition = function (dataIndex, position, distance) {
if (self._data) {
var layout = self._data.getItemLayout(dataIndex);
var start = layout[0];
var dir = layout[1];
var height = layout[2][1];
return vec3.scaleAndAdd([], start, dir, distance + height);
} else {
return [0, 0];
}
}; // Give a large render order.
this._labelsBuilder.getMesh().renderOrder = 100;
},
render: function (seriesModel, ecModel, api) {
// Swap barMesh
var tmp = this._prevBarMesh;
this._prevBarMesh = this._barMesh;
this._barMesh = tmp;
if (!this._barMesh) {
this._barMesh = new graphicGL.Mesh({
geometry: new BarsGeometry(),
shadowDepthMaterial: new graphicGL.Material({
shader: new graphicGL.Shader(graphicGL.Shader.source('ecgl.sm.depth.vertex'), graphicGL.Shader.source('ecgl.sm.depth.fragment'))
}),
// Only cartesian3D enable culling
// FIXME Performance
culling: seriesModel.coordinateSystem.type === 'cartesian3D',
// Render after axes
renderOrder: 10,
// Render normal in normal pass
renderNormal: true
});
}
this.groupGL.remove(this._prevBarMesh);
this.groupGL.add(this._barMesh);
this.groupGL.add(this._labelsBuilder.getMesh());
var coordSys = seriesModel.coordinateSystem;
this._doRender(seriesModel, api);
if (coordSys && coordSys.viewGL) {
coordSys.viewGL.add(this.groupGL);
var methodName = coordSys.viewGL.isLinearSpace() ? 'define' : 'undefine';
this._barMesh.material[methodName]('fragment', 'SRGB_DECODE');
}
this._data = seriesModel.getData();
this._labelsBuilder.updateData(this._data);
this._labelsBuilder.updateLabels();
this._updateAnimation(seriesModel);
},
_updateAnimation: function (seriesModel) {
graphicGL.updateVertexAnimation([['prevPosition', 'position'], ['prevNormal', 'normal']], this._prevBarMesh, this._barMesh, seriesModel);
},
_doRender: function (seriesModel, api) {
var data = seriesModel.getData();
var shading = seriesModel.get('shading');
var enableNormal = shading !== 'color';
var self = this;
var barMesh = this._barMesh;
var shadingPrefix = 'ecgl.' + shading;
if (!barMesh.material || barMesh.material.shader.name !== shadingPrefix) {
barMesh.material = graphicGL.createMaterial(shadingPrefix, ['VERTEX_COLOR']);
}
graphicGL.setMaterialFromModel(shading, barMesh.material, seriesModel, api);
barMesh.geometry.enableNormal = enableNormal;
barMesh.geometry.resetOffset(); // Bevel settings
var bevelSize = seriesModel.get('bevelSize');
var bevelSegments = seriesModel.get('bevelSmoothness');
barMesh.geometry.bevelSegments = bevelSegments;
barMesh.geometry.bevelSize = bevelSize;
var colorArr = [];
var vertexColors = new Float32Array(data.count() * 4);
var colorOffset = 0;
var barCount = 0;
var hasTransparent = false;
data.each(function (idx) {
if (!data.hasValue(idx)) {
return;
}
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) {
barCount++;
if (colorArr[3] < 0.99) {
hasTransparent = true;
}
}
});
barMesh.geometry.setBarCount(barCount);
var orient = data.getLayout('orient'); // Map of dataIndex and barIndex.
var barIndexOfData = this._barIndexOfData = new Int32Array(data.count());
var barCount = 0;
data.each(function (idx) {
if (!data.hasValue(idx)) {
barIndexOfData[idx] = -1;
return;
}
var layout = data.getItemLayout(idx);
var start = layout[0];
var dir = layout[1];
var size = layout[2];
var idx4 = idx * 4;
colorArr[0] = vertexColors[idx4++];
colorArr[1] = vertexColors[idx4++];
colorArr[2] = vertexColors[idx4++];
colorArr[3] = vertexColors[idx4++];
if (colorArr[3] > 0) {
self._barMesh.geometry.addBar(start, dir, orient, size, colorArr, idx);
barIndexOfData[idx] = barCount++;
}
});
barMesh.geometry.dirty();
barMesh.geometry.updateBoundingBox();
var material = barMesh.material;
material.transparent = hasTransparent;
material.depthMask = !hasTransparent;
barMesh.geometry.sortTriangles = hasTransparent;
this._initHandler(seriesModel, api);
},
_initHandler: function (seriesModel, api) {
var data = seriesModel.getData();
var barMesh = this._barMesh;
var isCartesian3D = seriesModel.coordinateSystem.type === 'cartesian3D';
barMesh.seriesIndex = seriesModel.seriesIndex;
var lastDataIndex = -1;
barMesh.off('mousemove');
barMesh.off('mouseout');
barMesh.on('mousemove', function (e) {
var dataIndex = barMesh.geometry.getDataIndexOfVertex(e.triangle[0]);
if (dataIndex !== lastDataIndex) {
this._downplay(lastDataIndex);
this._highlight(dataIndex);
this._labelsBuilder.updateLabels([dataIndex]);
if (isCartesian3D) {
api.dispatchAction({
type: 'grid3DShowAxisPointer',
value: [data.get('x', dataIndex), data.get('y', dataIndex), data.get('z', dataIndex, true)]
});
}
}
lastDataIndex = dataIndex;
barMesh.dataIndex = dataIndex;
}, this);
barMesh.on('mouseout', function (e) {
this._downplay(lastDataIndex);
this._labelsBuilder.updateLabels();
lastDataIndex = -1;
barMesh.dataIndex = -1;
if (isCartesian3D) {
api.dispatchAction({
type: 'grid3DHideAxisPointer'
});
}
}, this);
},
_highlight: function (dataIndex) {
var data = this._data;
if (!data) {
return;
}
var barIndex = this._barIndexOfData[dataIndex];
if (barIndex < 0) {
return;
}
var itemModel = data.getItemModel(dataIndex);
var emphasisItemStyleModel = itemModel.getModel('emphasis.itemStyle');
var emphasisColor = emphasisItemStyleModel.get('color');
var emphasisOpacity = emphasisItemStyleModel.get('opacity');
if (emphasisColor == null) {
var color = getItemVisualColor(data, dataIndex);
emphasisColor = echarts.color.lift(color, -0.4);
}
if (emphasisOpacity == null) {
emphasisOpacity = getItemVisualOpacity(data, dataIndex);
}
var colorArr = graphicGL.parseColor(emphasisColor);
colorArr[3] *= emphasisOpacity;
this._barMesh.geometry.setColor(barIndex, colorArr);
this._api.getZr().refresh();
},
_downplay: function (dataIndex) {
var data = this._data;
if (!data) {
return;
}
var barIndex = this._barIndexOfData[dataIndex];
if (barIndex < 0) {
return;
}
var color = getItemVisualColor(data, dataIndex);
var opacity = getItemVisualOpacity(data, dataIndex);
var colorArr = graphicGL.parseColor(color);
colorArr[3] *= opacity;
this._barMesh.geometry.setColor(barIndex, colorArr);
this._api.getZr().refresh();
},
highlight: function (seriesModel, ecModel, api, payload) {
this._toggleStatus('highlight', seriesModel, ecModel, api, payload);
},
downplay: function (seriesModel, ecModel, api, payload) {
this._toggleStatus('downplay', seriesModel, ecModel, api, payload);
},
_toggleStatus: function (status, seriesModel, ecModel, api, payload) {
var data = seriesModel.getData();
var dataIndex = retrieve.queryDataIndex(data, payload);
var self = this;
if (dataIndex != null) {
echarts.util.each(format.normalizeToArray(dataIndex), function (dataIdx) {
status === 'highlight' ? this._highlight(dataIdx) : this._downplay(dataIdx);
}, this);
} else {
data.each(function (dataIdx) {
status === 'highlight' ? self._highlight(dataIdx) : self._downplay(dataIdx);
});
}
},
remove: function () {
this.groupGL.removeAll();
},
dispose: function () {
this._labelsBuilder.dispose();
this.groupGL.removeAll();
}
});