reactjs - Bir React TypeScript D3 grafik projesinde hedef 'ES3' veya 'ES5' olduğunda katı modda bloklar içinde fonksiyon bildirimlerine izin verilmemesi hatası nasıl düzeltilir?
clicked fonksiyonunda bu hatayla karşılaşıyorum: Function declarations are not allowed inside blocks in strict mode when targeting 'ES3' or 'ES5'. Modules are automatically in strict mode.. Bir react typescript uygulamasında d3.js kullanarak bir sunburst grafiği çizmeye çalışıyorum. Kod şu şekilde:
function clicked(event: any, p: any) {
parent.datum(p.parent || root);
g.select("#mainCircleText").text(p.data.name);
root.each(
(d: any) =>
(d.target = {
x0:
Math.max(0, Math.min(1, (d.x0 - p.x0) / (p.x1 - p.x0))) *
2 *
Math.PI,
x1:
Math.max(0, Math.min(1, (d.x1 - p.x0) / (p.x1 - p.x0))) *
2 *
Math.PI,
y0: Math.max(0, d.y0 - p.depth),
y1: Math.max(0, d.y1 - p.depth),
})
);
const t = g.transition().duration(750);
// Transition the data on all arcs, even the ones that aren’t visible,
// so that if this transition is interrupted, entering arcs will start
// the next transition from the desired position.
path
.transition(t)
.tween("data", (d) => {
const i = d3.interpolate(d.current, d.target);
return (t) => (d.current = i(t));
})
.filter(function (d) {
return +this.getAttribute("fill-opacity") || arcVisible(d.target);
})
.attr("fill-opacity", (d) =>
arcVisible(d.target) ? (d.children ? 0.6 : 0.4) : 0
)
.attrTween("d", (d) => () => {
return d3
.arc()
.startAngle((d) => d.x0)
.endAngle((d) => d.x1)
.padAngle((d) => Math.min((d.x1 - d.x0) / 2, 0.005))
.padRadius(radius * 1.5)
.innerRadius((d) => d.y0 * radius)
.outerRadius((d) => Math.max(d.y0 * radius, d.y1 * radius - 1))(
d.current
);
});
label
.filter(function (d) {
return +this.getAttribute("fill-opacity") || labelVisible(d.target);
})
.transition(t)
.attr("fill-opacity", (d) => +labelVisible(d.target))
.attrTween("transform", (d) => () => labelTransform(d.current));
}
Tüm grafik bileşeni
import { useEffect, useRef } from "react";
import isEqual from "lodash/isEqual";
import * as d3 from "d3";
import data from "./data";
// interface SunburstProps {
// data: {};
// keyId: string;
// width: number;
// }
interface TreeNode {
name: string;
value?: number;
children?: TreeNode[];
}
interface Data {
name: string;
children: TreeNode[];
}
interface SunburstProps {
data: Data;
keyId: string;
width: number;
}
const partition = (data: any) => {
const root = d3
.hierarchy(data)
.sum((d) => d.value)
.sort((a, b) => (b.value || 0) - (a.value || 0));
const partition = d3.partition().size([2 * Math.PI, root.height + 1])(root);
return partition;
};
function usePrevious(value: any) {
const ref = useRef();
useEffect(() => {
ref.current = value;
});
return ref.current;
}
const Sunburst = (props: SunburstProps) => {
const svgRef = useRef<SVGSVGElement>(null);
const prevProps = usePrevious(props);
useEffect(() => {
if (!isEqual(prevProps, props)) {
renderSunburst();
}
// eslint-disable-next-line
}, [props]);
const renderSunburst = () => {
const { data, width } = props;
const color = d3.scaleOrdinal(
d3.quantize(d3.interpolateRainbow, data.children.length + 1)
);
if (data) {
document.querySelectorAll("g").forEach((node) => {
node.remove();
});
const radius = width / 6;
const svg = d3
.select(svgRef.current)
.attr("viewBox", [0, 0, width, width])
.style("font", "10px sans-serif");
const g = svg
.append("g")
.attr("transform", `translate(${width / 2},${width / 2})`);
const root = partition(data);
root.each((d: any) => (d.current = d));
console.log("Root:", root);
const arcVisible = (d: any) => {
return d.y1 <= 3 && d.y0 >= 1 && d.x1 > d.x0;
};
const labelVisible = (d: any) => {
return d.y1 <= 3 && d.y0 >= 1 && (d.y1 - d.y0) * (d.x1 - d.x0) > 0.03;
};
const labelTransform = (d: any) => {
const x = (((d.x0 + d.x1) / 2) * 180) / Math.PI;
const y = ((d.y0 + d.y1) / 2) * radius;
return `rotate(${x - 90}) translate(${y},0) rotate(${
x < 180 ? 0 : 180
})`;
};
const clicked = (event: any, p: any) => {
parent.datum(p.parent || root);
g.select("#mainCircleText").text(p.data.name);
root.each(
(d: any) =>
(d.target = {
x0:
Math.max(0, Math.min(1, (d.x0 - p.x0) / (p.x1 - p.x0))) *
2 *
Math.PI,
x1:
Math.max(0, Math.min(1, (d.x1 - p.x0) / (p.x1 - p.x0))) *
2 *
Math.PI,
y0: Math.max(0, d.y0 - p.depth),
y1: Math.max(0, d.y1 - p.depth),
})
);
const t = g.transition().duration(750);
// Transition the data on all arcs, even the ones that aren’t visible,
// so that if this transition is interrupted, entering arcs will start
// the next transition from the desired position.
path
.transition(t)
.tween("data", (d) => {
const i = d3.interpolate(d.current, d.target);
return (t) => (d.current = i(t));
})
.filter(function (d) {
return +this.getAttribute("fill-opacity") || arcVisible(d.target);
})
.attr("fill-opacity", (d) =>
arcVisible(d.target) ? (d.children ? 0.6 : 0.4) : 0
)
.attrTween("d", (d) => () => {
return d3
.arc()
.startAngle((d) => d.x0)
.endAngle((d) => d.x1)
.padAngle((d) => Math.min((d.x1 - d.x0) / 2, 0.005))
.padRadius(radius * 1.5)
.innerRadius((d) => d.y0 * radius)
.outerRadius((d) => Math.max(d.y0 * radius, d.y1 * radius - 1))(
d.current
);
});
label
.filter(function (d) {
return +this.getAttribute("fill-opacity") || labelVisible(d.target);
})
.transition(t)
.attr("fill-opacity", (d: any) => +labelVisible(d.target))
.attrTween("transform", (d: any) => () => labelTransform(d.current));
};
const path = g
.append("g")
.selectAll("path")
.data(root.descendants().slice(1))
.join("path")
.attr("fill", (d: any) => {
while (d.depth > 1) d = d.parent;
return color(d.data.name);
})
.attr("fill-opacity", (d: any) =>
arcVisible(d.current) ? (d.children ? 0.6 : 0.4) : 0
)
.attr("d", (d: any) => {
return d3
.arc()
.startAngle((d: any) => {
return d.x0;
})
.endAngle((d: any) => d.x1)
.padAngle((d: any) => Math.min((d.x1 - d.x0) / 2, 0.005))
.padRadius(radius * 1.5)
.innerRadius((d: any) => d.y0 * radius)
.outerRadius((d: any) =>
Math.max(d.y0 * radius, d.y1 * radius - 1)
)(d.current);
});
path
.filter((d: any) => d.children)
.style("cursor", "pointer")
.on("click", clicked);
path.append("title").text(
(d: any) =>
`${d
.ancestors()
.map((d: any) => d.data.name)
.reverse()
.join("/")}\n${d3.format(",d")(d.value)}`
);
const label = g
.append("g")
.attr("pointer-events", "none")
.attr("text-anchor", "middle")
.style("user-select", "none")
.selectAll("text")
.data(root.descendants().slice(1))
.join("text")
.attr("dy", "0.35em")
.attr("fill-opacity", (d: any) => +labelVisible(d.current))
.attr("transform", (d: any) => labelTransform(d.current))
.text((d: any) => d.data.name);
const parent = g
.append("circle")
.datum(root)
.attr("r", radius)
.attr("fill", "none")
.attr("pointer-events", "all")
.on("click", clicked);
g.append("text")
.datum(root)
.attr("id", "mainCircleText")
.text((d: any) => d.data.name)
.attr("font-size", 40) //font size
.attr("x", 0)
.attr("dy", ".35em")
.attr("text-anchor", "middle")
.on("click", clicked);
}
};
return (
<div id={props.keyId} className="text-center">
<svg ref={svgRef} id={`${props.keyId}-svg`} />
</div>
);
};
Codesandbox bağlantısı
Güncelleme
clicked fonksiyonunu şu şekilde güncelledim
const clicked = (event: any, p: any) => {
parent.datum(p.parent || root);
g.select("#mainCircleText").text(p.data.name);
root.each(
(d: any) =>
(d.target = {
x0:
Math.max(0, Math.min(1, (d.x0 - p.x0) / (p.x1 - p.x0))) *
2 *
Math.PI,
x1:
Math.max(0, Math.min(1, (d.x1 - p.x0) / (p.x1 - p.x0))) *
2 *
Math.PI,
y0: Math.max(0, d.y0 - p.depth),
y1: Math.max(0, d.y1 - p.depth),
})
);
const t = g.transition().duration(750);
// Transition the data on all arcs, even the ones that aren’t visible,
// so that if this transition is interrupted, entering arcs will start
// the next transition from the desired position.
path
.transition(t)
.tween("data", (d) => {
const i = d3.interpolate(d.current, d.target);
return (t) => (d.current = i(t));
})
.filter(function (d) {
return +this.getAttribute("fill-opacity") || arcVisible(d.target);
})
.attr("fill-opacity", (d) =>
arcVisible(d.target) ? (d.children ? 0.6 : 0.4) : 0
)
.attrTween("d", (d) => () => {
return d3
.arc()
.startAngle((d) => d.x0)
.endAngle((d) => d.x1)
.padAngle((d) => Math.min((d.x1 - d.x0) / 2, 0.005))
.padRadius(radius * 1.5)
.innerRadius((d) => d.y0 * radius)
.outerRadius((d) => Math.max(d.y0 * radius, d.y1 * radius - 1))(
d.current
);
});
label
.filter(function (d) {
return +this.getAttribute("fill-opacity") || labelVisible(d.target);
})
.transition(t)
.attr("fill-opacity", (d: any) => +labelVisible(d.target))
.attrTween("transform", (d: any) => () => labelTransform(d.current));
};
Bu sefer path..transition(t) içinde ts hatası olarak Bu çağrı ile eşleşen bir fazla yükleme yok. 3 fazla yüklemeden 1. olan '(name: string, factory: null): Transition<BaseType | SVGPathElement, HierarchyRectangularNode<unknown>, SVGGElement, unknown>' hatayı verdi.. Herhangi bir yardım/öneri gerçekten çok faydalı olur.
Cevap #1
Sadece fonksiyon bildirimini yeniden yaz
function clicked(event: any, p: any) {
// ...
}
için
const clicked = (event: any, p: any) => {
// ...
}
Ve tanım kullanımdan önce olacak şekilde kodda yukarı taşı.
