GlobeModel.js 5.6 KB
import * as echarts from 'echarts/lib/echarts';
import componentViewControlMixin from '../common/componentViewControlMixin';
import componentPostEffectMixin from '../common/componentPostEffectMixin';
import componentLightMixin from '../common/componentLightMixin';
import componentShadingMixin from '../common/componentShadingMixin';


function defaultId(option, idx) {
    option.id = option.id || option.name || (idx + '');
}
var GlobeModel = echarts.ComponentModel.extend({

    type: 'globe',

    layoutMode: 'box',

    coordinateSystem: null,

    init: function () {
        GlobeModel.superApply(this, 'init', arguments);

        echarts.util.each(this.option.layers, function (layerOption, idx) {
            echarts.util.merge(layerOption, this.defaultLayerOption);
            defaultId(layerOption, idx);
        }, this);
    },

    mergeOption: function (option) {
        // TODO test
        var oldLayers = this.option.layers;
        this.option.layers = null;
        GlobeModel.superApply(this, 'mergeOption', arguments);

        function createLayerMap(layers) {
            return echarts.util.reduce(layers, function (obj, layerOption, idx) {
                defaultId(layerOption, idx);
                obj[layerOption.id] = layerOption;
                return obj;
            }, {});
        }
        if (oldLayers && oldLayers.length) {
            var newLayerMap = createLayerMap(option.layers);
            var oldLayerMap = createLayerMap(oldLayers);
            for (var id in newLayerMap) {
                if (oldLayerMap[id]) {
                    echarts.util.merge(oldLayerMap[id], newLayerMap[id], true);
                }
                else {
                    oldLayers.push(option.layers[id]);
                }
            }
            // Copy back
            this.option.layers = oldLayers;
        }
        // else overwrite

        // Set default
        echarts.util.each(this.option.layers, function (layerOption) {
            echarts.util.merge(layerOption, this.defaultLayerOption);
        }, this);
    },

    optionUpdated: function () {
        this.updateDisplacementHash();
    },

    defaultLayerOption: {
        show: true,
        type: 'overlay'
    },

    defaultOption: {

        show: true,

        zlevel: -10,

        // Layout used for viewport
        left: 0,
        top: 0,
        width: '100%',
        height: '100%',

        environment: 'auto',

        baseColor: '#fff',

        // Base albedo texture
        baseTexture: '',

        // Height texture for bump mapping and vertex displacement
        heightTexture: '',

        // Texture for vertex displacement, default use heightTexture
        displacementTexture: '',
        // Scale of vertex displacement, available only if displacementTexture is set.
        displacementScale: 0,

        // Detail of displacement. 'low', 'medium', 'high', 'ultra'
        displacementQuality: 'medium',

        // Globe radius
        globeRadius: 100,

        // Globe outer radius. Which is max of altitude.
        globeOuterRadius: 150,

        // Shading of globe
        shading: 'lambert',

        // Extend light
        light: {
            // Main sun light
            main: {
                // Time, default it will use system time
                time: ''
            }
        },

        // atmosphere
        atmosphere: {
            show: false,
            offset: 5,
            color: '#ffffff',
            glowPower: 6.0,
            innerGlowPower: 2.0
        },

        // light
        // postEffect
        // temporalSuperSampling

        viewControl: {
            autoRotate: true,

            panSensitivity: 0,

            targetCoord: null
        },


        // {
        //     show: true,
        //     name: 'cloud',
        //     type: 'overlay',
        //     shading: 'lambert',
        //     distance: 10,
        //     texture: ''
        // }
        // {
        //     type: 'blend',
        //     blendTo: 'albedo'
        //     blendType: 'source-over'
        // }

        layers: []
    },

    setDisplacementData: function (data, width, height) {
        this.displacementData = data;
        this.displacementWidth = width;
        this.displacementHeight = height;
    },

    getDisplacementTexture: function () {
        return this.get('displacementTexture') || this.get('heightTexture');
    },

    getDisplacemenScale: function () {
        var displacementTexture = this.getDisplacementTexture();
        var displacementScale = this.get('displacementScale');
        if (!displacementTexture || displacementTexture === 'none') {
            displacementScale = 0;
        }
        return displacementScale;
    },

    hasDisplacement: function () {
        return this.getDisplacemenScale() > 0;
    },

    _displacementChanged: true,

    _displacementScale: 0,

    updateDisplacementHash: function () {
        var displacementTexture = this.getDisplacementTexture();
        var displacementScale = this.getDisplacemenScale();

        this._displacementChanged =
            this._displacementTexture !== displacementTexture
            || this._displacementScale !== displacementScale;

        this._displacementTexture = displacementTexture;
        this._displacementScale = displacementScale;
    },

    isDisplacementChanged: function () {
        return this._displacementChanged;
    }
});

echarts.util.merge(GlobeModel.prototype, componentViewControlMixin);
echarts.util.merge(GlobeModel.prototype, componentPostEffectMixin);
echarts.util.merge(GlobeModel.prototype, componentLightMixin);
echarts.util.merge(GlobeModel.prototype, componentShadingMixin);

export default GlobeModel;