186 lines
5.5 KiB
JavaScript
186 lines
5.5 KiB
JavaScript
import * as echarts from 'echarts/lib/echarts';
|
|
import componentShadingMixin from '../../component/common/componentShadingMixin';
|
|
import formatTooltip from '../common/formatTooltip';
|
|
import createList from '../common/createList';
|
|
var SurfaceSeries = echarts.SeriesModel.extend({
|
|
type: 'series.surface',
|
|
dependencies: ['globe', 'grid3D', 'geo3D'],
|
|
visualStyleAccessPath: 'itemStyle',
|
|
formatTooltip: function (dataIndex) {
|
|
return formatTooltip(this, dataIndex);
|
|
},
|
|
getInitialData: function (option, ecModel) {
|
|
var data = option.data;
|
|
|
|
function validateDimension(dimOpts) {
|
|
return !(isNaN(dimOpts.min) || isNaN(dimOpts.max) || isNaN(dimOpts.step));
|
|
}
|
|
|
|
function getPrecision(dimOpts) {
|
|
var getPrecision = echarts.number.getPrecisionSafe;
|
|
return Math.max(getPrecision(dimOpts.min), getPrecision(dimOpts.max), getPrecision(dimOpts.step)) + 1;
|
|
}
|
|
|
|
if (!data) {
|
|
if (!option.parametric) {
|
|
// From surface equation
|
|
var equation = option.equation || {};
|
|
var xOpts = equation.x || {};
|
|
var yOpts = equation.y || {};
|
|
['x', 'y'].forEach(function (dim) {
|
|
if (!validateDimension(equation[dim])) {
|
|
if (process.env.NODE_ENV !== 'production') {
|
|
console.error('Invalid equation.%s', dim);
|
|
}
|
|
|
|
return;
|
|
}
|
|
});
|
|
|
|
if (typeof equation.z !== 'function') {
|
|
if (process.env.NODE_ENV !== 'production') {
|
|
console.error('equation.z needs to be function');
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
var xCount = Math.floor((xOpts.max + xOpts.step - xOpts.min) / xOpts.step);
|
|
var yCount = Math.floor((yOpts.max + yOpts.step - yOpts.min) / yOpts.step);
|
|
data = new Float32Array(xCount * yCount * 3);
|
|
var xPrecision = getPrecision(xOpts);
|
|
var yPrecision = getPrecision(yOpts);
|
|
var off = 0;
|
|
|
|
for (var j = 0; j < yCount; j++) {
|
|
for (var i = 0; i < xCount; i++) {
|
|
var x = i * xOpts.step + xOpts.min;
|
|
var y = j * yOpts.step + yOpts.min;
|
|
var x2 = echarts.number.round(Math.min(x, xOpts.max), xPrecision);
|
|
var y2 = echarts.number.round(Math.min(y, yOpts.max), yPrecision);
|
|
var z = equation.z(x2, y2);
|
|
data[off++] = x2;
|
|
data[off++] = y2;
|
|
data[off++] = z;
|
|
}
|
|
}
|
|
} else {
|
|
var parametricEquation = option.parametricEquation || {};
|
|
var uOpts = parametricEquation.u || {};
|
|
var vOpts = parametricEquation.v || {};
|
|
['u', 'v'].forEach(function (dim) {
|
|
if (!validateDimension(parametricEquation[dim])) {
|
|
if (process.env.NODE_ENV !== 'production') {
|
|
console.error('Invalid parametricEquation.%s', dim);
|
|
}
|
|
|
|
return;
|
|
}
|
|
});
|
|
['x', 'y', 'z'].forEach(function (dim) {
|
|
if (typeof parametricEquation[dim] !== 'function') {
|
|
if (process.env.NODE_ENV !== 'production') {
|
|
console.error('parametricEquation.%s needs to be function', dim);
|
|
}
|
|
|
|
return;
|
|
}
|
|
});
|
|
var uCount = Math.floor((uOpts.max + uOpts.step - uOpts.min) / uOpts.step);
|
|
var vCount = Math.floor((vOpts.max + vOpts.step - vOpts.min) / vOpts.step);
|
|
data = new Float32Array(uCount * vCount * 5);
|
|
var uPrecision = getPrecision(uOpts);
|
|
var vPrecision = getPrecision(vOpts);
|
|
var off = 0;
|
|
|
|
for (var j = 0; j < vCount; j++) {
|
|
for (var i = 0; i < uCount; i++) {
|
|
var u = i * uOpts.step + uOpts.min;
|
|
var v = j * vOpts.step + vOpts.min;
|
|
var u2 = echarts.number.round(Math.min(u, uOpts.max), uPrecision);
|
|
var v2 = echarts.number.round(Math.min(v, vOpts.max), vPrecision);
|
|
var x = parametricEquation.x(u2, v2);
|
|
var y = parametricEquation.y(u2, v2);
|
|
var z = parametricEquation.z(u2, v2);
|
|
data[off++] = x;
|
|
data[off++] = y;
|
|
data[off++] = z;
|
|
data[off++] = u2;
|
|
data[off++] = v2;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
var dims = ['x', 'y', 'z'];
|
|
|
|
if (option.parametric) {
|
|
dims.push('u', 'v');
|
|
} // PENDING getSource?
|
|
|
|
|
|
var list = createList(this, dims, data);
|
|
return list;
|
|
},
|
|
defaultOption: {
|
|
coordinateSystem: 'cartesian3D',
|
|
zlevel: -10,
|
|
// Cartesian coordinate system
|
|
grid3DIndex: 0,
|
|
// Surface needs lambert shading to show the difference
|
|
shading: 'lambert',
|
|
// If parametric surface
|
|
parametric: false,
|
|
wireframe: {
|
|
show: true,
|
|
lineStyle: {
|
|
color: 'rgba(0,0,0,0.5)',
|
|
width: 1
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Generate surface data from z = f(x, y) equation
|
|
*/
|
|
equation: {
|
|
// [min, max, step]
|
|
x: {
|
|
min: -1,
|
|
max: 1,
|
|
step: 0.1
|
|
},
|
|
y: {
|
|
min: -1,
|
|
max: 1,
|
|
step: 0.1
|
|
},
|
|
z: null
|
|
},
|
|
parametricEquation: {
|
|
// [min, max, step]
|
|
u: {
|
|
min: -1,
|
|
max: 1,
|
|
step: 0.1
|
|
},
|
|
v: {
|
|
min: -1,
|
|
max: 1,
|
|
step: 0.1
|
|
},
|
|
// [x, y, z] = f(x, y)
|
|
x: null,
|
|
y: null,
|
|
z: null
|
|
},
|
|
// Shape of give data
|
|
// It is an array to specify rows and columns.
|
|
// For example [30, 30]
|
|
dataShape: null,
|
|
itemStyle: {// Color
|
|
},
|
|
animationDurationUpdate: 500
|
|
}
|
|
});
|
|
echarts.util.merge(SurfaceSeries.prototype, componentShadingMixin);
|
|
export default SurfaceSeries; |