MediaWiki:DataMaps.js: Difference between revisions

From Deez Nuts' Sword Coast Campaign
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: 'dn-map-label' + ( isMini ? ' dn-map-label-mini' : '' )
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();
		} );
	} );
} );