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

查看:106
本文介绍了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它完美地工作,但在这种情况下,我想使用canvas。
谢谢。

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天全站免登陆