You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何同时使用Plotly的plotly_click与plotly_selected事件?

Fixing Plotly plotly_click Event Conflict with plotly_selected

Hey there! The issue you're facing happens because Plotly's event handling can prioritize box/lasso selection events over click events when both are active. Here are two straightforward solutions to get both features working together:

Solution 1: Use Native Click Event with Plotly's getPoint

Instead of relying on Plotly's plotly_click event, use the browser's native click event paired with Plotly's getPoint method to fetch the clicked coordinates. This bypasses any event conflicts with plotly_selected.

First, make sure your layout.shapes array is initialized (critical for avoiding errors):

// Initialize shapes array if it doesn't exist yet
if (!layout.shapes) {
    layout.shapes = [];
}

Then replace your original plotly_click handler with this native click listener:

// Handle click to add vertical line using native click event
plotDiv.addEventListener('click', function(event) {
    // Get the exact Plotly data point clicked
    const clickedPoint = Plotly.getPoint(event, 'myDiv');
    if (clickedPoint) {
        const xVal = clickedPoint.x;
        console.log("Vous voulez ajouter une rupture au point : ", xVal);
        
        // Add vertical line to the layout shapes
        layout.shapes.push({
            'type': 'line',
            'x0': xVal,
            'y0': line_bottom,
            'x1': xVal,
            'y1': line_top,
            'line': {
                'color': 'black',
                dash: 'dot',
                'width': 3,
            }
        });
        Plotly.redraw('myDiv');
    }
});

Keep your existing plotly_selected handler as-is, but add a check to skip it for click-only actions:

// Handle box selection to draw rectangle
plotDiv.on('plotly_selected', (eventData) => {
    const xRange = eventData.range.x;
    const yRange = eventData.range.y;
    
    // Only run if it's a real box selection (not a click)
    if (xRange[0] !== xRange[1] && yRange[0] !== yRange[1]) {
        console.log("x0 = ",xRange[0]," x1 = ",xRange[1]," y0 = ",yRange[0]," y1 = ",yRange[1]);
        
        // Add the four lines for the rectangle
        layout.shapes.push({
            'type': 'line',
            'x0':xRange[0],
            'y0':yRange[0],
            'x1':xRange[0],
            'y1':yRange[1],
            'line': {
                'color': 'red',
                dash: 'dot',
                'width':3,
            }
        });
        layout.shapes.push({
            'type': 'line',
            'x0':xRange[1],
            'y0':yRange[0],
            'x1':xRange[1],
            'y1':yRange[1],
            'line': {
                'color': 'red',
                dash: 'dot',
                'width':3,
            }
        });
        layout.shapes.push({
            'type': 'line',
            'x0':xRange[0],
            'y0':yRange[1],
            'x1':xRange[1],
            'y1':yRange[1],
            'line': {
                'color': 'red',
                dash: 'dot',
                'width':3,
            }
        });
        layout.shapes.push({
            'type': 'line',
            'x0':xRange[0],
            'y0':yRange[0],
            'x1':xRange[1],
            'y1':yRange[0],
            'line': {
                'color': 'red',
                dash: 'dot',
                'width':3,
            }
        });
        Plotly.redraw('myDiv');
    }
});

Solution 2: Merge Logic into plotly_selected Event

If you prefer to keep everything in one event handler, check if the "selection" is actually a click (where the start and end coordinates are identical). Then run the appropriate logic:

// Initialize shapes array
if (!layout.shapes) {
    layout.shapes = [];
}

// Combined handler for clicks and box selections
plotDiv.on('plotly_selected', (eventData) => {
    const xRange = eventData.range.x;
    const yRange = eventData.range.y;
    
    // Check if it's a click (no range change)
    if (xRange[0] === xRange[1] && yRange[0] === yRange[1]) {
        const xVal = xRange[0];
        console.log("Vous voulez ajouter une rupture au point : ", xVal);
        // Add vertical line
        layout.shapes.push({
            'type': 'line',
            'x0': xVal,
            'y0': line_bottom,
            'x1': xVal,
            'y1': line_top,
            'line': {
                'color': 'black',
                dash: 'dot',
                'width': 3,
            }
        });
    } else {
        // It's a box selection, draw the rectangle
        console.log("x0 = ",xRange[0]," x1 = ",xRange[1]," y0 = ",yRange[0]," y1 = ",yRange[1]);
        // Add rectangle lines
        layout.shapes.push({
            'type': 'line',
            'x0':xRange[0],
            'y0':yRange[0],
            'x1':xRange[0],
            'y1':yRange[1],
            'line': {
                'color': 'red',
                dash: 'dot',
                'width':3,
            }
        });
        layout.shapes.push({
            'type': 'line',
            'x0':xRange[1],
            'y0':yRange[0],
            'x1':xRange[1],
            'y1':yRange[1],
            'line': {
                'color': 'red',
                dash: 'dot',
                'width':3,
            }
        });
        layout.shapes.push({
            'type': 'line',
            'x0':xRange[0],
            'y0':yRange[1],
            'x1':xRange[1],
            'y1':yRange[1],
            'line': {
                'color': 'red',
                dash: 'dot',
                'width':3,
            }
        });
        layout.shapes.push({
            'type': 'line',
            'x0':xRange[0],
            'y0':yRange[0],
            'x1':xRange[1],
            'y1':yRange[0],
            'line': {
                'color': 'red',
                dash: 'dot',
                'width':3,
            }
        });
    }
    Plotly.redraw('myDiv');
});

Key Notes

  • Make sure line_bottom and line_top are properly defined with your chart's y-axis bounds.
  • Both solutions ensure clicks and box selections don't interfere with each other.

内容的提问来源于stack exchange,提问作者kowsik186

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.28 22:29:09