hefeihvac_java/node_modules/echarts-gl/lib/chart/lines3D/lines3DLayout.js

147 lines
4.5 KiB
JavaScript
Raw Normal View History

2024-04-07 18:15:00 +08:00
import * as echarts from 'echarts/lib/echarts';
import glmatrix from 'claygl/src/dep/glmatrix';
var vec3 = glmatrix.vec3;
var vec2 = glmatrix.vec2;
var normalize = vec3.normalize;
var cross = vec3.cross;
var sub = vec3.sub;
var add = vec3.add;
var create = vec3.create;
var normal = create();
var tangent = create();
var bitangent = create();
var halfVector = create();
var coord0 = [];
var coord1 = [];
function getCubicPointsOnGlobe(coords, coordSys) {
vec2.copy(coord0, coords[0]);
vec2.copy(coord1, coords[1]);
var pts = [];
var p0 = pts[0] = create();
var p1 = pts[1] = create();
var p2 = pts[2] = create();
var p3 = pts[3] = create();
coordSys.dataToPoint(coord0, p0);
coordSys.dataToPoint(coord1, p3); // Get p1
normalize(normal, p0); // TODO p0-p3 is parallel with normal
sub(tangent, p3, p0);
normalize(tangent, tangent);
cross(bitangent, tangent, normal);
normalize(bitangent, bitangent);
cross(tangent, normal, bitangent); // p1 is half vector of p0 and tangent on p0
add(p1, normal, tangent);
normalize(p1, p1); // Get p2
normalize(normal, p3);
sub(tangent, p0, p3);
normalize(tangent, tangent);
cross(bitangent, tangent, normal);
normalize(bitangent, bitangent);
cross(tangent, normal, bitangent); // p2 is half vector of p3 and tangent on p3
add(p2, normal, tangent);
normalize(p2, p2); // Project distance of p0 on halfVector
add(halfVector, p0, p3);
normalize(halfVector, halfVector);
var projDist = vec3.dot(p0, halfVector); // Angle of halfVector and p1
var cosTheta = vec3.dot(halfVector, p1);
var len = (Math.max(vec3.len(p0), vec3.len(p3)) - projDist) / cosTheta * 2;
vec3.scaleAndAdd(p1, p0, p1, len);
vec3.scaleAndAdd(p2, p3, p2, len);
return pts;
}
function getCubicPointsOnPlane(coords, coordSys, up) {
var pts = [];
var p0 = pts[0] = vec3.create();
var p1 = pts[1] = vec3.create();
var p2 = pts[2] = vec3.create();
var p3 = pts[3] = vec3.create();
coordSys.dataToPoint(coords[0], p0);
coordSys.dataToPoint(coords[1], p3);
var len = vec3.dist(p0, p3);
vec3.lerp(p1, p0, p3, 0.3);
vec3.lerp(p2, p0, p3, 0.3);
vec3.scaleAndAdd(p1, p1, up, Math.min(len * 0.1, 10));
vec3.scaleAndAdd(p2, p2, up, Math.min(len * 0.1, 10));
return pts;
}
function getPolylinePoints(coords, coordSys) {
var pts = new Float32Array(coords.length * 3);
var off = 0;
var pt = [];
for (var i = 0; i < coords.length; i++) {
coordSys.dataToPoint(coords[i], pt);
pts[off++] = pt[0];
pts[off++] = pt[1];
pts[off++] = pt[2];
}
return pts;
}
function prepareCoords(data) {
var coordsList = [];
data.each(function (idx) {
var itemModel = data.getItemModel(idx);
var coords = itemModel.option instanceof Array ? itemModel.option : itemModel.getShallow('coords', true);
if (process.env.NODE_ENV !== 'production') {
if (!(coords instanceof Array && coords.length > 0 && coords[0] instanceof Array)) {
throw new Error('Invalid coords ' + JSON.stringify(coords) + '. Lines must have 2d coords array in data item.');
}
}
coordsList.push(coords);
});
return {
coordsList: coordsList
};
}
function layoutGlobe(seriesModel, coordSys) {
var data = seriesModel.getData();
var isPolyline = seriesModel.get('polyline');
data.setLayout('lineType', isPolyline ? 'polyline' : 'cubicBezier');
var res = prepareCoords(data);
data.each(function (idx) {
var coords = res.coordsList[idx];
var getPointsMethod = isPolyline ? getPolylinePoints : getCubicPointsOnGlobe;
data.setItemLayout(idx, getPointsMethod(coords, coordSys));
});
}
function layoutOnPlane(seriesModel, coordSys, normal) {
var data = seriesModel.getData();
var isPolyline = seriesModel.get('polyline');
var res = prepareCoords(data);
data.setLayout('lineType', isPolyline ? 'polyline' : 'cubicBezier');
data.each(function (idx) {
var coords = res.coordsList[idx];
var pts = isPolyline ? getPolylinePoints(coords, coordSys) : getCubicPointsOnPlane(coords, coordSys, normal);
data.setItemLayout(idx, pts);
});
}
export default function lines3DLayout(ecModel, api) {
ecModel.eachSeriesByType('lines3D', function (seriesModel) {
var coordSys = seriesModel.coordinateSystem;
if (coordSys.type === 'globe') {
layoutGlobe(seriesModel, coordSys);
} else if (coordSys.type === 'geo3D') {
layoutOnPlane(seriesModel, coordSys, [0, 1, 0]);
} else if (coordSys.type === 'mapbox3D' || coordSys.type === 'maptalks3D') {
layoutOnPlane(seriesModel, coordSys, [0, 0, 1]);
}
});
}
;