0

I'm using the datamaps library for d3 and I have asked the question unsuccessfully there on github so I wanted to cross-post it here.

What I'm trying to do is to visualise two measures – Income Inequality (Gini) and GDP per capita – in one world map and make it possible to switch between the two views.

I am almost there. Here is my example.

On the top you can choose which measure to look at and the updating works – except that the updated map is plotted underneath the previous one and not on top. This is happening even though I'm referring to the same id with both maps.

What am I missing? Thanks for helping me!

EDIT: I managed to get it a little bit nicer – here is the updated version – but the maps are still printed over and over again below the space where they should appear.

user2656065
  • 57
  • 1
  • 8
  • I haven't had a look at the code honestly, but why don't you change the fill of the countries instead of drawing maps over and over again? you could have the two color ranges triggered by the buttons and then applied to each country – tomtomtom Jun 12 '14 at 11:36
  • Thanks for your reply! I cannot do that for this chart because it's not just the fill of the countries (=visualised data) that changes. For the case you are referring to I do just this – [example](http://www.ourworldindata.org/roser/maps/ChildMortalitySince1950_childmortalityOrg/ChildMortalitySince1950_childmortalityOrg.html). In this case here it is also the bins, the legend, and the tooltip that change so I think I have to redraw the whole map. – user2656065 Jun 12 '14 at 14:45
  • legends with bins and so on could be appended or deleted by the events like .on click and such, so actually that could be an option. But yeah I was suggesting just because drawing a whole map over and over is not the best way to me, and maybe for older machines could slow down the browser – tomtomtom Jun 12 '14 at 15:04

1 Answers1

0

I made a lot of these same mistakes when I first used D3. You have to use an enter(), update(), exit() pattern. There are lots of good tutorials on how to do that. Fundamentally, your structure is not setup correctly and is going to give you trouble.

For your code, you want to do the following:

  1. Move the initial call to map() inside the map function.
  2. Nest the map() function inside another function where you config your variables. You need to do all your global data/variable defining here.
  3. Inside that config function, include d3.select(#radialbuttonname) and re run the map() function to update the chart on.click.
  4. Inside the map function, you need to create functions for .data().enter(), .data.exit().remove(), and .data().transition(). That will replace the same SVG map area with a new map rather than just appending more svg's below.
  5. You can change the tooltips and those other elements with if/then operators and remove() inside the map() function.

That should get you on your way..

Union find
  • 7,759
  • 13
  • 60
  • 111
  • Thanks so much for your helpful answer! I'll try to follow your advice as soon as I can and post the updated code. – user2656065 Jun 17 '14 at 22:52
  • I tried to follow your steps but I don't get ahead to be honest.. Is there some example where someone did something like this before? I'm sorry that I cannot provide a better answer here. – user2656065 Jun 18 '14 at 10:40
  • Sorry to ask but would you be able to help me a bit more? I don't understand what you mean by 'move the initial call to map() inside the map function'. – user2656065 Jun 18 '14 at 18:54
  • look for examples of the enter(), update() exit() structure. there are many. my explanation will be clearer once you get that approach. – Union find Jun 18 '14 at 19:52
  • I'll try! Maybe it is helpful to have the code available. Here is the example that I linked to above in a jsfiddle: http://jsfiddle.net/axammamax/Y2pTD/ – user2656065 Jun 18 '14 at 23:50