Skip to content

Commit

Permalink
Add patterns
Browse files Browse the repository at this point in the history
  • Loading branch information
slowe committed Feb 29, 2024
1 parent 3aff98a commit b22c64c
Show file tree
Hide file tree
Showing 3 changed files with 143 additions and 18 deletions.
121 changes: 116 additions & 5 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,6 @@ <h2>A basic hexmap</h2>
OI.ready(function(){
// Attach our hexmap to <div id="hexmap1"></div>
hex = new OI.hexmap(document.getElementById('hexmap1'),{
'labels': { 'show': true },
// Define the HexJSON - https://open-innovations.org/projects/hexmaps/hexjson
'hexjson':{
"layout":"odd-r",
Expand All @@ -211,13 +210,13 @@ <h2>Styling hexes and labels</h2>
#hexmap2 { height: 500px; width: 100%; animation-duration: 0.3s; }
#hexmap2 .hex-cell { stroke: white; stroke-width: 2; transition: fill 0.3s ease-in, stroke 0.3s ease-in, stroke-width 0.3s ease-in; }
/* Make the hexagon larger when hovered */
#hexmap2 .hex-cell.hover { stroke-width: 4px; transform: scale(1.75); }
#hexmap2 .hover path { stroke-width: 4px; transform: scale(1.75); }
/* Set the on and off styles for the text labels */
#hexmap2 .hex-label tspan.on { display: none; }
#hexmap2 .hex-label tspan.off { display: block; }
#hexmap2 .hex-label tspan.big { font-weight: bold; font-size: 1.2em; }
#hexmap2 .hex-label.hover tspan.on { display: block; }
#hexmap2 .hex-label.hover tspan.off { display: none; }
#hexmap2 .hover .hex-label tspan.on { display: block; }
#hexmap2 .hover .hex-label tspan.off { display: none; }
</style>
<figure>
<div id="hexmap2"></div>
Expand Down Expand Up @@ -301,7 +300,7 @@ <h2>Using external data, adding tooltips, styling boundaries</h2>
<style>
#hexmap3 { height: 800px; width: 100%; margin-top: 1em; position: relative; animation-duration: 0.3s; }
#hexmap3 .hex-cell { stroke: black; stroke-width: 0; transition: fill 0.2s ease-in, stroke 0.2s ease-in, stroke-width 0.2s ease-in; }
#hexmap3 .hex-cell.hover { stroke-width: 4px; }
#hexmap3 .hover path { stroke-width: 4px; }
@media only screen and (max-width: 700px) {
/* Don't bother with labels if it is too small */
#hexmap3 .hex-label { display: none; }
Expand Down Expand Up @@ -403,6 +402,118 @@ <h2>Using external data, adding tooltips, styling boundaries</h2>
</div>
</section>

<section class="example" id="ex4">
<h2>London 1895</h2>

<div class="example-code">
<style>
#ex4 figure {
font-family: "Times New Roman", serif;
background-color: #fdf4d6;
padding: 2rem;
position: relative;
color: #656058;
}
#ex4 figcaption {
margin-top: 2em;
text-align: center;
}
#hexmap4 {
aspect-ratio: 1 / 1;
position: relative;
margin: auto;
}
#hexmap4 tspan.name {
font-family: "Arial Black","Copperplate Gothic Bold","Times New Roman", serif;
}
#hexmap4 .hex-cell {
fill: #fdf4d6;
stroke: #656058;
stroke-width: 3px;
color: inherit;
}
#hexmap4 .hex-label .id, #hexmap4 .hex-label .name {
font-weight: 700;
fill: #656058;
text-shadow: 3px 3px 2px #fdf4d6, -3px 3px 1px #fdf4d6, -3px -3px 1px #fdf4d6, 3px -3px 2px #fdf4d6;
}
#hexmap4 .hex.big .hex-label { transform: scale(1.8); }
#hexmap4 .hex-label .id {
font-size: 250%;
font-family: "Times New Roman", serif;
}
#hexmap4 .hex-label .name {
font-size: 1.3em;
text-transform: uppercase;
}
#hexmap4 .hex.hover path, #hexmap4 .hex.hover .hex-label { transform: scale(1.3); }
#hexmap4 .hex.hover.big .hex-label { transform: scale(2.5); }
#hexmap4 .hex.hover path { stroke-width: 4px; fill: #656058!important; }
#hexmap4 .hover .id, #hexmap4 .hover .name { text-shadow: none; fill: #fdf4d6; }
.vertical path { fill: url(#verticalHatch)!important; }
.horizontal path { fill: url(#horizontalHatch)!important; }
</style>
<figure>
<div id="hexmap4">
</div>
<figcaption>London indexed by 2-mile hexagons</figcaption>
</figure>
<script>
OI.ready(function(){

// Create the hexagon layout
hex = new OI.hexmap(document.getElementById('hexmap4'),{
// The HexJSON layout
'hexjson': {
"layout":"odd-q",
"hexes": {
"A":{"n":"1a","q":0,"r":3,"label":"Horn<br>sey","class":"horizontal"},
"B":{"n":"2a","q":1,"r":2,"label":"Hack<br>ney","class":"horizontal"},
"C":{"n":"3a","q":2,"r":2,"label":"Old<br>Ford","class":"horizontal"},
"D":{"n":"4a","q":2,"r":1,"label":"Poplar","class":"horizontal"},
"E":{"n":"5a","q":2,"r":0,"label":"Dept<br>ford","class":"horizontal"},
"F":{"n":"6a","q":1,"r":-1,"label":"Peck<br>ham","class":"horizontal"},
"G":{"n":"7a","q":0,"r":-1,"label":"Brix<br>ton","class":"horizontal"},
"H":{"n":"8a","q":-1,"r":-1,"label":"Batter<br>sea","class":"horizontal"},
"I":{"n":"9a","q":-2,"r":0,"label":"Chel<br>sea","class":"horizontal"},
"J":{"n":"10a","q":-2,"r":1,"label":"Mary Le<br>Bone","class":"horizontal"},
"K":{"n":"11a","q":-2,"r":2,"label":"S<sup>t</sup> John'<sup>s</sup><br />Wood","class":"horizontal"},
"L":{"n":"12a","q":-1,"r":2,"label":"Kentish<br>Town","class":"horizontal"},
"M":{"n":"1","q":0,"r":2,"label":"Isling·<br>ton","class":"vertical"},
"N":{"n":"2","q":1,"r":1,"label":"Bethnal<br>Green","class":"vertical"},
"O":{"n":"3","q":1,"r":0,"label":"South·<br>wark","class":"vertical"},
"P":{"n":"4","q":0,"r":0,"label":"Kenning·<br>ton","class":"vertical"},
"Q":{"n":"5","q":-1,"r":0,"label":"Westmin·<br>ster","class":"vertical"},
"R":{"n":"6","q":-1,"r":1,"label":"St Pan·<br>cras","class":"vertical"},
"S":{"n":"","q":0,"r":1,"label":"The<br><tspan class='big'>City</tspan>","class":"big"}
}
},
'patterns': [
'<pattern id="verticalHatch" patternUnits="userSpaceOnUse" width="8" height="8"><path d="M0,0 l0,8 M0,4 l0,8" style="stroke:#656058;stroke-width:8;opacity:0.3;" /></pattern>',
'<pattern id="horizontalHatch" patternUnits="userSpaceOnUse" width="8" height="8"><path d="M0,0 l8,0 M4,0 l8,0" style="stroke:#656058;stroke-width:8;opacity:0.3;" /></pattern>'
],
'label': {
'show': true,
'format': function(txt,attr){
var tspans = '';
lines = (txt) ? [txt] : [];
lines = lines.concat(attr.hex.label.split(/<br ?\/?>/));
lineheight = attr['font-size']*1.5;
for(var i = 0; i < lines.length; i++){
tspans += '<tspan class="'+(txt && i==0 ? 'id':'name')+'" y="'+(attr.y + (i-lines.length/2+0.5)*lineheight).toFixed(3)+'" x="'+attr.x.toFixed(3)+'">'+lines[i].replace(/<sup>/g,'<tspan dy="-4" font-size="60%">').replace(/<\/sup>/g,'</tspan><tspan dy="4"> </tspan>')+'</tspan>';
}
return tspans;
}
},
// Once we've loaded the map the ready function is called
'ready':function(){
}
});
});
</script>
</div>
</section>

</div>
</div>
<footer>
Expand Down
37 changes: 25 additions & 12 deletions oi.hexmap.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
OI hex map in SVG
0.7.0:
- Draw boundary lines
- Add patterns
0.6.4:
- Remove browser tooltip
0.6.3:
Expand Down Expand Up @@ -175,22 +176,20 @@
style = clone(this.style['default']);
cls = "";
if(h.active) style.fill = h.fillcolour;
if(h.hover) cls += ' hover';
if(h.hover) h.hex.classList.add('hover');
if(h.selected){
for(p in this.style.selected){
if(this.style.selected[p]) style[p] = this.style.selected[p];
}
cls += ' selected';
}
if(this.mapping.hexes[r]['class']) cls += " "+this.mapping.hexes[r]['class'];
style['class'] = 'hex-cell'+cls;
setAttr(h.hex,style);
if(h.label) setAttr(h.label,{'class':'hex-label'+cls});
setAttr(h.path,style);
return h;
};

function setClip(h){
var sty = getComputedStyle(h.hex);
var sty = getComputedStyle(h.path);
var s = {};
if(sty.transform) s.transform = sty.transform;
if(s.transform=="none") s.transform = "";
Expand All @@ -208,12 +207,12 @@
// Keep selected items on top
for(var r in this.areas){
if(this.areas[r]){
if(this.areas[r].selected) add(this.areas[r].g,overlay);
if(this.areas[r].selected) add(this.areas[r].hex,overlay);
if(this.options.clip) setClip(this.areas[r]);
}
}
// Simulate a change of z-index by moving this element (hex and label) to the end of the SVG
add(this.areas[region].g,overlay);
add(this.areas[region].hex,overlay);
}
return this;
};
Expand Down Expand Up @@ -284,6 +283,15 @@
return this;
};

this.setClass = function(fn){
if(typeof fn==="function"){
for(var region in this.areas){
fn.call(this,region,this.areas[region]);
}
}
return this;
};

// Add events (mouseover, mouseout, click)
this.on = function(type,prop,fn){
if(typeof prop==="function" && !fn){
Expand Down Expand Up @@ -622,6 +630,7 @@
defs = svgEl('defs');
add(defs,svg);
id = (el.getAttribute('id')||'hex');
if(attr.patterns) defs.innerHTML += attr.patterns.join("");

// Create hexagons
if(this.mapping.hexes){
Expand All @@ -635,12 +644,15 @@
x = roundTo(h.x,3);
y = roundTo(h.y,3);
g = svgEl('g');
setAttr(g,{'data':r,'role':'listitem'});
g.classList.add('hex');
if(this.mapping.hexes[r].class) g.classList.add(this.mapping.hexes[r].class);
setAttr(g,{'data-id':r,'role':'listitem'});
hexes.appendChild(g);
path = svgEl('path');
setAttr(path,{'d':h.path,'class':'hex-cell hex','transform-origin':x+'px '+y+'px','data-q':this.mapping.hexes[r].q,'data-r':this.mapping.hexes[r].r});

g.appendChild(path);
this.areas[r] = {'g':g,'hex':path,'selected':false,'active':true,'data':this.mapping.hexes[r],'orig':h};
this.areas[r] = {'hex':g,'path':path,'selected':false,'active':true,'data':this.mapping.hexes[r],'orig':h};

// Attach events to our SVG group nodes
addEvent('mouseover',g,{type:'hex',hexmap:this,region:r,data:this.mapping.hexes[r],pop:this.mapping.hexes[r].p},events.mouseover);
Expand All @@ -662,16 +674,17 @@
label = svgEl('text');
// Add to DOM
g.appendChild(label);
label.innerHTML = this.options.formatLabel(this.mapping.hexes[r].n||this.mapping.hexes[r].msoa_name_hcl,{'x':h.x,'y':h.y,'hex':this.mapping.hexes[r],'size':this.properties.size,'font-size':parseFloat(getComputedStyle(label)['font-size'])});
setAttr(label,{'x':x,'y':y,'transform-origin':x+'px '+y+'px','dominant-baseline':'central','clip-path':'url(#'+this.areas[r].clipid+')','data-q':this.mapping.hexes[r].q,'data-r':this.mapping.hexes[r].r,'class':'hex-label','text-anchor':'middle','font-size':this.style['default']['font-size']+'px','title':(this.mapping.hexes[r].n || r),'_region':r});
label.innerHTML = this.options.formatLabel(this.mapping.hexes[r].n||this.mapping.hexes[r].msoa_name_hcl,{'x':h.x,'y':h.y,'hex':this.mapping.hexes[r],'size':this.properties.size,'font-size':parseFloat(this.style.default['font-size'])});
setAttr(label,{'x':x,'y':y,'transform-origin':x+'px '+y+'px','dominant-baseline':'central','data-q':this.mapping.hexes[r].q,'data-r':this.mapping.hexes[r].r,'class':'hex-label','text-anchor':'middle','font-size':this.style['default']['font-size']+'px','title':(this.mapping.hexes[r].n || r),'_region':r});
if(this.options.clip) setAttr(label,{'clip-path':'url(#'+this.areas[r].clipid+')'});
this.areas[r].label = label;
this.areas[r].labelprops = {x:x,y:y};
}
}

}
this.setHexStyle(r);
setAttr(this.areas[r].hex,{'stroke':this.style['default'].stroke,'stroke-opacity':this.style['default']['stroke-opacity'],'stroke-width':this.style['default']['stroke-width'],'title':this.mapping.hexes[r].n,'data-regions':r,'style':'cursor: pointer;'});
setAttr(this.areas[r].path,{'stroke':this.style['default'].stroke,'stroke-opacity':this.style['default']['stroke-opacity'],'stroke-width':this.style['default']['stroke-width'],'title':this.mapping.hexes[r].n,'data-regions':r,'style':'cursor: pointer;'});
}
}
}
Expand Down
Loading

0 comments on commit b22c64c

Please sign in to comment.