in src/Wmap/index.tsx [557:658]
function drawMapBackground(ctx: Map, chart: Chart, ds: DataSet, config: WmapConfig) {
let geoData = null;
if (ctx.geoData) {
// 如果用户有传geoData,优先使用
geoData = ctx.geoData;
} else if (config.type === 'china') {
// 自带中国地图数据
geoData = chinaGeo;
} else {
warn('Wmap', "no geo data, can't draw the map!");
}
const bgMapDataView = ds.createView('bgMap').source(geoData, {
type: 'GeoJSON',
});
let { projection } = config;
if (!projection) {
projection = bgMapDataView.getGeoProjection('geoConicEqualArea');
projection
// @ts-ignore
.center([0, 36.4])
.parallels([25, 47])
.scale(1000)
.rotate([-105, 0])
.translate([0, 0]);
}
bgMapDataView.transform({
type: 'geo.projection',
// 因为G2的投影函数不支持设置投影参数,这里使用自定义的投影函数设置参数
// @ts-ignore
projection() {
return projection;
},
as: ['x', 'y', 'cX', 'cY'],
});
if (config.type === 'china') {
// 过滤掉南海诸岛
bgMapDataView.transform({
type: 'filter',
callback(row) {
return row.properties.name !== '南海诸岛';
},
});
}
// start: 按照投影后尺寸比例调整图表的真实比例
const longitudeRange = bgMapDataView.range('x');
const latitudeRange = bgMapDataView.range('y');
const ratio = (longitudeRange[1] - longitudeRange[0]) / (latitudeRange[1] - latitudeRange[0]);
ctx.bgMapRatio = ratio;
const { width: chartWidth, height: chartHeight } = chart;
const chartRatio = chartWidth / chartHeight;
let width = chartWidth;
let height = chartHeight;
if (chartRatio > ratio) {
width = chartHeight * ratio;
} else if (chartRatio < ratio) {
height = chartWidth / ratio;
}
if (width !== chartWidth || height !== chartHeight) {
const p1 = (chartWidth - width) / 2;
const p2 = (chartHeight - height) / 2;
// 不设置尺寸,通过padding控制地图形状
chart.appendPadding = [p2, p1, p2, p1];
}
ctx.bgMapSize = [width, height];
// end: 按照投影后尺寸比例调整图表的真实比例
const { fill: bgFill, stroke: bgStroke, ...otherBgStyle } = config.background || {};
const bgMapView = chart.createView({
padding: 0,
});
bgMapView.data(bgMapDataView.rows);
bgMapView.tooltip(false);
bgMapView
.polygon()
.position('x*y')
.style('name', function (name) {
const result = {
fill: bgFill || themes['widgets-map-area-bg'],
stroke: bgStroke || themes['widgets-map-area-border'],
lineWidth: 1,
...otherBgStyle,
};
// 对一些尺寸非常小的形状特殊处理,以显示出来。
if (minArea.indexOf(name) > -1) {
result.stroke = bgFill || themes['widgets-map-area-bg'];
}
return result;
});
ctx.bgMapDataView = bgMapDataView;
ctx.bgMapView = bgMapView;
ctx.projection = projection;
}