原创

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

原文地址:https://www.cnblogs.com/xiaoxu-xmy/p/13764570.html