MediaWiki:DataMaps.js: Difference between revisions
Jump to navigation
Jump to search
Site gadget for the interactive maps: permanent name labels beside every marker |
Labels: tag by group, hide minor-group labels when zoomed far out |
||
| Line 1: | Line 1: | ||
/** | /** | ||
* Interactive maps (Extension:DataMaps) site script. | * Interactive maps (Extension:DataMaps) site script. | ||
* Binds a permanent name label to every marker so the maps read like the printed ones. | * Binds a permanent name label to every marker so the maps read like the printed ones, | ||
* and hides labels of the busier groups (towns, ruins, wilds) while zoomed far out. | |||
* Styling lives in MediaWiki:DataMaps.css (.dn-map-label). | * Styling lives in MediaWiki:DataMaps.css (.dn-map-label). | ||
*/ | */ | ||
mw.loader.using( 'ext.datamaps.bootstrap' ).then( function () { | mw.loader.using( 'ext.datamaps.bootstrap' ).then( function () { | ||
var MINOR_GROUPS = [ 'town', 'ruin', 'wilds', 'rumour' ], | |||
FAR_ZOOM = -1.25; // below this (map px per screen px > ~2.4) minor labels are hidden | |||
mw.dataMaps.registerMapAddedHandler( function ( map ) { | mw.dataMaps.registerMapAddedHandler( function ( map ) { | ||
var isMini = map.rootElement.classList.contains( 'ext-datamaps-mini-layout' ); | var isMini = map.rootElement.classList.contains( 'ext-datamaps-mini-layout' ); | ||
| Line 10: | Line 14: | ||
map.on( 'markerReady', function ( marker ) { | map.on( 'markerReady', function ( marker ) { | ||
var state = marker.apiInstance && marker.apiInstance[ 2 ], | var state = marker.apiInstance && marker.apiInstance[ 2 ], | ||
size, offsetX; | group = marker.attachedLayers && marker.attachedLayers[ 0 ], | ||
size, offsetX, cls; | |||
if ( !state || !state.label || typeof marker.bindTooltip !== 'function' ) { | if ( !state || !state.label || typeof marker.bindTooltip !== 'function' ) { | ||
return; | return; | ||
| Line 17: | Line 22: | ||
size = marker.options && marker.options.icon && marker.options.icon.options.iconSize; | size = marker.options && marker.options.icon && marker.options.icon.options.iconSize; | ||
offsetX = size ? ( Array.isArray( size ) ? size[ 0 ] : size.x || 40 ) / 2 + 2 : 12; | offsetX = size ? ( Array.isArray( size ) ? size[ 0 ] : size.x || 40 ) / 2 + 2 : 12; | ||
cls = 'dn-map-label dn-map-label-g-' + ( group || 'none' ); | |||
if ( isMini ) { | |||
cls += ' dn-map-label-mini'; | |||
} | |||
if ( MINOR_GROUPS.indexOf( group ) !== -1 ) { | |||
cls += ' dn-map-label-minor'; | |||
} | |||
marker.bindTooltip( state.label, { | marker.bindTooltip( state.label, { | ||
permanent: true, | permanent: true, | ||
| Line 23: | Line 35: | ||
interactive: false, | interactive: false, | ||
opacity: 1, | opacity: 1, | ||
className: | className: cls | ||
} ); | } ); | ||
} ); | |||
// Zoom tier → data attribute the CSS keys off. | |||
map.on( 'leafletLoaded', function () { | |||
var leafletMap = map.viewport && map.viewport.getLeafletMap(); | |||
if ( !leafletMap ) { | |||
return; | |||
} | |||
function updateTier() { | |||
map.rootElement.dataset.dnLabelTier = leafletMap.getZoom() < FAR_ZOOM ? 'far' : 'near'; | |||
} | |||
leafletMap.on( 'zoomend', updateTier ); | |||
updateTier(); | |||
} ); | } ); | ||
} ); | } ); | ||
} ); | } ); | ||
Revision as of 18:59, 29 August 2026
/**
* Interactive maps (Extension:DataMaps) site script.
* Binds a permanent name label to every marker so the maps read like the printed ones,
* and hides labels of the busier groups (towns, ruins, wilds) while zoomed far out.
* Styling lives in MediaWiki:DataMaps.css (.dn-map-label).
*/
mw.loader.using( 'ext.datamaps.bootstrap' ).then( function () {
var MINOR_GROUPS = [ 'town', 'ruin', 'wilds', 'rumour' ],
FAR_ZOOM = -1.25; // below this (map px per screen px > ~2.4) minor labels are hidden
mw.dataMaps.registerMapAddedHandler( function ( map ) {
var isMini = map.rootElement.classList.contains( 'ext-datamaps-mini-layout' );
map.on( 'markerReady', function ( marker ) {
var state = marker.apiInstance && marker.apiInstance[ 2 ],
group = marker.attachedLayers && marker.attachedLayers[ 0 ],
size, offsetX, cls;
if ( !state || !state.label || typeof marker.bindTooltip !== 'function' ) {
return;
}
// Sit the label just right of the icon (icons are anchored at their centre).
size = marker.options && marker.options.icon && marker.options.icon.options.iconSize;
offsetX = size ? ( Array.isArray( size ) ? size[ 0 ] : size.x || 40 ) / 2 + 2 : 12;
cls = 'dn-map-label dn-map-label-g-' + ( group || 'none' );
if ( isMini ) {
cls += ' dn-map-label-mini';
}
if ( MINOR_GROUPS.indexOf( group ) !== -1 ) {
cls += ' dn-map-label-minor';
}
marker.bindTooltip( state.label, {
permanent: true,
direction: 'right',
offset: [ offsetX, 0 ],
interactive: false,
opacity: 1,
className: cls
} );
} );
// Zoom tier → data attribute the CSS keys off.
map.on( 'leafletLoaded', function () {
var leafletMap = map.viewport && map.viewport.getLeafletMap();
if ( !leafletMap ) {
return;
}
function updateTier() {
map.rootElement.dataset.dnLabelTier = leafletMap.getZoom() < FAR_ZOOM ? 'far' : 'near';
}
leafletMap.on( 'zoomend', updateTier );
updateTier();
} );
} );
} );