erincerol
erincerol

Reputation: 683

How to dynamically add circle with label?

I'm using d3 to create a map and add some data on it in. So far, I managed to draw circles based on the data that I pull from database. What I want to do is, when I mouseover one of those circle, create a new bigger circle with some text on it. I was able to draw the bigger circle but couldn't figure out how to add the label or text on it.

This is how I add circles to the map.

    for (var i = 0; i < data.length; i++) {
        var coordinates = projection([data[i]["Longitude"], data[i]["Latitude"]]);
        svg.append('svg:circle')
            .attr('cx', coordinates[0])
            .attr('cy', coordinates[1])
            .attr('r', 5)
            .attr('fill', 'black')
            .attr('class', 'pClass')
            .attr('id', data[i]["Id"])
            .attr('dataId', data[i]["DataId"])
            .on('mouseover', dataMouseover);
    }

Here is the mouseover event

    function dataMouseover() {
        var id = $(this).attr('id');
        var d= $.grep(data, function (e) { return e.Id == id; });
        var coordinates = projection([d[0]["Longitude"], d[0]["Latitude"]]);

        svg.append('svg:circle')
           .attr('cx', coordinates[0])
           .attr('cy', coordinates[1])
           .attr('r', 120)
           .attr('fill', 'darkblue')
           .attr('class', 'pClass')
           .attr('id', data[0]["Id"] + "popUp")
           .attr('dataId', plaques[0]["DataId"])
           .attr("stroke", "white")
           .attr("stroke-width", "5")
           .on('mouseout', function () {
                d3.select(this).remove();
        });
    }

So, I'm also removing the bigger circle when mouse is out. What I want is to put a text in that circle from the data while drawing it in there.

UPDATE: I updated my code to change current circle's radius instead of drawing new one.

        for (var i = 0; i < data.length; i++) {
            var coordinates = projection([data[i]["Longitude"], data[i]["Latitude"]]);
            svg.append('svg:circle')
            .attr('cx', coordinates[0])
            .attr('cy', coordinates[1])
            .attr('r', 5)
            .attr('fill', 'black')
            .attr('class', 'pClass')
            .attr('id', data[i]["Id"])
            .attr('dataId', data[i]["DataId"])
            .on('click', function () {
                $("#dialog").dialog('open');
            })
            .on('mouseover', function (data) {
                var sel = d3.select(this);
                sel.moveToFront();

                d3.select(this)
                .transition()
                .duration(200)
                .attr('fill', 'darkblue')
                .attr('r', 120)
                .attr('stroke', 'white')
                .attr('stroke-width', '5')
            })
            .on('mouseout', function () {
                d3.select(this)
                .transition()
                .duration(200)
                .attr('fill', 'black')
                .attr('r', 5)
                .attr('stroke', 'none')
                .attr('stroke-width', '0')
            });
        }

Still could use some guidance on how to use g element to cover both circle and text in my case.

Upvotes: 0

Views: 1363

Answers (1)

sir_thursday
sir_thursday

Reputation: 5409

You can't actually add text inside an svg circle. I discovered this to my own chagrin as well a few weeks ago. :\

Instead, encapsulate both the circle and the text inside a g element. Here's a link to a SO post explaining exactly how to do that: d3 add text to circle

Steps to going about doing this:

  1. On hover: Instead of appending a circle, first append a g element.
  2. Then append a circle element to that g element
  3. Then append a text element to that g element
  4. ??? (stylize the elements as you will...)
  5. Profit from having it look like the text is inside the circle!

Also: instead of redrawing the entire circle on mouseover, see if you can just change the r attr of the circle on mouseover. Might save you some code & make your app update a bit faster.

Upvotes: 2

Related Questions