144 lines
5.8 KiB
JavaScript
144 lines
5.8 KiB
JavaScript
|
|
import * as echarts from 'echarts/lib/echarts';
|
||
|
|
import Vector3 from 'claygl/src/math/Vector3';
|
||
|
|
import glmatrix from 'claygl/src/dep/glmatrix';
|
||
|
|
import cartesian3DLayout from './cartesian3DLayout';
|
||
|
|
import evaluateBarSparseness from './evaluateBarSparseness';
|
||
|
|
var vec3 = glmatrix.vec3;
|
||
|
|
var isDimensionStacked = echarts.helper.dataStack.isDimensionStacked;
|
||
|
|
|
||
|
|
function globeLayout(seriesModel, coordSys) {
|
||
|
|
var data = seriesModel.getData();
|
||
|
|
var barMinHeight = seriesModel.get('minHeight') || 0;
|
||
|
|
var barSize = seriesModel.get('barSize');
|
||
|
|
var dims = ['lng', 'lat', 'alt'].map(function (coordDimName) {
|
||
|
|
return seriesModel.coordDimToDataDim(coordDimName)[0];
|
||
|
|
});
|
||
|
|
|
||
|
|
if (barSize == null) {
|
||
|
|
var perimeter = coordSys.radius * Math.PI;
|
||
|
|
var fillRatio = evaluateBarSparseness(data, dims[0], dims[1]);
|
||
|
|
barSize = [perimeter / Math.sqrt(data.count() / fillRatio), perimeter / Math.sqrt(data.count() / fillRatio)];
|
||
|
|
} else if (!echarts.util.isArray(barSize)) {
|
||
|
|
barSize = [barSize, barSize];
|
||
|
|
}
|
||
|
|
|
||
|
|
var valueDim = getValueDimension(data, dims);
|
||
|
|
data.each(dims, function (lng, lat, val, idx) {
|
||
|
|
var stackedValue = data.get(valueDim.dimension, idx);
|
||
|
|
var baseValue = valueDim.isStacked ? stackedValue - val : coordSys.altitudeAxis.scale.getExtent()[0]; // TODO Stacked with minHeight.
|
||
|
|
|
||
|
|
var height = Math.max(coordSys.altitudeAxis.dataToCoord(val), barMinHeight);
|
||
|
|
var start = coordSys.dataToPoint([lng, lat, baseValue]);
|
||
|
|
var end = coordSys.dataToPoint([lng, lat, stackedValue]);
|
||
|
|
var dir = vec3.sub([], end, start);
|
||
|
|
vec3.normalize(dir, dir);
|
||
|
|
var size = [barSize[0], height, barSize[1]];
|
||
|
|
data.setItemLayout(idx, [start, dir, size]);
|
||
|
|
});
|
||
|
|
data.setLayout('orient', Vector3.UP.array);
|
||
|
|
}
|
||
|
|
|
||
|
|
function geo3DLayout(seriesModel, coordSys) {
|
||
|
|
var data = seriesModel.getData();
|
||
|
|
var barSize = seriesModel.get('barSize');
|
||
|
|
var barMinHeight = seriesModel.get('minHeight') || 0;
|
||
|
|
var dims = ['lng', 'lat', 'alt'].map(function (coordDimName) {
|
||
|
|
return seriesModel.coordDimToDataDim(coordDimName)[0];
|
||
|
|
});
|
||
|
|
|
||
|
|
if (barSize == null) {
|
||
|
|
var size = Math.min(coordSys.size[0], coordSys.size[2]);
|
||
|
|
var fillRatio = evaluateBarSparseness(data, dims[0], dims[1]);
|
||
|
|
barSize = [size / Math.sqrt(data.count() / fillRatio), size / Math.sqrt(data.count() / fillRatio)];
|
||
|
|
} else if (!echarts.util.isArray(barSize)) {
|
||
|
|
barSize = [barSize, barSize];
|
||
|
|
}
|
||
|
|
|
||
|
|
var dir = [0, 1, 0];
|
||
|
|
var valueDim = getValueDimension(data, dims);
|
||
|
|
data.each(dims, function (lng, lat, val, idx) {
|
||
|
|
var stackedValue = data.get(valueDim.dimension, idx);
|
||
|
|
var baseValue = valueDim.isStacked ? stackedValue - val : coordSys.altitudeAxis.scale.getExtent()[0];
|
||
|
|
var height = Math.max(coordSys.altitudeAxis.dataToCoord(val), barMinHeight);
|
||
|
|
var start = coordSys.dataToPoint([lng, lat, baseValue]);
|
||
|
|
var size = [barSize[0], height, barSize[1]];
|
||
|
|
data.setItemLayout(idx, [start, dir, size]);
|
||
|
|
});
|
||
|
|
data.setLayout('orient', [1, 0, 0]);
|
||
|
|
}
|
||
|
|
|
||
|
|
function mapService3DLayout(seriesModel, coordSys) {
|
||
|
|
var data = seriesModel.getData();
|
||
|
|
var dimLng = seriesModel.coordDimToDataDim('lng')[0];
|
||
|
|
var dimLat = seriesModel.coordDimToDataDim('lat')[0];
|
||
|
|
var dimAlt = seriesModel.coordDimToDataDim('alt')[0];
|
||
|
|
var barSize = seriesModel.get('barSize');
|
||
|
|
var barMinHeight = seriesModel.get('minHeight') || 0;
|
||
|
|
|
||
|
|
if (barSize == null) {
|
||
|
|
var xExtent = data.getDataExtent(dimLng);
|
||
|
|
var yExtent = data.getDataExtent(dimLat);
|
||
|
|
var corner0 = coordSys.dataToPoint([xExtent[0], yExtent[0]]);
|
||
|
|
var corner1 = coordSys.dataToPoint([xExtent[1], yExtent[1]]);
|
||
|
|
var size = Math.min(Math.abs(corner0[0] - corner1[0]), Math.abs(corner0[1] - corner1[1])) || 1;
|
||
|
|
var fillRatio = evaluateBarSparseness(data, dimLng, dimLat); // PENDING, data density
|
||
|
|
|
||
|
|
barSize = [size / Math.sqrt(data.count() / fillRatio), size / Math.sqrt(data.count() / fillRatio)];
|
||
|
|
} else {
|
||
|
|
if (!echarts.util.isArray(barSize)) {
|
||
|
|
barSize = [barSize, barSize];
|
||
|
|
}
|
||
|
|
|
||
|
|
barSize[0] /= coordSys.getScale() / 16;
|
||
|
|
barSize[1] /= coordSys.getScale() / 16;
|
||
|
|
}
|
||
|
|
|
||
|
|
var dir = [0, 0, 1];
|
||
|
|
var dims = [dimLng, dimLat, dimAlt];
|
||
|
|
var valueDim = getValueDimension(data, dims);
|
||
|
|
data.each(dims, function (lng, lat, val, idx) {
|
||
|
|
var stackedValue = data.get(valueDim.dimension, idx);
|
||
|
|
var baseValue = valueDim.isStacked ? stackedValue - val : 0;
|
||
|
|
var start = coordSys.dataToPoint([lng, lat, baseValue]);
|
||
|
|
var end = coordSys.dataToPoint([lng, lat, stackedValue]);
|
||
|
|
var height = Math.max(end[2] - start[2], barMinHeight);
|
||
|
|
var size = [barSize[0], height, barSize[1]];
|
||
|
|
data.setItemLayout(idx, [start, dir, size]);
|
||
|
|
});
|
||
|
|
data.setLayout('orient', [1, 0, 0]);
|
||
|
|
}
|
||
|
|
|
||
|
|
function getValueDimension(data, dataDims) {
|
||
|
|
var isStacked = isDimensionStacked(data, dataDims[2]);
|
||
|
|
return {
|
||
|
|
dimension: isStacked ? data.getCalculationInfo('stackResultDimension') : dataDims[2],
|
||
|
|
isStacked: isStacked
|
||
|
|
};
|
||
|
|
}
|
||
|
|
|
||
|
|
export default function registerBarLayout(registers) {
|
||
|
|
registers.registerLayout(function (ecModel, api) {
|
||
|
|
ecModel.eachSeriesByType('bar3D', function (seriesModel) {
|
||
|
|
var coordSys = seriesModel.coordinateSystem;
|
||
|
|
var coordSysType = coordSys && coordSys.type;
|
||
|
|
|
||
|
|
if (coordSysType === 'globe') {
|
||
|
|
globeLayout(seriesModel, coordSys);
|
||
|
|
} else if (coordSysType === 'cartesian3D') {
|
||
|
|
cartesian3DLayout(seriesModel, coordSys);
|
||
|
|
} else if (coordSysType === 'geo3D') {
|
||
|
|
geo3DLayout(seriesModel, coordSys);
|
||
|
|
} else if (coordSysType === 'mapbox3D' || coordSysType === 'maptalks3D') {
|
||
|
|
mapService3DLayout(seriesModel, coordSys);
|
||
|
|
} else {
|
||
|
|
if (process.env.NODE_ENV !== 'production') {
|
||
|
|
if (!coordSys) {
|
||
|
|
throw new Error('bar3D doesn\'t have coordinate system.');
|
||
|
|
} else {
|
||
|
|
throw new Error('bar3D doesn\'t support coordinate system ' + coordSys.type);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
});
|
||
|
|
});
|
||
|
|
}
|