252 lines
		
	
	
		
			7.3 KiB
		
	
	
	
		
			JavaScript
		
	
	
			
		
		
	
	
			252 lines
		
	
	
		
			7.3 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.
 | 
						|
 */
 | 
						|
import * as echarts from 'echarts/lib/echarts';
 | 
						|
import LayerGL from './core/LayerGL';
 | 
						|
import backwardCompat from './preprocessor/backwardCompat';
 | 
						|
 | 
						|
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) {
 | 
						|
    // Disable auto sleep in gl layer.
 | 
						|
    zr.setSleepAfterStill(0);
 | 
						|
    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;
 | 
						|
        }
 | 
						|
 | 
						|
        var 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
 | 
						|
 | 
						|
 | 
						|
echarts.registerPostInit(function (chart) {
 | 
						|
  var zr = chart.getZr();
 | 
						|
  var oldDispose = zr.painter.dispose;
 | 
						|
 | 
						|
  zr.painter.dispose = function () {
 | 
						|
    if (typeof this.eachOtherLayer === 'function') {
 | 
						|
      this.eachOtherLayer(function (layer) {
 | 
						|
        if (layer instanceof LayerGL) {
 | 
						|
          layer.dispose();
 | 
						|
        }
 | 
						|
      });
 | 
						|
    }
 | 
						|
 | 
						|
    oldDispose.call(this);
 | 
						|
  };
 | 
						|
 | 
						|
  zr.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, null, scope);
 | 
						|
    }
 | 
						|
 | 
						|
    findAndDrawOtherLayer(zlevel, Infinity);
 | 
						|
    return canvas;
 | 
						|
  };
 | 
						|
});
 | 
						|
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);
 | 
						|
export default EChartsGL; |