D3.js D3V5使用画布在鼠标上绘制工具提示
我使用D3V5绘制散点图,使用具有缩放功能的画布,当悬停在特定点上时,我无法创建工具提示。如果一个点被悬停,我想用它的x和y轴显示工具提示。 如果没有画布,我可以将事件添加到点,但当有超过400个点时,UI会卡住,这就是为什么我将实现更改为画布 以下是我的工作代码:D3.js D3V5使用画布在鼠标上绘制工具提示,d3.js,D3.js,我使用D3V5绘制散点图,使用具有缩放功能的画布,当悬停在特定点上时,我无法创建工具提示。如果一个点被悬停,我想用它的x和y轴显示工具提示。 如果没有画布,我可以将事件添加到点,但当有超过400个点时,UI会卡住,这就是为什么我将实现更改为画布 以下是我的工作代码: const container = d3.select('#graph'); // Init SVG const svgChart = container.append('svg:svg') .attr(&qu
const container = d3.select('#graph');
// Init SVG
const svgChart = container.append('svg:svg')
.attr("id", "svg-id2")
.attr('width', outerWidth)
.attr('height', outerHeight)
.attr('class', 'svg-plot')
.append('g')
.attr('transform', `translate(${margin.left}, ${margin.top})`);
// Init Canvas
const canvasChart = container.append('canvas')
.attr("id", "canvass-id2")
.attr('width', width)
.attr('height', height)
.style('margin-left', margin.left + 'px')
.style('margin-top', margin.top + 'px')
.attr('class', 'canvas-plot');
// Prepare buttons
const toolsList = container.select('.tools')
.style('margin-top', margin.top + 'px')
.style('visibility', 'visible');
toolsList.select('#reset').on('click', () => {
const t = d3.zoomIdentity.translate(0, 0).scale(1);
canvasChart.transition()
.duration(200)
.ease(d3.easeLinear)
.call(zoom_function.transform, t)
});
var scale = 1.5;
const context = canvasChart.node().getContext('2d');
let min_x = d3.max(data, (d) => d['x'])
// Init Scales
const x = d3.scaleLinear().domain([d3.min(data, (d) => d['x']), d3.max(data, (d) => d['x'])]).range([0, width]).nice();
const y = d3.scaleLinear().domain([d3.min(data, (d) => d['y']), d3.max(data, (d) => d['y'])]).range([height, 0]).nice();
// Init Axis
const xAxis = d3.axisBottom(x);
const yAxis = d3.axisLeft(y);
// Add Axis
const gxAxis = svgChart.append('g')
.attr('transform', `translate(0, ${height})`)
.call(xAxis);
const gyAxis = svgChart.append('g')
.call(yAxis);
// Add labels
svgChart.append('text')
.attr('x', `-${height / 2}`)
.attr('dy', '-3.5em')
.attr('transform', 'rotate(-90)')
.text('Axis Y');
svgChart.append('text')
.attr('x', `${width / 2}`)
.attr('y', `${height + 40}`)
.text('Axis X');
// Draw plot on canvas
function draw(transform) {
const scaleX = transform.rescaleX(x);
const scaleY = transform.rescaleY(y);
gxAxis.call(xAxis.scale(scaleX));
gyAxis.call(yAxis.scale(scaleY));
context.clearRect(0, 0, width, height);
data.forEach(point => {
drawPoint(scaleX, scaleY, point, transform.k);
});
}
var zoom = d3.zoom()
.on('zoom', function () {
canvasChart.attr('transform', d3.event.transform);
})
// Initial draw made with no zoom
draw(d3.zoomIdentity)
function drawPoint(scaleX, scaleY, point, k) {
context.beginPath();
context.fillStyle = pointColor;
context.strokeStyle = pointStroke;
context.lineWidth = 1;
const px = scaleX(point['x']);
const py = scaleY(point['y']);
var r = 2
context.arc(px, py, r, 0, 2 * Math.PI, true);
context.fill();
}
// Zoom/Drag handler
const zoom_function = d3.zoom().scaleExtent([1, 1000])
.on('zoom', () => {
console.log('zoom')
const transform = d3.event.transform;
context.save();
draw(transform);
context.restore();
});
function changeRadius(val) {
return Math.log10(val);
}
function reset() {
const t = d3.zoomIdentity.translate(0, 0).scale(1);
canvasChart.transition()
.duration(200)
.ease(d3.easeLinear)
.call(zoom_function.transform, t)
}
d3.selectAll('#zoomIn').on('click', function () {
scale += 0.1
const t = d3.zoomIdentity.translate(0, 0).scale(scale);
canvasChart.transition()
.duration(200)
.ease(d3.easeLinear)
.call(zoom_function.transform, t)
})
d3.selectAll('#zoomOut').on('click', function () {
scale -= 0.1
d3.zoom().scaleExtent([1, 1000]);
const t = d3.zoomIdentity.translate(0, 0).scale(scale);
canvasChart.transition()
.duration(200)
.ease(d3.easeLinear)
.call(zoom_function.transform, t)
});
d3.selectAll('#reset').on('click', reset);
canvasChart.call(zoom_function);
如何将工具提示添加到特定点任何帮助都将不胜感激。您可以使用来显示工具提示。