cione-comp-lib
Version:
`$ yarn add cione-comp-lib` 或者 `$ npm i cione-comp-lib -S`
248 lines (247 loc) • 9.13 kB
JavaScript
import "../../../../echarts/lib/echarts.mjs";
import graphicGL from "../../util/graphicGL.mjs";
import retrieve from "../../util/retrieve.mjs";
import formatUtil from "../../util/format.mjs";
import BarsGeometry from "../../util/geometry/Bars3DGeometry.mjs";
import LabelsBuilder from "../../component/common/LabelsBuilder.mjs";
import glmatrix from "../../../../claygl/src/glmatrix/index.mjs";
import { getItemVisualColor, getItemVisualOpacity } from "../../util/visual.mjs";
import ChartView from "../../../../echarts/lib/view/Chart.mjs";
import { lift } from "../../../../zrender/lib/tool/color.mjs";
import { each } from "../../../../zrender/lib/core/util.mjs";
var vec3 = glmatrix.vec3;
var Bar3DView = 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];
}
};
this._labelsBuilder.getMesh().renderOrder = 100;
},
render: function(seriesModel, ecModel, api) {
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"))
}),
culling: seriesModel.coordinateSystem.type === "cartesian3D",
renderOrder: 10,
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();
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");
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 = 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) {
each(formatUtil.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();
}
});
export { Bar3DView as default };