我无法在图表中拖动圆圈。这是现场演示https://codesandbox.io/s/71loxoq65j。
我的图表
echo number_format("150",2);
还有我正在调用图表的组件
import { event, select, Selection } from "d3-selection";
import { scaleLinear, ScaleLinear } from "d3-scale";
import { Axis, axisBottom, axisLeft } from "d3-axis";
import { line, Line } from "d3-shape";
import { drag } from "d3-drag";
interface IMargin {
left: number;
right: number;
top: number;
bottom: number;
}
interface IConfig {
height: number;
margin: IMargin;
target: SVGSVGElement;
width: number;
}
interface ISample {
x: number;
y: number;
}
export default class Trigger {
private chart: Selection<SVGGElement, {}, null, undefined>;
private xScale: ScaleLinear<number, number>;
private yScale: ScaleLinear<number, number>;
private xAxis: Axis<number>;
private xAxisGroup: Selection<SVGGElement, {}, null, undefined>;
private yAxis: Axis<number>;
private yAxisGroup: Selection<SVGGElement, {}, null, undefined>;
constructor(config: IConfig) {
const w = config.width - config.margin.left - config.margin.right;
const h = config.height - config.margin.top - config.margin.bottom;
// create global chart object
this.chart = select(config.target)
.attr("width", config.width)
.attr("height", config.height)
.append("g")
.attr(
"transform",
`translate(${config.margin.left}, ${config.margin.top})`
);
// create x scale function
this.xScale = scaleLinear()
.domain([0, 100])
.range([0, w]);
// create y scale function
this.yScale = scaleLinear()
.domain([0, 100])
.range([h, 0]);
// create x axis function
this.xAxis = (axisBottom(this.xScale) as Axis<number>).ticks(5);
// create y axis function
this.yAxis = (axisLeft(this.yScale) as Axis<number>).ticks(5);
// append x axis to chart and call xAxis function
this.xAxisGroup = this.chart
.append("g")
.attr("class", "x axis")
.attr("transform", `translate(0, ${h})`)
.call(this.xAxis);
// append y axis to chart and call yAxis function
this.yAxisGroup = this.chart
.append("g")
.attr("class", "y axis")
.call(this.yAxis);
// add x axis description
this.chart
.append("text")
.attr("x", w / 2)
.attr("y", h + config.margin.bottom)
.style("text-anchor", "middle")
.text("foo");
// add y axis description
this.chart
.append("text")
.attr("x", -h / 2)
.attr("y", -config.margin.left)
.attr("transform", "rotate(-90)")
.attr("text-anchor", "middle")
.attr("alignment-baseline", "hanging")
.text("bar");
}
public yellow(data: ISample[]) {
// draw circles
this.chart
.selectAll("circle")
.data(data)
.enter()
.append("circle")
.attr("cx", d => this.xScale(d.x))
.attr("cy", d => this.yScale(d.y))
.attr("r", 8)
.attr("fill", "orange")
.attr("class", "circle")
.call(
drag().on("drag", function(d) {
select(this).attr("cx", (d.x = event.x));
})
);
}
}
您可以看到第一次拖动的初始位置是错误的。它总是从import * as React from "react";
import { render } from "react-dom";
import Chart from "./chart";
import "./styles.css";
const Trigger = () => {
const chart: React.MutableRefObject<Chart | null> = React.useRef(null);
const chartRef = React.useRef(null);
const [start, setStart] = React.useState(20);
const [end, setEnd] = React.useState(50);
// run on did mount but never again
React.useEffect(() => {
chart.current = new Chart({
height: 320,
margin: {
bottom: 40,
left: 50,
right: 20,
top: 10
},
target: chartRef.current!,
width: 640
});
const yellow = [{ x: start, y: 50 }, { x: end, y: 50 }];
chart.current.yellow(yellow);
}, []);
return (
<div>
<svg ref={chartRef} />
</div>
);
};
const rootElement = document.getElementById("root");
render(<Trigger />, rootElement);
开始。圆圈跳到左侧。之后,一切都很好,并且可以按预期工作。我尝试遵循这个简单的示例https://bl.ocks.org/mbostock/22994cc97fefaeede0d861e6815a847e,但它没有任何规模。
我在做什么错了?
最好的问候, 米尔科
答案 0 :(得分:1)
您需要将鼠标位置转换为图表的g
import { event, select, Selection, mouse } from "d3-selection";
public yellow(data: ISample[]) {
// draw circles
var that = this;
this.chart
.selectAll("circle")
.data(data)
.enter()
.append("circle")
.attr("cx", d => this.xScale(d.x))
.attr("cy", d => this.yScale(d.y))
.attr("r", 8)
.attr("fill", "orange")
.attr("class", "circle")
.call(
drag().on("drag", function(d) {
select(this).attr("cx", (d.x = mouse(that.chart.node())[0]));
})
);
}