diff --git a/site-config.js b/site-config.js index a56d75d..0319641 100644 --- a/site-config.js +++ b/site-config.js @@ -34,6 +34,8 @@ var site_config = { /* define column names to pull data from */ linkField: 'url', countryField: 'country', + statusField: 'status', + capacityField: 'capacity', locationColumns:{ lat: 'lat', lng: 'lng' diff --git a/src/site.js b/src/site.js index 62475fb..e457075 100644 --- a/src/site.js +++ b/src/site.js @@ -319,16 +319,18 @@ function addLayers() { ]; } + let interpolateExpression = ["linear"]; + if (config.interpolateExponent) { + interpolateExpression = ["exponential", config.interpolateExponent]; + } paint['circle-radius'] = [ "interpolate", ["linear"], ["zoom"], -// 1, ["interpolate", ["exponential", 1.5], - - 1, ["interpolate", ["linear"], + 1, ["interpolate", interpolateExpression, ["get", config.capacityField], config.minCapacity, config.minRadius, config.maxCapacity, config.maxRadius ], - 10, ["interpolate", ["linear"], + 10, ["interpolate", interpolateExpression, ["get", config.capacityField], config.minCapacity, config.highZoomMinRadius, config.maxCapacity, config.highZoomMaxRadius @@ -357,11 +359,11 @@ function addLayers() { 'icon-allow-overlap': true, 'icon-size': [ "interpolate", ["linear"], ["zoom"], - 1, ['interpolate', ['linear'], + 1, ['interpolate', interpolateExpression, ["to-number", ["get", config.capacityField]], config.minCapacity, config.minRadius * 2 / 64, config.maxCapacity, config.maxRadius * 2 / 64], - 10, ['interpolate', ['linear'], + 10, ['interpolate', interpolateExpression, ["to-number", ["get", config.capacityField]], config.minCapacity, config.highZoomMinRadius * 2 / 64, config.maxCapacity, config.highZoomMaxRadius * 2 / 64] @@ -442,11 +444,7 @@ function addEvents() { (feature) => feature.properties[config.linkField] ); - map.setFilter('assets-highlighted', [ - 'in', - config.linkField, - ...links - ]); + setHighlightFilter(...links); if (selectedFeatures.length == 1) { //if (config.tiles) { @@ -457,11 +455,11 @@ function addEvents() { } else { var modalText = "
There are multiple " + config.assetFullLabel + " near this location. Select one for more details
" $('.modal-body').html(modalText); @@ -505,7 +503,7 @@ function buildFilters() { } for (let i=0; i`; + let check = `
`; check += '
'; check += `
`; check += (config.color.field == filter.field ? '' : ""); @@ -595,27 +593,30 @@ function filterTiles() { } }); - let filterExpression = []; + config.filterExpression = []; if (config.searchText.length >= 3) { let searchExpression = ['any']; config.selectedSearchFields.split(',').forEach((field) => { - searchExpression.push(['in', ['literal', config.searchText], ["get", field]]); + searchExpression.push(['in', ['literal', config.searchText], ['downcase', ["get", field]]]); }); - filterExpression.push(searchExpression); + config.filterExpression.push(searchExpression); } if (config.selectedCountries.length > 0) { - filterExpression.push(['in', ['get', config.countryField], ['literal', config.selectedCountries]]); + config.filterExpression.push(['in', ['get', config.countryField], ['literal', config.selectedCountries]]); } for (let field in filterStatus) { - filterExpression.push(['in', ['get', field], ['literal', filterStatus[field]]]); + config.filterExpression.push(['in', ['get', field], ['literal', filterStatus[field]]]); } - if (filterExpression.length > 0) { - filterExpression.unshift("all"); - map.setFilter('assets', filterExpression); + if (config.filterExpression.length == 0) { + config.filterExpression = null; } else { - map.setFilter('assets', null); + config.filterExpression.unshift("all"); } + map.setFilter('assets', config.filterExpression); + map.setFilter('assets-labels', config.filterExpression); + + map.on('idle', filterGeoJSON); } @@ -668,7 +669,7 @@ function updateSummary() { countFilteredFeatures(); config.filters.forEach((filter) => { for (let i=0; i { return {'title': header}}) - }); - - if ('rightAlign' in config.tableHeaders) { - config.tableHeaders.rightAlign.forEach((col) => { - $("#site-style").get(0).sheet.insertRule('td:nth-child(' + (config.tableHeaders.values.indexOf(col)+1) + ') { text-align:right }', 0); - }); - } - if ('noWrap' in config.tableHeaders) { - config.tableHeaders.noWrap.forEach((col) => { - $("#site-style").get(0).sheet.insertRule('td:nth-child(' + (config.tableHeaders.values.indexOf(col)+1) + ') { white-space: nowrap }', 0); - }); - } - $('#table-toggle').on("click", function() { if ($('#table-toggle-label').text().includes("Table view")) { $('#table-toggle-label').html("Map view "); @@ -704,6 +686,7 @@ function buildTable() { $('#sidebar').hide(); $('#table-container').show(); $('#basemap-toggle').hide(); + updateTable(true); } else { $('#table-toggle-label').html("Table view "); $('#map').show(); @@ -713,9 +696,38 @@ function buildTable() { } }); } -function updateTable() { - config.table.clear(); - config.table.rows.add(geoJSON2Table()).draw(); +function createTable() { + if ('rightAlign' in config.tableHeaders) { + config.tableHeaders.rightAlign.forEach((col) => { + $("#site-style").get(0).sheet.insertRule('td:nth-child(' + (config.tableHeaders.values.indexOf(col)+1) + ') { text-align:right }', 0); + }); + } + if ('noWrap' in config.tableHeaders) { + config.tableHeaders.noWrap.forEach((col) => { + $("#site-style").get(0).sheet.insertRule('td:nth-child(' + (config.tableHeaders.values.indexOf(col)+1) + ') { white-space: nowrap }', 0); + }); + } + config.table = $('#table').DataTable({ + data: geoJSON2Table(), + searching: false, + pageLength: 100, + fixedHeader: true, + columns: config.tableHeaders.labels.map((header) => { return {'title': header}}) + }); +} +function updateTable(force) { + // table create/update with large number of rows is slow, only do it if visible + if ($('#table-container').is(':visible') || force) { + if (config.table == null) { + createTable(); + } else if (config.tableDirty) { + config.table.clear(); + config.table.rows.add(geoJSON2Table()).draw(); + } + config.tableDirty = false; + } else { + config.tableDirty = true; + } } function geoJSON2Table() { return config.preLinkedGeoJSON.features.map(feature => { @@ -740,13 +752,28 @@ function geoJSON2Headers() { function enableModal() { config.modal = new bootstrap.Modal($('#modal')); $('#modal').on('hidden.bs.modal', function (event) { - map.setFilter('assets-highlighted', [ + setHighlightFilter(''); + }) +} +function setHighlightFilter(links) { + let filter; + if (config.filterExpression != null) { + filter = JSON.parse(JSON.stringify(config.filterExpression)); + filter.push([ '==', - config.linkField, - '' + ["get", config.linkField], + ["literal", links] ]); - }) + } else { + filter = [ + '==', + ["get", config.linkField], + ["literal", links] + ]; + } + map.setFilter('assets-highlighted',filter); } + function displayDetails(features) { if (typeof features == "string") { features = JSON.parse(features); @@ -817,12 +844,18 @@ function displayDetails(features) { } }); - let capacity = Object.assign(...config.filters[0].values.map(f => ({[f]: 0}))); - let count = Object.assign(...config.filters[0].values.map(f => ({[f]: 0}))); + let filterIndex = 0; + for (const[index, filter] of config.filters.entries()) { + if (filter.field == config.statusField) { + filterIndex = index; + } + } + let capacity = Object.assign(...config.filters[filterIndex].values.map(f => ({[f]: 0}))); + let count = Object.assign(...config.filters[filterIndex].values.map(f => ({[f]: 0}))); features.forEach((feature) => { - capacity[feature.properties['status']] += feature.properties['capacity']; - count[feature.properties['status']]++; + capacity[feature.properties[config.statusField]] += feature.properties[config.capacityField]; + count[feature.properties[config.statusField]]++; }); let detail_capacity = ''; @@ -849,11 +882,7 @@ function displayDetails(features) { '
' + '
'); - map.setFilter('assets-highlighted', [ - '==', - config.linkField, - features[0].properties[config.linkField] - ]); + setHighlightFilter(features[0].properties[config.linkField]); } function buildSatImage(features) { let location_arg = ''; @@ -887,11 +916,7 @@ function buildSatImage(features) { } function showAllPhases(link) { config.modal.hide(); - map.setFilter('assets-highlighted', [ - 'in', - config.linkField, - link - ]); + setHighlightFilter(link); var bbox = []; config.linked[link].forEach((feature) => { var feature_lng = Number(feature.geometry.coordinates[0]); diff --git a/trackers/integrated/config.js b/trackers/integrated/config.js index e4ae07f..4c6b2ce 100644 --- a/trackers/integrated/config.js +++ b/trackers/integrated/config.js @@ -18,14 +18,15 @@ var config = { 'wind': 'green' } }, - minRadius: 2, + minRadius: 1, maxRadius: 10, highZoomMinRadius: 4, highZoomMaxRadius: 32, + interpolateExponent: 1.5, filters: [ { field: 'Type', - values: ['coal','oilgas','nuclear','geothermal','hydro','bioenergy','solar','wind'], + values: ['coal','oil/gas','nuclear','geothermal','hydro','bioenergy','solar','wind'], primary: true }, { @@ -35,7 +36,9 @@ var config = { } ], nameField: 'Plant/project name', + statusField: 'Status', capacityField: 'Capacity (MW)', + capacityLabel: 'Capacity (MW)', linkField: 'Wiki URL', countryField: 'Country', searchFields: { 'Project': ['Plant/project name'],