mirror of
https://gitee.com/smartchart/smartchart
synced 2025-05-05 00:59:25 +08:00
279 lines
8.9 KiB
JavaScript
279 lines
8.9 KiB
JavaScript
/**
|
|
* echarts-gl
|
|
* Extension pack of ECharts providing 3d plots and globe visualization
|
|
*
|
|
* Copyright (c) 2014, echarts-gl
|
|
* All rights reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions are met:
|
|
*
|
|
* * Redistributions of source code must retain the above copyright notice, this
|
|
* list of conditions and the following disclaimer.
|
|
*
|
|
* * Redistributions in binary form must reproduce the above copyright notice,
|
|
* this list of conditions and the following disclaimer in the documentation
|
|
* and/or other materials provided with the distribution.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
*/
|
|
|
|
/**
|
|
* @module echarts-gl
|
|
* @author Yi Shen(http://github.com/pissang)
|
|
*/
|
|
|
|
// PENDING Use a single canvas as layer or use image element?
|
|
var echartsGl = {
|
|
version: '1.1.1',
|
|
dependencies: {
|
|
echarts: '4.1.0',
|
|
claygl: '1.2.1'
|
|
}
|
|
};
|
|
import echarts from 'echarts/lib/echarts';
|
|
import clayVersion from 'claygl/src/version';
|
|
import LayerGL from './core/LayerGL';
|
|
import backwardCompat from './preprocessor/backwardCompat';
|
|
import graphicGL from './util/graphicGL';
|
|
|
|
// Version checking
|
|
var deps = echartsGl.dependencies;
|
|
function versionTooOldMsg(name) {
|
|
throw new Error(
|
|
name + ' version is too old, needs ' + deps[name] + ' or higher'
|
|
);
|
|
}
|
|
function checkVersion(version, name) {
|
|
if ((version.replace('.', '') - 0) < (deps[name].replace('.', '') - 0)) {
|
|
versionTooOldMsg(name);
|
|
}
|
|
// console.log('Loaded ' + name + ', version ' + version);
|
|
}
|
|
checkVersion(clayVersion, 'claygl');
|
|
checkVersion(echarts.version, 'echarts');
|
|
|
|
function EChartsGL (zr) {
|
|
this._layers = {};
|
|
|
|
this._zr = zr;
|
|
}
|
|
|
|
EChartsGL.prototype.update = function (ecModel, api) {
|
|
var self = this;
|
|
var zr = api.getZr();
|
|
|
|
if (!zr.getWidth() || !zr.getHeight()) {
|
|
console.warn('Dom has no width or height');
|
|
return;
|
|
}
|
|
|
|
function getLayerGL(model) {
|
|
var zlevel;
|
|
// Host on coordinate system.
|
|
if (model.coordinateSystem && model.coordinateSystem.model) {
|
|
zlevel = model.get('zlevel');
|
|
}
|
|
else {
|
|
zlevel = model.get('zlevel');
|
|
}
|
|
|
|
var layers = self._layers;
|
|
var layerGL = layers[zlevel];
|
|
if (!layerGL) {
|
|
layerGL = layers[zlevel] = new LayerGL('gl-' + zlevel, zr);
|
|
|
|
if (zr.painter.isSingleCanvas()) {
|
|
layerGL.virtual = true;
|
|
// If container is canvas, use image to represent LayerGL
|
|
// FIXME Performance
|
|
var img = new echarts.graphic.Image({
|
|
z: 1e4,
|
|
style: {
|
|
image: layerGL.renderer.canvas
|
|
},
|
|
silent: true
|
|
});
|
|
layerGL.__hostImage = img;
|
|
|
|
zr.add(img);
|
|
}
|
|
|
|
zr.painter.insertLayer(zlevel, layerGL);
|
|
}
|
|
if (layerGL.__hostImage) {
|
|
layerGL.__hostImage.setStyle({
|
|
width: layerGL.renderer.getWidth(),
|
|
height: layerGL.renderer.getHeight()
|
|
});
|
|
}
|
|
|
|
return layerGL;
|
|
}
|
|
|
|
function setSilent(groupGL, silent) {
|
|
if (groupGL) {
|
|
groupGL.traverse(function (mesh) {
|
|
if (mesh.isRenderable && mesh.isRenderable()) {
|
|
mesh.ignorePicking = mesh.$ignorePicking != null
|
|
? mesh.$ignorePicking : silent;
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
for (var zlevel in this._layers) {
|
|
this._layers[zlevel].removeViewsAll();
|
|
}
|
|
|
|
ecModel.eachComponent(function (componentType, componentModel) {
|
|
if (componentType !== 'series') {
|
|
var view = api.getViewOfComponentModel(componentModel);
|
|
var coordSys = componentModel.coordinateSystem;
|
|
// View with __ecgl__ flag is a echarts-gl component.
|
|
if (view.__ecgl__) {
|
|
var viewGL;
|
|
if (coordSys) {
|
|
if (!coordSys.viewGL) {
|
|
console.error('Can\'t find viewGL in coordinateSystem of component ' + componentModel.id);
|
|
return;
|
|
}
|
|
viewGL = coordSys.viewGL;
|
|
}
|
|
else {
|
|
if (!componentModel.viewGL) {
|
|
console.error('Can\'t find viewGL of component ' + componentModel.id);
|
|
return;
|
|
}
|
|
viewGL = coordSys.viewGL;
|
|
}
|
|
|
|
viewGL = coordSys.viewGL;
|
|
var layerGL = getLayerGL(componentModel);
|
|
|
|
layerGL.addView(viewGL);
|
|
|
|
view.afterRender && view.afterRender(
|
|
componentModel, ecModel, api, layerGL
|
|
);
|
|
|
|
setSilent(view.groupGL, componentModel.get('silent'));
|
|
}
|
|
}
|
|
});
|
|
|
|
ecModel.eachSeries(function (seriesModel) {
|
|
var chartView = api.getViewOfSeriesModel(seriesModel);
|
|
var coordSys = seriesModel.coordinateSystem;
|
|
if (chartView.__ecgl__) {
|
|
if ((coordSys && !coordSys.viewGL) && !chartView.viewGL) {
|
|
console.error('Can\'t find viewGL of series ' + chartView.id);
|
|
return;
|
|
}
|
|
var viewGL = (coordSys && coordSys.viewGL) || chartView.viewGL;
|
|
// TODO Check zlevel not same with component of coordinate system ?
|
|
var layerGL = getLayerGL(seriesModel);
|
|
layerGL.addView(viewGL);
|
|
|
|
chartView.afterRender && chartView.afterRender(
|
|
seriesModel, ecModel, api, layerGL
|
|
);
|
|
|
|
setSilent(chartView.groupGL, seriesModel.get('silent'));
|
|
}
|
|
});
|
|
};
|
|
|
|
// Hack original getRenderedCanvas. Will removed after new echarts released
|
|
// TODO
|
|
var oldInit = echarts.init;
|
|
echarts.init = function () {
|
|
var chart = oldInit.apply(this, arguments);
|
|
chart.getZr().painter.getRenderedCanvas = function (opts) {
|
|
opts = opts || {};
|
|
if (this._singleCanvas) {
|
|
return this._layers[0].dom;
|
|
}
|
|
|
|
var canvas = document.createElement('canvas');
|
|
var dpr = opts.pixelRatio || this.dpr;
|
|
canvas.width = this.getWidth() * dpr;
|
|
canvas.height = this.getHeight() * dpr;
|
|
var ctx = canvas.getContext('2d');
|
|
ctx.dpr = dpr;
|
|
|
|
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
|
if (opts.backgroundColor) {
|
|
ctx.fillStyle = opts.backgroundColor;
|
|
ctx.fillRect(0, 0, canvas.width, canvas.height);
|
|
}
|
|
|
|
var displayList = this.storage.getDisplayList(true);
|
|
|
|
var scope = {};
|
|
var zlevel;
|
|
|
|
var self = this;
|
|
function findAndDrawOtherLayer(smaller, larger) {
|
|
var zlevelList = self._zlevelList;
|
|
if (smaller == null) {
|
|
smaller = -Infinity;
|
|
}
|
|
var intermediateLayer;
|
|
for (var i = 0; i < zlevelList.length; i++) {
|
|
var z = zlevelList[i];
|
|
var layer = self._layers[z];
|
|
if (!layer.__builtin__ && z > smaller && z < larger) {
|
|
intermediateLayer = layer;
|
|
break;
|
|
}
|
|
}
|
|
if (intermediateLayer && intermediateLayer.renderToCanvas) {
|
|
ctx.save();
|
|
intermediateLayer.renderToCanvas(ctx);
|
|
ctx.restore();
|
|
}
|
|
}
|
|
var layer = {
|
|
ctx: ctx
|
|
};
|
|
for (var i = 0; i < displayList.length; i++) {
|
|
var el = displayList[i];
|
|
|
|
if (el.zlevel !== zlevel) {
|
|
findAndDrawOtherLayer(zlevel, el.zlevel);
|
|
zlevel = el.zlevel;
|
|
}
|
|
this._doPaintEl(el, layer, true, scope);
|
|
}
|
|
|
|
findAndDrawOtherLayer(zlevel, Infinity);
|
|
|
|
return canvas;
|
|
};
|
|
return chart;
|
|
};
|
|
|
|
|
|
echarts.registerPostUpdate(function (ecModel, api) {
|
|
var zr = api.getZr();
|
|
|
|
var egl = zr.__egl = zr.__egl || new EChartsGL(zr);
|
|
|
|
egl.update(ecModel, api);
|
|
});
|
|
|
|
echarts.registerPreprocessor(backwardCompat);
|
|
|
|
echarts.graphicGL = graphicGL;
|
|
|
|
export default EChartsGL; |