D3.js 画布上下文填充错误 [英] D3.js canvas context fill wrong

查看:29
本文介绍了D3.js 画布上下文填充错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我用 D3 制作地图,这是我的代码

I make a map with D3, it's my code

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()
    });

并得到错误的画布

有一些白色,但应该是灰色的.我不知道发生了什么,如果使用 svg 效果很好,但在这种情况下,我想使用画布.谢谢.

There are some white but should be gray. I have no idea what happened, if use svg it works perfectly, but in this case, I want to use canvas. Thanks.

推荐答案

发生这种情况是因为您实际上并未绘制国家/地区.您正在围绕国家/地区绘制网格 - 这意味着您的要素不是国家/地区,而是边界(和海岸)段.

This happens because you aren't actually drawing the countries. You are drawing the mesh around the countries - and this means that your features aren't countries, but border (and coast) segments.

通常在绘制国家/地区时,每个要素都是一个国家/地区,填充路径即可填充要素,如您所愿.因此,两国之间的每条边界都绘制了两次.Topojson 对拓扑进行编码,将国家形状分成线段,以便每个线段记录一次.topojson 网格只生成这些线段.填充一条线本质上是通过将第一个点与最后一个点连接起来创建一个多边形.在您的地图中,这在美国大陆的海岸上非常明显.

Normally when drawing countries, each feature is a whole country, and filling the path fills the feature, as you want. Each border between two countries is thus drawn twice. Topojson encodes topology, which breaks the countries shapes into line segments so that each segment is recorded once. The topojson mesh just produces these line segments. Filling a line essentially creates a polygon by linking the first point with the last point. In your map this is quite visible with the coasts of the continental US.

尝试将 topojson 转换为 geojson:

Try converting the topojson to geojson:

topojson.feature(topology, topology.objects.features)

如下面的代码片段(使用您的代码):

As in the snippet below (using your code):

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.js 画布上下文填充错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆