zoukankan      html  css  js  c++  java
  • 原创

    reac +d3.js +TS 实现地理图 报错解决

    1. 结构

    结构请看之前的文章,这里记录部分报错解决的方式。能力受限无法解决d3-tip报错问题。

    2. 报错

    2.1 Property 'features' does not exis on type 'Feature<Point, GeoJsonProperties>'

    let worldMeta = topojson.feature<GeoJsonProperties>(
            data,
            data.objects.countries
          );
          projection.fitSize([innerWidth, innerHeight], worldMeta as any);
          g.selectAll("path")
            .data(worldMeta.features)
    

    解决方法
    1: worldMeta类型设置为GeoJsonProperties

    let worldMeta: GeoJsonProperties = topojson.feature<GeoJsonProperties>(
            data,
            data.objects.countries
          );
          projection.fitSize([innerWidth, innerHeight], worldMeta as any);
          g.selectAll("path")
            .data(worldMeta.features)
    

    2: worldMeta类型设置为any

    let worldMeta: any = topojson.feature<GeoJsonProperties>(
            data,
            data.objects.countries
          );
          projection.fitSize([innerWidth, innerHeight], worldMeta as any);
          g.selectAll("path")
            .data(worldMeta.features)
    

    2.2 使用geoPath生成器为d属性赋值时报错

    Type 'unknown' is not assignable to type 'ExtendedFeatureCollection<ExtendedFeature<Point | MultiPoint | LineString | MultiLineString | Polygon | MultiPolygon | GeometryCollection | GeoSphere | null, GeoJsonProperties>>'.

     const projection = d3.geoNaturalEarth1();
     const geo = d3.geoPath().projection(projection);
    
    
     g.selectAll("path")
            .data(worldMeta.features)
            .enter()
            .append("path")
            .attr("stroke", "black")
            .attr("stroke-width", 1)
            .attr("d", geo)
    

    解决方法:
    使用valueFn解决

    attr(name: string, value: ValueFn<GElement, Datum, string | number | boolean | null>): this;

    g.selectAll("path")
            .data(worldMeta.features)
            .enter()
            .append("path")
            .attr("stroke", "black")
            .attr("stroke-width", 1)
            .attr("d", (data: any) => geo(data))
    

    2.3 关于d3-tip报错 没有解决

    d3-tip是d3.js社区的一个库,它将tip方法直接挂载到d3.js中的d3全局对象上,但是在react + ts环境下,不管调用d3-tip还是d3.tip都无法使用。

    d3-tip中index.d.ts文件使用模块扩展语法,想要将tip()挂载到d3模块下。

    import { Primitive } from "d3";
    declare module "d3" {
        type TooltipDirection = ("n" | "s" | "e" | "w" | "nw" | "ne" | "sw" | "se");
        interface Tooltip {
            hide(): Tooltip;
            show(): Tooltip;
            show<Datum>(data: Datum[]): Tooltip;
            show(target: SVGElement): Tooltip;
            show<Datum>(data: Datum[], target: SVGElement): Tooltip;
            attr(name: string): string;
            attr(name: string, value: Primitive): Tooltip;
            attr<Datum>(name: string, value: (datum: Datum, index: number, outerIndex: number) => Primitive): Tooltip;
            attr<Datum>(obj: { [key: string]: Primitive | ((datum: Datum, index: number, outerIndex: number) => Primitive) }): Tooltip;
            style(name: string): string;
            style(name: string, value: Primitive, priority?: string): Tooltip;
            style<Datum>(name: string, value: (datum: Datum, index: number, outerIndex: number) => Primitive, priority?: string): Tooltip;
            style<Datum>(obj: { [key: string]: Primitive | ((datum: Datum, index: number, outerIndex: number) => Primitive) }, priority?: string): Tooltip;
            offset(): [number, number];
            offset(tuple: [number, number]): Tooltip;
            offset<Datum>(func: (datum: Datum, index: number, outerIndex: number) => [number, number]): Tooltip;
            direction(): TooltipDirection;
            direction(direction: TooltipDirection): Tooltip;
            direction<Datum>(func: (datum: Datum, index: number, outerIndex: number) => TooltipDirection): Tooltip;
            html(): string;
            html(content: string): Tooltip;
            html<Datum>(func: (datum: Datum, index: number, outerIndex: number) => string): Tooltip;
            rootElement(): HTMLElement;
            rootElement(element: HTMLElement): Tooltip;
            rootElement<Datum>(func: (datum: Datum, index: number, outerIndex: number) => HTMLElement): Tooltip;
            destroy(): Tooltip;
        }
        export function tip(): Tooltip;
    }
    

    3 完整代码

    import React, { useRef, useEffect, useState } from "react";
    import * as topojson from "topojson";
    import { GeoJsonProperties, Feature } from "geojson";
    import * as d3 from "d3";
    import { svg } from "d3";
    import "d3-tip";
    import "../CSS/earth.css";
    import "d3-tip";
    const InteractionMap: React.FC = () => {
      const ref = useRef<SVGSVGElement>(null);
      const [width] = useState(1600);
      const [height] = useState(800);
      const [margin] = useState({
        top: 60,
        right: 60,
        bottom: 10,
        left: 60,
      });
      const innerWidth = width - margin.left - margin.right;
      const innerHeight = height - margin.top - margin.bottom;
      useEffect(() => {
        const svgSelection = d3.select(ref.current);
        svgSelection.attr("width", width).attr("height", height);
        const g = svgSelection
          .append("g")
          .attr("id", "mainGroup")
          .attr("transform", `translate(${margin.left},${margin.right})`);
        const projection = d3.geoNaturalEarth1();
        const geo = d3.geoPath().projection(projection);
        // let tip: any = d3
        //   .tip()
        //   .attr("class", "d3-tip")
        //   .html((d: any) => d.properties.name);
        // svgSelection.call(tip);
        d3.json("./topoJson/countries-110m.json").then((data: any) => {
          let worldMeta: GeoJsonProperties = topojson.feature<GeoJsonProperties>(
            data,
            data.objects.countries
          );
          projection.fitSize([innerWidth, innerHeight], worldMeta as any);
          g.selectAll("path")
            .data(worldMeta.features)
            .enter()
            .append("path")
            .attr("stroke", "black")
            .attr("stroke-width", 1)
            .attr("d", (data: any) => geo(data))
            .on("mouseover", function (d) {
              d3.select(this)
                .attr("opacity", 0.5)
                .attr("stroke", "white")
                .attr("stroke-width", 6);
              //   tip.show(d);
            })
            .on("mouseout", function (d) {
              d3.select(this)
                .attr("opacity", 1)
                .attr("stroke", "black")
                .attr("stroke-width", 1);
            });
        });
      });
      return (
        <>
          <svg ref={ref}></svg>
        </>
      );
    };
    export { InteractionMap };
    

    原文地址:https://www.cnblogs.com/xiaoxu-xmy/p/13764570.html
    GitHub: https://github.com/lemon-Xu/Learning-d3.-Js
    作者: lemon

  • 相关阅读:
    flask-script插件
    狗书(flask基础)
    2018.1.18纪事
    py3.6 + xadmin的自学网站搭建
    使用selenium抓取淘宝的商品信息
    pyquery操作
    requests模块
    python3里的Urllib库
    随便写点
    How many ways?? HDU
  • 原文地址:https://www.cnblogs.com/xiaoxu-xmy/p/13764570.html
Copyright © 2011-2022 走看看