NewSignature / us-map

An interactive map of the United States using Raphaël
BSD 2-Clause "Simplified" License
280 stars 184 forks source link

Cannot set width of map based on percentage. #39

Open CaptainStack opened 10 years ago

CaptainStack commented 10 years ago

If you attempt to size the containing div with a percentage rather than an explicit pixel-based height/width, the map will be rendered in full size and cut off beyond the size of its containing div, rather than shrinking the map to fit into the div.

bobsawyer commented 10 years ago

Following for answers. It would also be nice if this were responsive. It's SVG -- it should resize nicely, yes? Being able to set the width of the container and having the map resize to the container would probably do the trick.

johnnyr209 commented 9 years ago

How would you make the map responsive?

bobsawyer commented 9 years ago

On lines 158-159, the container width is set via: var xscale = this.element.width()/WIDTH; var yscale = this.element.height()/HEIGHT;

But if you change those to: var xscale = WIDTH/this.element.width(); var yscale = HEIGHT/this.element.height();

Then the map scales to fit the container. I forked this and made those plus a few other minor tweaks and am using it on a corporate site rebuild. It's not 100% perfect but it works pretty well. https://github.com/bobsawyer/us-map-scale

johnnyr209 commented 9 years ago

it only seems to resize on refresh.

johnnyr209 commented 9 years ago

I ended up using @media queries in my style sheet to show and hide three different sizes of the map.

davesbrown commented 9 years ago

Can you provide an example of how you styled? I can't seem to get it to resize on refresh or @media queries.

johnnyr209 commented 9 years ago

in my header file

<script type="text/javascript">
$(document).ready(function() {

    $('#map-large').usmap({

stateStyles: {fill: '#999999', 'stroke' : '#FFFFFF'},
stateHoverStyles: {fill: '#e4701e'},

showLabels: false,

labelBackingStyles: {
        fill: '#999999',
        stroke: '#FFFFFF',
        'stroke-width': 1,
        'stroke-linejoin': 'round',
        scale: [1, 1]
      },
labelTextStyles: {
      fill: '#FFFFFF',
        'stroke': 'none',
        'font-size': '10px'
      },
labelBackingHoverStyles: {
        fill: '#e4701e',
        stroke: '#FFFFFF'
      }
        });

  });
</script>

<script type="text/javascript">
$(document).ready(function() {

    $('#map-medium').usmap({

stateStyles: {fill: '#999999', 'stroke' : '#FFFFFF'},
stateHoverStyles: {fill: '#e4701e'},

showLabels: false,

labelBackingStyles: {
        fill: '#999999',
        stroke: '#FFFFFF',
        'stroke-width': 1,
        'stroke-linejoin': 'round',
        scale: [1, 1]
      },
labelTextStyles: {
      fill: '#FFFFFF',
        'stroke': 'none',
        'font-size': '10px'
      },
labelBackingHoverStyles: {
        fill: '#e4701e',
        stroke: '#FFFFFF'
      }
        });

  });
</script>

<script type="text/javascript">
$(document).ready(function() {

    $('#map-small').usmap({

stateStyles: {fill: '#999999', 'stroke' : '#FFFFFF'},
stateHoverStyles: {fill: '#e4701e'},

showLabels: false,

labelBackingStyles: {
        fill: '#999999',
        stroke: '#FFFFFF',
        'stroke-width': 1,
        'stroke-linejoin': 'round',
        scale: [1, 1]
      },
labelTextStyles: {
      fill: "#FFFFFF",
        'stroke': 'none',
        'font-size': '10px'
      },
labelBackingHoverStyles: {
        fill: '#e4701e',
        stroke: '#FFFFFF'
      }
        });
  });
</script>

in my css

@media (min-width: 1071px){
#map-large {
    width:800px;
    height:600px;
    display:block;
    }
#map-medium {
    width:600px;
    height:400px;
    display:none;
    }
#map-small {
    width:300px;
    height:200px;
    display:none;
    }
}
@media (max-width: 1070px){
#map-large {
    width:800px;
    height:600px;
    display:block;
    }
#map-medium {
    width:600px;
    height:400px;
    display:none;
    }
#map-small {
    width:300px;
    height:200px;
    display:none;
    }
}
@media (max-width: 835px){
#map-large {
    width:800px;
    height:600px;
    display:none;
    }
#map-medium {
    width:600px;
    height:400px;
    display:block;
    }
#map-small {
    width:300px;
    height:200px;
    display:none;
    }
}
@media (max-width: 520px){
#map-large {
    width:800px;
    height:600px;
    display:none;
    }
#map-medium {
    width:600px;
    height:400px;
    display:none;
    }
#map-small {
    width:400px;
    height:200px;
    display:block;
    }
}
davesbrown commented 9 years ago

Thank you, I did get it to work with refreshing. I was starting to think that I would have to have an instance of each size map to respond to, sure enough with your answer.

eweisbrot commented 9 years ago

@CaptainStack

I currently have my map width and height set using pixels as opposed to percentages, but the map doesn't resize for smaller resolutions such as iPhones. Has any responsive functionality been added for this map? You can see the map on the page here: http://www.jwsuretybonds.com/

CaptainStack commented 9 years ago

@eweisbrot Sorry, I have not added any new features to my fork of this repo for some time now. I had a few things I wanted to add, but this was not one of them. If I eventually get back to it, I would implement those features first, and take a look at responsive/mobile support next.

eweisbrot commented 9 years ago

@CaptainStack No problem. From what I understand in your first comment above, shouldn't the map in the link below shrink for small resolutions since it's width/height is in explicit pixels?

http://www.jwsuretybonds.com/

CaptainStack commented 9 years ago

@eweisbrot I don't believe that kind of functionality exists. You can try with a percentage-based width, but my recollection is that it doesn't work. Explicit pixels almost definitely won't work. I'm sure there's a way to trick it into behaving how you want it to, but it'd take some time and know-how.

n3dwards commented 9 years ago

I was able to achieve some responsive functionality by overwriting some things via JS after the map loads. I prefer this to modifying any vendor files in my projects.

First: you can set some custom CSS to make the #map element width: 100% !important; and svg element to width: 100%; These can be applied via an external CSS file, which apply before the map is loaded.

Second: After initializing the map via your $('#map').usmap() call, do the following: $('#map').css('height', 'auto'); $('#map svg').removeAttr('height'); The height: auto; needs to be applied after the map is loaded and the removal of the height attribute on the svg obviously needs to be done with JS.

This worked for me to make the map svg fully responsive and maintain aspect ratio. I haven't tested this in multiple browsers yet but it works in Chrome. Also, forgive me for being unfamiliar with markdown, I don't comment much.

lsterling03 commented 9 years ago

@n3dwards -- I tried this but had no luck. Do you happen to have an example you could show of how you made this work? Here's the code I tried:

<style>    
#map{width:100%!important}
#map svg {width:100%}
</style>

<script>
$(document).ready(function() {

$('#map').usmap();

$('#map').css('height', 'auto');
$('#map svg').removeAttr('height');

});
</script>

Did you do anything more than that? It looks like the 100% width isn't being honored, and when setting the height to auto, the map is only about 100px tall.