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