vishnu BHAT
vishnu BHAT

Reputation: 1

Text and annotations removal with Legend

I did a scatter plot with legends , text and annotations . But when i click on the legend text and annotations associated with the bubble remains. Please check the below code.

    const getAnnotations = () => {
        if (totalRecords <= 10) {
            const annotations: any[] = [];
            const placedPositions: { x: number; y: number }[] = [];
            const groupedData = new Map<string, { storeLabels: string[], x: number, y: number, z: number }>();
    
            // Group data by total_sales and spearman_correlation
            data.forEach((item) => {
                const storeLabel = item[firstColumnFieldName] || "Unknown Store";
                const key = `${item.total_sales}-${item.spearman_correlation}`;
                if (!groupedData.has(key)) {
                    groupedData.set(key, { storeLabels: [], x: item.total_sales, y: item.spearman_correlation, z: item.max_sales });
                }
                groupedData.get(key)!.storeLabels.push(storeLabel);
            });
    
            // Alternating offsets for y (up and down)
            let isPositiveYOffset = true;
    
            groupedData.forEach(({ storeLabels, x, y, z }) => {
                // Only include annotations where spearman_correlation is greater than 0.2 or less than -0.2
                if (y <= 0.5 && y >= -0.5) return; // Skip if correlation is between -0.2 and 0.2
    
                const combinedLabel = storeLabels.join(", <br>"); // Combine store names with commas
                const isShortLabel = combinedLabel.length <= 3; // Check if label is short
    
                // Calculate bubble size based on total_sales (or another metric if necessary)
                const bubbleSize = calculateBubbleSize(y, totalRecords, x, z, allLessThanOrEqualZero);
    
                // Check if label can fit inside the bubble
                const labelFitsInsideBubble = !isLabelTooBig(combinedLabel, bubbleSize);
    
                // Alternate between positive and negative y offsets for annotation placement
                const yOffset = isPositiveYOffset ? 30 : -30;
    
                // Switch between positive and negative offsets for next annotation
                isPositiveYOffset = !isPositiveYOffset;
    
                // Function to check if an annotation overlaps with either an existing bubble or annotation
                const isOverlapping = (x: number, y: number, bubbleSize: number) => {
                    // Check if it overlaps with other annotations
                    const annotationOverlap = placedPositions.some(pos => {
                        const distance = calculateDistance(pos.x, pos.y, x, y);
                        return distance < bubbleSize * 0.8; // Adjust threshold as necessary for annotations
                    });
    
                    // Check if it overlaps with any bubbles
                    const bubbleOverlap = placedPositions.some(pos => {
                        const distance = calculateDistance(pos.x, pos.y, x, y);
                        return distance < bubbleSize; // Adjust threshold for bubbles
                    });
    
                    // If either overlaps, return true
                    return annotationOverlap || bubbleOverlap;
                };
    
                // Apply the y offset and check for overlap with bubbles and annotations
                let currentX = x; // Keep the x position same for each annotation
                let currentY = y + yOffset; // Apply y offset (up/down)
    
                // If it overlaps with existing bubbles or annotations, skip this annotation
                if (isOverlapping(currentX, currentY, bubbleSize)) {
                    return;
                }
    
                // No overlap, so add the position
                placedPositions.push({ x: currentX, y: currentY });
    
                // Add the annotation to the list
                annotations.push({
                    x: x,
                    y: y,
                    text: `<b>${combinedLabel}</b>`, // Display combined label
                    showarrow: !labelFitsInsideBubble, // Show arrow if label is outside
                    arrowhead: 1,
                    arrowwidth: 2,
                    ax: labelFitsInsideBubble ? 10 : 30, // Offset if label is too big
                    ay: labelFitsInsideBubble ? yOffset : -yOffset, // Adjust vertical offset if label is too big
                    font: { size: labelFitsInsideBubble ? 12 : 10, color: labelFitsInsideBubble ? "white" : "black", weight: "800" },
                    bgcolor: labelFitsInsideBubble ? "transparent" : "white", // Transparent if label fits
                    bordercolor: labelFitsInsideBubble ? "transparent" : "black",
                    borderradius: 10, // Rounded corners
                    xanchor: isShortLabel ? "center" : undefined,
                    yanchor: isShortLabel ? "middle" : undefined,
                    arrowcolor: "black", // Set arrow color
                });
            });
    
            return annotations;
        }
        return [];
    };

Here i want to remove annotations when toggled over the label. Let me know if one can simply toggle the legend and remove the associated annotations and text on the bubble. How can we control legend and text according to the toggle legend button.

Upvotes: 0

Views: 9

Answers (0)

Related Questions