D3.js canvas 上下文填写错误
D3.js canvas context fill wrong
我用D3做地图,这是我的代码
d3.json('https://unpkg.com/world-atlas@1/world/110m.json', (error, topology) => {
if (error) throw error;
let width = map.offsetWidth,
height = map.offsetHeight;
let projection = d3.geoMercator().scale('200').translate([width / 2, height / 1.4]);
let canvas = d3.select('.map').append('canvas')
.attr('width', width)
.attr('height', height);
let context = canvas.node().getContext('2d'),
path = d3.geoPath()
.context(context)
.projection(projection);
context.fillStyle = '#d8d8d8';
context.strokeStyle = 'black';
context.beginPath();
path(topojson.mesh(topology));
context.fill();
context.stroke()
});
并出错canvas
有一些白色但应该是灰色的。
我不知道发生了什么,如果使用 svg 效果很好,但在这种情况下,我想使用 canvas。
谢谢。
发生这种情况是因为您实际上并未绘制国家/地区。您正在围绕国家/地区绘制网格 - 这意味着您的特征不是国家/地区,而是边界(和海岸)部分。
一般画国家的时候,每个要素都是一个国家,填路径就填要素,随心所欲。因此,两国之间的每条边界都被绘制了两次。 Topojson 对拓扑进行编码,将国家/地区的形状分解为线段,以便每个线段记录一次。 topojson 网格只生成这些线段。填充一条线本质上是通过连接第一个点和最后一个点来创建一个多边形。在您的地图中,这在美国大陆海岸非常明显。
尝试将 topojson 转换为 geojson:
topojson.feature(topology, topology.objects.features)
如以下代码片段所示(使用您的代码):
d3.json('https://unpkg.com/world-atlas@1/world/110m.json', (error, topology) => {
if (error) throw error;
let width = 960,
height = 500;
let projection = d3.geoMercator().scale('200').translate([width / 2, height / 1.4]);
let canvas = d3.select('body').append('canvas')
.attr('width', width)
.attr('height', height);
let context = canvas.node().getContext('2d'),
path = d3.geoPath()
.context(context)
.projection(projection);
context.fillStyle = '#d8d8d8';
context.strokeStyle = 'black';
context.beginPath();
path(topojson.feature(topology, topology.objects.countries));
context.fill();
context.stroke()
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.10.0/d3.min.js"></script>
<script src="https://d3js.org/topojson.v2.min.js"></script>
我用D3做地图,这是我的代码
d3.json('https://unpkg.com/world-atlas@1/world/110m.json', (error, topology) => {
if (error) throw error;
let width = map.offsetWidth,
height = map.offsetHeight;
let projection = d3.geoMercator().scale('200').translate([width / 2, height / 1.4]);
let canvas = d3.select('.map').append('canvas')
.attr('width', width)
.attr('height', height);
let context = canvas.node().getContext('2d'),
path = d3.geoPath()
.context(context)
.projection(projection);
context.fillStyle = '#d8d8d8';
context.strokeStyle = 'black';
context.beginPath();
path(topojson.mesh(topology));
context.fill();
context.stroke()
});
并出错canvas
有一些白色但应该是灰色的。 我不知道发生了什么,如果使用 svg 效果很好,但在这种情况下,我想使用 canvas。 谢谢。
发生这种情况是因为您实际上并未绘制国家/地区。您正在围绕国家/地区绘制网格 - 这意味着您的特征不是国家/地区,而是边界(和海岸)部分。
一般画国家的时候,每个要素都是一个国家,填路径就填要素,随心所欲。因此,两国之间的每条边界都被绘制了两次。 Topojson 对拓扑进行编码,将国家/地区的形状分解为线段,以便每个线段记录一次。 topojson 网格只生成这些线段。填充一条线本质上是通过连接第一个点和最后一个点来创建一个多边形。在您的地图中,这在美国大陆海岸非常明显。
尝试将 topojson 转换为 geojson:
topojson.feature(topology, topology.objects.features)
如以下代码片段所示(使用您的代码):
d3.json('https://unpkg.com/world-atlas@1/world/110m.json', (error, topology) => {
if (error) throw error;
let width = 960,
height = 500;
let projection = d3.geoMercator().scale('200').translate([width / 2, height / 1.4]);
let canvas = d3.select('body').append('canvas')
.attr('width', width)
.attr('height', height);
let context = canvas.node().getContext('2d'),
path = d3.geoPath()
.context(context)
.projection(projection);
context.fillStyle = '#d8d8d8';
context.strokeStyle = 'black';
context.beginPath();
path(topojson.feature(topology, topology.objects.countries));
context.fill();
context.stroke()
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.10.0/d3.min.js"></script>
<script src="https://d3js.org/topojson.v2.min.js"></script>