SuzukiBlue
SuzukiBlue

Reputation: 135

D3 map - excluding a polygon from hovering

In a follow up to my previous question I am trying to adopt to my needs this great example of a map (working with this dataset) and opening a custom tooltip upon hovering.

I would like to exclude from hovering some states.

I want them to appear on a map but as gray and non-responsive.

If I were working with svg path I would define a different css class for polygons/states with hovering and a different class just for the non-responsive.

I don't know how to do it in this case where my paths are encapsulated in a variable (dataset).

function(){
var uStatePaths={id:"HI",n:"Hawaii",d:"M233.08751,(...),554.06663Z"}, (...)
{id:"VT",n:"Vermont",d:"M844.48416,(...),154.05791Z"}, (...)

Upvotes: 0

Views: 335

Answers (2)

tarulen
tarulen

Reputation: 2100

First of all, you need a way to say if a given state is gray or active. The direct way to do that is to add an active field in your data, which is either trueor false.

Then, you draw the map as before (using uStates.draw). After that, you can paint the inactive states in gray and remove the mouseover and mouseout events as follows:

  d3.selectAll(".state") //select all state objects
    .filter(function(d) { return !data[d.id].active }) //keep only inactives:
          //d.id  is the state id, 
          //data[d.id]  fetches your piece of data related to this state, and     
          //!data[d.id].active  gives the negation of the newly created active flag
    .style("fill", function(d){ return "#888" }) // paint in gray
    .on("mouseover", null) //remove mouseover events
    .on("mouseout", null); //remove mouseout events

Upvotes: 1

Alvaro Montoro
Alvaro Montoro

Reputation: 29655

You can tweak the file uStates.js to achieve what you want. Create a duplicate of the draw() method and apply some changes:

  • Pass a list of the states IDs that you want to "disable".
  • If the ID of the state is in the list, instead of using the defined fill, use a "disabled gray" color.
  • In the event controllers, check if the state ID is in the list; and if it is, don't apply the changes (as the state will be "disabled").

The function would be like this:

// notice the new parameter "list" that will contain the disabled states
uStates.drawSpecial = function(id, data, toolTip, list){        

    function mouseOver(d){
      // only show the tooltip if the state is not in the disabled list
      if (list.indexOf(d.id) < 0) {
        d3.select("#tooltip").transition().duration(200).style("opacity", .9);      
        d3.select("#tooltip").html(toolTip(d.n, data[d.id]))  
            .style("left", (d3.event.pageX) + "px")     
            .style("top", (d3.event.pageY - 28) + "px");
        }
    }

    function mouseOut(){
        d3.select("#tooltip").transition().duration(500).style("opacity", 0);      
    }

    d3.select(id).selectAll(".state")
        .data(uStatePaths)
        .enter()
        .append("path")
        .attr("class","state")
        .attr("d",function(d){ return d.d;})
        // if the state id is in the list, select gray instead of the state color
        .style("fill",function(d){ return list.indexOf(d.id) >= 0 ? "#dddddd" : data[d.id].color; })
        .on("mouseover", mouseOver).on("mouseout", mouseOut);
} 

Then instead of calling the draw method, call your own personlized drawSpecial method. For example, in a similar code to the one found in the tutorial you linked, if you want to disable Texas (TX) and Vermont (VT), you'd call the function like this:

uStates.draw("#statesvg", sampleData, tooltipHtml, ['TX', 'VT']);

Upvotes: 1

Related Questions