async generateQuadrat(id: any, current_data: any, dimensions?: any) {
d3.selectAll(#${id} > svg
).remove();
console.log(current_data);
if (!dimensions) {
dimensions = {
width: document.getElementById(id).offsetWidth,
height: document.getElementById(id).offsetHeight,
};
}
const margin = { top: 50, right: 20, bottom: 30, left: 50 },
width = dimensions.width - margin.left - margin.right,
height = dimensions.height - margin.top - margin.bottom;
const xAxisLabel = current_data.data.data.quadrant.x_axis.label;
const yAxisLabel = current_data.data.data.quadrant.y_axis.label;
const xAxisAdditionalLabel = current_data.data.data.quadrant.x_axis.additional_label;
const yAxisAdditionalLabel = current_data.data.data.quadrant.y_axis.additional_label;
const bubbleData = Object.values(current_data.data.data.bubble);
const quadrantData = current_data.data.data.quadrant.data;
const xRange = current_data.data.data.quadrant.x_axis.range;
const yRange = current_data.data.data.quadrant.y_axis.range;
const xMid = (xRange[0] + xRange[1]) / 2;
const yMid = (yRange[0] + yRange[1]) / 2;
const svg = d3.select(`#${id}`)
.append("svg")
.attr("width", dimensions.width + margin.left + margin.right)
.attr("height", dimensions.height + margin.top + margin.bottom)
.style("position", "relative")
.append("g")
.attr("transform", `translate(${margin.left},${margin.top})`);
const x = d3.scalePoint()
.domain(bubbleData.map((d: any) => d.x))
.range([0, width])
.padding(0.5);
svg.append("g")
.attr("transform", `translate(0, ${height})`)
.call(d3.axisBottom(x))
.append("text")
.attr("x", width)
.attr("y", -5) // Adjust this value to position near max x
.attr("text-anchor", "end")
.attr("font-size", "12px")
.attr("fill", "black")
.text(xAxisLabel);
const yMinValue = Math.min(...bubbleData.map((d: any) => d.y));
const yMaxValue = Math.max(...bubbleData.map((d: any) => d.y));
const y = d3.scaleLinear()
.domain([yMinValue, yMaxValue])
.range([height, 0]);
svg.append("g")
.call(d3.axisLeft(y))
.append("text")
.attr("transform", "rotate(-90)")
.attr("x", -height / 2)
.attr("y", -margin.left + 15)
.attr("dy", "0.71em")
.attr("text-anchor", "end")
.attr("font-size", "12px")
.attr("fill", "black")
.text(yAxisLabel);
const xQuadrant = d3.scaleLinear()
.domain(xRange)
.range([0, width]);
const yQuadrant = d3.scaleLinear()
.domain(yRange)
.range([height, 0]);
const quadrants = [
{ x1: 0, y1: 0, x2: width / 2, y2: height / 2, color: current_data.data.data.quadrant.colors.quadrant3 },
{ x1: width / 2, y1: 0, x2: width, y2: height / 2, color: current_data.data.data.quadrant.colors.quadrant4 },
{ x1: 0, y1: height / 2, x2: width / 2, y2: height, color: current_data.data.data.quadrant.colors.quadrant1 },
{ x1: width / 2, y1: height / 2, x2: width, y2: height, color: current_data.data.data.quadrant.colors.quadrant2 }
];
quadrants.forEach(quadrant => {
svg.append("rect")
.attr("x", quadrant.x1)
.attr("y", quadrant.y1)
.attr("width", quadrant.x2 - quadrant.x1)
.attr("height", quadrant.y2 - quadrant.y1)
.attr("fill", quadrant.color)
.attr("opacity", 0.3);
});
svg.append("line")
.attr("x1", width / 2)
.attr("y1", 0)
.attr("x2", width / 2)
.attr("y2", height)
.attr("stroke", "#000")
.attr("stroke-width", 1);
svg.append("line")
.attr("x1", 0)
.attr("y1", height / 2)
.attr("x2", width)
.attr("y2", height / 2)
.attr("stroke", "#000")
.attr("stroke-width", 1);
// Add quadrant descriptions
quadrantData.forEach((d: any, i: number) => {
let xPosition, yPosition;
switch (i) {
case 0:
xPosition = width / 4;
yPosition = height - height / 4;
break;
case 1:
xPosition = (3 * width) / 4;
yPosition = height - height / 4;
break;
case 2:
xPosition = (3 * width) / 4;
yPosition = height / 4;
break;
case 3:
xPosition = width / 4;
yPosition = height / 4;
break;
}
// Add temporary text to measure width
const tempText = svg.append("text")
.attr("x", xPosition)
.attr("y", yPosition)
.attr("text-anchor", "middle")
.attr("font-size", "12px")
.attr("font-family", "sans-serif")
.attr("fill", "black")
.text(d.description);
const bbox = tempText.node().getBBox(); // Get the bounding box of the text
const padding = 10; // Padding around the text
// Background rectangle
svg.append("rect")
.attr("x", xPosition - (bbox.width / 2) - padding)
.attr("y", yPosition - (bbox.height / 2) - padding)
.attr("width", bbox.width + 2 * padding)
.attr("height", bbox.height + 2 * padding)
.attr("fill", "white")
.attr("stroke", "black")
.attr("stroke-width", 1)
.attr("rx", 5)
.attr("ry", 5);
// Text
tempText.remove(); // Remove temporary text
svg.append("text")
.attr("x", xPosition)
.attr("y", yPosition)
.attr("text-anchor", "middle")
.attr("font-size", "12px")
.attr("font-family", "sans-serif")
.attr("fill", "black")
.text(d.description);
});
// Additional label for the y-axis, above the center y-axis
svg.append("text")
.attr("x", margin.left + (height) + 20) // Center horizontally along the y-axis
.attr("y", -margin.top / 2) // Position above the y-axis
.attr("text-anchor", "middle")
.attr("font-size", "12px")
.attr("fill", "black")
.text(yAxisAdditionalLabel);
// Additional label for the x-axis, to the right side of the center x-axis
svg.append("text")
.attr("x", width / 2 + (width / 2 - margin.right) - 35) // End of the center x-axis considering margins
.attr("y", height / 2 + margin.bottom - 10) // Adjust y position as needed
.attr("text-anchor", "middle")
.attr("font-size", "12px")
.attr("fill", "black")
.text(xAxisAdditionalLabel);
const minBubbleSize = 4;
const maxBubbleSize = 40;
const bubbleSizeScale = d3.scaleLinear()
.domain([d3.min(bubbleData, (d: any) => d.size), d3.max(bubbleData, (d: any) => d.size)])
.range([minBubbleSize, maxBubbleSize]);
const tooltip = d3.select('body')
.append('div')
.attr('id', 'tooltip')
.style('position', 'absolute')
.style('opacity', 0)
.style('background-color', '#333')
.style('color', '#fff')
.style('border', '1px solid #fff')
.style('border-radius', '5px')
.style('padding', '5px')
.style('pointer-events', 'none')
.style('z-index','100');
svg.selectAll("circle")
.data(bubbleData)
.enter()
.append("circle")
.attr("cx", (d: any) => x(d.x))
.attr("cy", (d: any) => y(d.y))
.attr("r", (d: any) => bubbleSizeScale(d.size))
.style("fill", "#69b3a2")
.style("opacity", 0.8)
.attr("stroke", "black")
.on('mouseover', function(event, d:any) {
d3.select(`${id}`)
.transition().duration(200)
.style('opacity', 1).text(d.x)
})
.on('mousemove', function(event:any) {
d3.select(`${id}`)
.style('left', event.pageX + 'px')
.style('top', event.pageY + 'px')
})
.on('mouseout', function() {
d3.select(`${id}`).style('opacity', 0)
});
svg.selectAll("text.bubble-label")
.data(bubbleData)
.enter()
.append("text")
.attr("class", "bubble-label")
.attr("x", (d: any) => x(d.x))
.attr("y", (d: any) => y(d.y))
.attr("dy", ".35em")
.attr("text-anchor", "middle")
.attr("font-size", "10px")
.text((d: any) => d.legend);
} While mouse hover the mouseover gets called and executes but the tooltip didnt show up
This is my function for bubble chart along with quadrant’s. I had this tooltip issue for last 2 days. Help me to get out of this one. The function of tool tip mouseover and mousemove gets triggered and data flow was correct. But the tool tip dosent come.
New contributor
vijai is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.