diff --git a/changelog/index.html b/changelog/index.html index 9da903d..36dfbc7 100644 --- a/changelog/index.html +++ b/changelog/index.html @@ -77,6 +77,47 @@
Paleomagnetism.org 2 - Changelog
+ +
+
+ +
+
+
+ Change Summary +

Some new features were added for user convenience. Minor bugs were fixed. +

    +

    Features +

  • Added window to add some metadata to collections in the statistics portal. This can be used when exporting .pub files for sharing for literature data that cannot be submitted to the data library. +
  • Added satellite imagery to the geography portal (#53). +
+
    +

    Fixes +

  • Added new paper (Koymans et al., 2020) to the references page. +
  • Fixed JSON exporting in statistics portal mean directions tab. +
  • Fixed reading of input files in reversed order. The order is now as expected. +
  • Intensity plot in the interpretation portal now uses categories instead of numeric values. +
  • Size of charts in the interpretation portal has been increased. +
  • The PalPole description on the miscellaneous portal has been updated. +
  • A warning is now shown when the application is run in to beta mode. +
  • Map width in the geography portal has been reduced and bounds were removed (#51, #52). +
  • Fixed GPlates rotation files for plate ID "0" which is the same as "000" (#54) +
  • Fixed accidental swap of latitude, longitude in publication preview map. +
  • Fixed CTMD test not working for reversed directions. +
  • Added Remasoft (RS3) file format. +
  • Data library author information is now taken from DOI by default. +
  • Added age and generated country based on lat, lng to data library. +
  • Prevent linking to statistics/geography portal when no interpreted components are available. +
+ +
+
+
+ +

+

- Change Summary <20> + Change Summary

The release of Paleomagnetism 2.0.0 exists in parallel with the old application. The old version may have some additional features in the statistics portal that were removed in this version. This version of Paleomagnetism.org focuses on raw demagnetization data and its provenance, and may therefore be more limited in what it allows.

    Features diff --git a/collection/js/index.js b/collection/js/index.js index 450ddec..862ca28 100644 --- a/collection/js/index.js +++ b/collection/js/index.js @@ -18,8 +18,6 @@ function addMap(specimens) { var mapOptions = { "minZoom": 1, "maxZoom": 13, - "maxBounds": new L.latLngBounds(new L.latLng(-90, -180), new L.latLng(90, 180)), - "maxBoundsViscosity": 0.5, "attributionControl": true } diff --git a/css/style.css b/css/style.css index e6ea234..c275b5d 100644 --- a/css/style.css +++ b/css/style.css @@ -31,7 +31,10 @@ p { #wrapper { position: relative; + width: 80%; + margin: auto; } + .popover { min-width: 25%; } diff --git a/geography/index.html b/geography/index.html index a035569..fd1face 100644 --- a/geography/index.html +++ b/geography/index.html @@ -192,14 +192,24 @@

-
-
+
+
+ +
+ + +
+ +

+
diff --git a/geography/js/gplates.js b/geography/js/gplates.js index c414255..c4daed5 100644 --- a/geography/js/gplates.js +++ b/geography/js/gplates.js @@ -99,12 +99,12 @@ function readGPlatesRotation(ID, age) { } // Continue when we are referencing the fixed plate ID - while(ID !== "000") { + while(parseInt(ID) !== 0) { var plateData = GPlatesData[ID]; // Search input for matching plateID & age - for(var i = 0; i < plateData.length; i++) { + for(var i = 1; i < plateData.length; i++) { if(plateData[i].age < age) { diff --git a/geography/js/index.js b/geography/js/index.js index fe21664..090a0f4 100644 --- a/geography/js/index.js +++ b/geography/js/index.js @@ -18,20 +18,22 @@ function addMap() { */ const MAP_CONTAINER = "map"; - const TILE_LAYER = "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"; + const TILE_LAYER_DEFAULT = "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"; + const TILE_LAYER_ARCGIS = "https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}"; const VIEWPORT = new L.latLng(35, 0); // Set map options (bounds) var mapOptions = { "minZoom": 2, - "maxBounds": new L.latLngBounds(new L.latLng(-90, -180), new L.latLng(90, 180)), - "maxBoundsViscosity": 0.5, "attributionControl": true } // Create the map and tile layer map = L.map(MAP_CONTAINER, mapOptions).setView(VIEWPORT, 1); - L.tileLayer(TILE_LAYER).addTo(map); + + window.defaultLayer = L.tileLayer(TILE_LAYER_DEFAULT); + window.arcgisLayer = L.tileLayer(TILE_LAYER_ARCGIS); + toggleSatelliteLayer(); // Reload the map when the tab is focussed on $("#nav-apwp-tab").on("shown.bs.tab", map.invalidateSize.bind(map)); @@ -65,10 +67,10 @@ function createGridLayer(map) { */ return L.latlngGraticule({ - "opacity": 0.5, + "opacity": 1, "color": HIGHCHARTS_WHITE, - "fontColor": HIGHCHARTS_BLACK, - "font": "12px Helvetica", + "fontColor": HIGHCHARTS_WHITE, + "font": "12px Sans-Serif", "showLabel": true, "zoomInterval": [ {"start": 2, "end": 3, "interval": 30}, @@ -81,6 +83,18 @@ function createGridLayer(map) { } +function toggleSatelliteLayer() { + + if(document.getElementById("enable-satellite").checked) { + map.removeLayer(window.defaultLayer); + map.addLayer(window.arcgisLayer); + } else { + map.removeLayer(window.arcgisLayer); + map.addLayer(window.defaultLayer); + } + +} + function toggleGridLayer() { /* @@ -244,6 +258,7 @@ function registerEventHandlers() { document.getElementById("cutoff-selection").addEventListener("change", redrawCharts); document.addEventListener("keydown", keyboardHandler); document.getElementById("defaultCheck1").addEventListener("change", toggleGridLayer); + document.getElementById("enable-satellite").addEventListener("change", toggleSatelliteLayer); document.getElementById("calculate-reference").addEventListener("click", plotPredictedDirections); document.getElementById("defer-input").addEventListener("click", inputFileWrapper); diff --git a/interpretation/index.html b/interpretation/index.html index 6aede91..97450b3 100644 --- a/interpretation/index.html +++ b/interpretation/index.html @@ -125,6 +125,7 @@
Paleomagnetism.org 2 - Interpretation
+ @@ -190,7 +191,7 @@
Paleomagnetism.org 2 - Interpretation
-
+
@@ -215,10 +216,10 @@
Paleomagnetism.org 2 - Interpretation
-
+
-
+
diff --git a/interpretation/js/graphs.js b/interpretation/js/graphs.js index fe8d87c..8858405 100644 --- a/interpretation/js/graphs.js +++ b/interpretation/js/graphs.js @@ -108,6 +108,7 @@ function plotIntensityDiagram(hover) { var specimen = getSelectedSpecimen(); var intensities = new Array(); + var categories = new Array(); var hoverIndex = null; specimen.steps.forEach(function(step, i) { @@ -122,11 +123,11 @@ function plotIntensityDiagram(hover) { hoverIndex = intensities.length; } - // Get the treatment step as a number - var treatmentStep = extractNumbers(step.step); + // Use categories to stop mixing AF / TH + categories.push(step.step) intensities.push({ - "x": treatmentStep, + "x": i, "y": new Coordinates(step.x, step.y, step.z).length, "stepIndex": i }); @@ -217,7 +218,7 @@ function plotIntensityDiagram(hover) { "zIndex": 0 }); - createIntensityDiagram(hover, plotSeries); + createIntensityDiagram(hover, plotSeries, categories); } @@ -447,6 +448,7 @@ function plotZijderveldDiagram(hover) { "chart": { "animation": false, "id": "zijderveld-container", + "height": 500, "zoomType": "xy", "events": { "load": resetMarkerSize @@ -833,7 +835,7 @@ function resetMarkerSize() { } -function createIntensityDiagram(hover, series) { +function createIntensityDiagram(hover, series, categories) { /* * Function createIntensityDiagram @@ -894,6 +896,7 @@ function createIntensityDiagram(hover, series) { "formatter": intensityTooltip }, "xAxis": { + "categories": categories, "title": { "text": "Demagnetization steps" } @@ -1099,6 +1102,7 @@ function eqAreaProjection(hover) { Highcharts.chart(CHART_CONTAINER, { "chart": { "polar": true, + "height": 500, "events": { "load": resetMarkerSize }, diff --git a/interpretation/js/importing.js b/interpretation/js/importing.js index d443464..d0593a0 100644 --- a/interpretation/js/importing.js +++ b/interpretation/js/importing.js @@ -700,16 +700,8 @@ function importJR6(file) { var P3 = Number(line.slice(71, 74)); var P4 = Number(line.slice(74, 77)); - // Support for these orientation parameters - if(P1 !== 12 || P2 !== 0 || P3 !== 12) { - throw(new Exception("The AGICO orientation format is not supported. Supported: {12, 0, 12, *}.")); - } - - // P4 0 means (dip direction / dip) notation is used - // We use bedding strike so subtract 90 - if(P4 === 0) { - beddingStrike -= 90; - } + // Convert AGICO orientations + orientations = convertAgico(P1, P2, P3, P4, coreAzimuth, coreDip, beddingStrike, beddingDip); if(!specimenSortObject.hasOwnProperty(sampleName)) { specimenSortObject[sampleName] = { @@ -729,10 +721,10 @@ function importJR6(file) { "sample": sampleName, "name": sampleName, "volume": 10.0, - "beddingStrike": 0, - "beddingDip": 0, - "coreAzimuth": coreAzimuth, - "coreDip": coreDip, + "beddingStrike": orientations.beddingStrike, + "beddingDip": orientations.beddingDip, + "coreAzimuth": orientations.coreAzimuth, + "coreDip": orientations.coreDip, "interpretations": new Array() } @@ -750,6 +742,55 @@ function importJR6(file) { } +function convertAgico(P1, P2, P3, P4, coreAzimuth, coreDip, beddingStrike, beddingDip) { + + /* + * function convertAgico + * Converts AGICO orientation parameters to paleomagnetism.org parameters. + * + * P1 P2 P3 P4 + * 12 00 12 90 + * P1 means arrow is measured point to inside core (is fine) + * P2 0 Means dip of frontal side is measured (i.e. hade) (90 when horizontal) + * P3 Means measured in field (is fine) + * P4 90 means strike (RHR) and dip are measured.. same convention + */ + + if(P1 !== 12) { + throw("P1 parameter " + P1 + " not supported. Only the value {12} is supported."); + } + + // Is measuring + if(P2 === 0) { + coreDip = 90 - coreDip + } else if(P2 === 90) { + coreDip = coreDip; + } else { + throw("P2 parameter not supported. Only the values {0, 90} are supported."); + } + + if(P3 !== 12) { + throw("P3 parameter " + P3 + " not supported. Only the value {12} is supported."); + } + + // P4 90 means RHR.. otherwise dip direction so take - 90 + if(P4 === 0) { + beddingStrike = beddingStrike - 90; + } else if(P4 === 90) { + beddingStrike = beddingStrike; + } else { + throw("P4 parameter not supported. Only the values {0, 90} are supported."); + } + + return { + "coreAzimuth": coreAzimuth, + "coreDip": coreDip, + "beddingStrike": beddingStrike, + "beddingDip": beddingDip + } + +} + function importRS3(file) { /* @@ -779,25 +820,16 @@ function importRS3(file) { let P3 = Number(header.slice(116, 118)); let P4 = Number(header.slice(119, 121)); - // P1 P2 P3 P4 - // 12 00 12 90 - // P1 means arrow is measured point to inside core (is fine) - // P2 Means dip of frontal side is measured (i.e. hade) (90 when horizontal) - // P3 Means measured in field (is fine) - // P4 90 means strike (RHR) and dip are measured.. same convention - // Confirm AGICO format is supported - if(P1 !== 12 || P2 !== 0 || P3 !== 12 || P4 !== 90) { - throw(new Exception("The AGICO orientation format is not supported. Supported: {12, 0, 12, 90}.")); - } - // Core parameters (dip = hade) var coreAzimuth = Number(header.slice(74, 77).trim()) - var coreDip = 90 - Number(header.slice(79, 82).trim()); + var coreDip = Number(header.slice(79, 82).trim()); // Bedding parameters var beddingStrike = Number(header.slice(86, 90).trim()); var beddingDip = Number(header.slice(92, 95).trim()); + var orientations = convertAgico(P1, P2, P3, P4, coreAzimuth, coreDip, beddingStrike, beddingDip); + // Go over each demagnetization step var steps = lines.slice(2).map(function(line) { @@ -805,7 +837,7 @@ function importRS3(file) { // Intensity is in A/m var intensity = 1E6 * Number(line.slice(15, 27)); - var declination = Number(line.slice(29, 33)); + var declination = Number(line.slice(28, 33)); var inclination = Number(line.slice(34, 39)); var a95 = Number(line.slice(77, 80)) @@ -832,11 +864,11 @@ function importRS3(file) { "lithology": null, "sample": sampleName, "name": sampleName, - "volume": 10.0, - "beddingStrike": beddingStrike, - "beddingDip": beddingDip, - "coreAzimuth": coreAzimuth, - "coreDip": coreDip, + "volume": null, + "beddingStrike": orientations.beddingStrike, + "beddingDip": orientations.beddingDip, + "coreAzimuth": orientations.coreAzimuth, + "coreDip": orientations.coreDip, "interpretations": new Array() }); @@ -1320,7 +1352,7 @@ function importCaltech(file) { line = lines[i]; var stepType = line.slice(0, 2); - var step = line.slice(2, 6).trim() || "0"; + var step = line.slice(0, 6).trim() || "0"; var dec = Number(line.slice(46, 51)); var inc = Number(line.slice(52, 57)); diff --git a/js/table.js b/js/table.js new file mode 100644 index 0000000..246495d --- /dev/null +++ b/js/table.js @@ -0,0 +1,301 @@ +var Table = function(options) { + + /* Class Table + * Returns table with content including + * search & pagination functionality + */ + + // Some configuration + this.MINIMUM_ITEMS_PER_PAGE = 5; + this.MAXIMUM_NUMBER_PAGES = 10; + + this.header = options.header; + this.body = options.body; + this.search = options.search && this.body.length !== 0; + + // Generate the HTML for this table + var content = new Array(); + + // Add search box element + if(this.search) { + content = content.concat([ + "
", + " ", + "
", + " ", + "
", + "
", + " ", + "
", + ]) + } + + content.push("
") + + document.getElementById(options.id).innerHTML = content.join("\n"); + + // Get the search & content elements for this table + if(this.search) { + this.search = document.getElementById(options.id + "-search"); + this.search.addEventListener("input", this.draw.bind(this)); + } + + this.id = document.getElementById(options.id + "-content"); + + // Dynamically set the number of items per page + this.itemsPerPage = Math.max( + this.MINIMUM_ITEMS_PER_PAGE, + Math.ceil(this.body.length / this.MAXIMUM_NUMBER_PAGES) + ); + + // Keep track of the active page through pagination + this.activeIndex = 0; + + // Draw the initial table + this.draw(); + +} + +Table.prototype.draw = function() { + + /* Function Table.draw + * Redraws the table by creating the HTML + */ + + var filteredRows = this.body; + + if(this.search) { + + var searchTerm = this.search.value; + var regex = new RegExp("^.*" + searchTerm + ".*$", "i"); + var filteredRows = this.body.filter(function(x) { + for(var i = 0; i < x.length; i++) { + if(String(x[i]).match(regex)) { + return true; + } + } + }); + + } + + var pagination = this.generatePagination(filteredRows); + + this.id.innerHTML = [ + "", + this.generateTableHead(this.header), + this.generateTableBody(filteredRows), + "
", + pagination + ].join("\n"); + + // Add listeners to all the page buttons + Array.from(this.id.getElementsByClassName("page-item")).forEach(function(x) { + x.addEventListener("click", this.setActiveIndex.bind(this, x)); + }.bind(this)); + + // Enable tooltips + $('[data-toggle="tooltip"]').tooltip() + +} + +Table.prototype.generatePaginationList = function(list) { + + /* Function Table.generatePaginationList + * Generates all pagination buttons + */ + + // No results (1 page) + if(list.length === 0) { + return this.paginationItem(0) + } + + if(this.activeIndex * this.itemsPerPage > list.length) { + this.activeIndex = Math.floor(list.length / this.itemsPerPage); + } + + // Create the number of pages + return list.filter(function(_, i) { + return (i % this.itemsPerPage) === 0 + }.bind(this)).map(function(_, i) { + return this.paginationItem(i); + }.bind(this)).join("\n"); + +} + +Table.prototype.paginationItem = function(index) { + + /* Function Table.paginationItem + * Returns HTML representation of a pagination button + */ + + return "
  • " + (index + 1) + "
  • "; + +} + +Table.prototype.getMaxIndex = function() { + + if(this.body.length === this.itemsPerPage) { + return 0; + } else { + return Math.floor(this.body.length / this.itemsPerPage); + } + +} + +Table.prototype.setActiveIndex = function(context) { + + /* Function Table.setActiveIndex + * Updates the table on click + */ + + var children = context.children[0]; + + var maxIndex = this.getMaxIndex(); + + switch(children.innerHTML) { + case "Next": + if(this.activeIndex === maxIndex) return; + this.activeIndex++; + break; + case "Previous": + if(this.activeIndex === 0) return; + this.activeIndex--; + break; + default: + this.activeIndex = Number(children.innerHTML) - 1; + break; + } + + // Clamp the active index between 0 and max pages + this.activeIndex = Math.max(Math.min(maxIndex, this.activeIndex), 0); + + // Redraw + this.draw(); + +} + +Table.prototype.generatePagination = function(list) { + + /* function generatePagination + * Generates the pagination for the active table + */ + + if(list.length < this.MINIMUM_ITEMS_PER_PAGE) { + return ""; + } + + if(this.activeIndex * this.itemsPerPage > list.length) { + this.activeIndex = Math.floor(list.length / this.itemsPerPage); + } + + var endDisabled = this.getMaxIndex() === this.activeIndex; + var startDisabled = this.activeIndex === 0; + + return [ + "" + ].join("\n"); + +} + +Table.prototype.generateTableHead = function(header) { + + /* Function generateTableHead + * Generates the head row of the table + */ + + return [ + " ", + " ", + this.generateTableHeadContent(header), + " ", + " " + ].join("\n"); + +} + +Table.prototype.generateTableBodyContent = function(body) { + + /* Function generateTableBodyContent + * Generates the body of the table + */ + + const startSlice = this.itemsPerPage * this.activeIndex; + const endSlice = startSlice + this.itemsPerPage; + + // Slice the data from memory to what is visible & unfiltered + return body.slice(startSlice, endSlice).map(function(x) { + return "" + this.generateTableRowContent(x) + "" + }.bind(this)).join("\n"); + +} + +Table.prototype.generateTableHeadContent = function(header) { + + /* Function generateTableHeadContent + * Generates the actual content of the table header + */ + + function addTagTH(x) { + + /* Function addTagTH + * Generates a TH HTML element + */ + + return addTag("th", x); + + } + + return header.map(addTagTH).join("\n"); + +} + + +Table.prototype.generateTableBody = function(body) { + + /* Function generateTableBody + * Generates the actual content of the table body + */ + + return [ + " ", + this.generateTableBodyContent(body), + " " + ].join("\n"); + +} + +function addTag(tag, x) { + + /* Function addTag + * Generate a HTML element + */ + + return "<" + tag + ">" + x + ""; + +} + +Table.prototype.generateTableRowContent = function(row) { + + /* function generateTableRowContent + * Generates single row content for a table + */ + + function addTagTD(x) { + + /* Function addTagTD + * Generates a TD HTML element + */ + + return addTag("td", x); + + } + + return row.map(addTagTD).join("\n"); + +} \ No newline at end of file diff --git a/js/utils.js b/js/utils.js index 7138a63..0a953d5 100644 --- a/js/utils.js +++ b/js/utils.js @@ -1,5 +1,5 @@ let __DEBUG__ = false; -const __VERSION__ = "2.0.0"; +let __VERSION__ = "2.0.1"; const __DOI__ = "10.5281/zenodo.3647864" const RADIANS = Math.PI / 180; const PROJECTION_TYPE = "AREA"; @@ -42,6 +42,8 @@ if(document.getElementById("enable-sound")) { window.addEventListener("online", notify.bind(null, "success", "Your connection to the internet has been recovered.")); window.addEventListener("offline", notify.bind(null, "danger", "Your connection to the internet was dropped.")); +var openedCollection; + function padLeft(nr, n){ return Array(n - String(nr).length + 1).join("0") + nr; } @@ -221,6 +223,7 @@ function addSiteWindowWrapper() { "color": null, "type": "collection", "name": collectionName, + "doi": null, "components": components, "created": new Date().toISOString(), "index": collections.length @@ -1198,7 +1201,7 @@ function readMultipleFiles(files, callback) { } // Next queued file: create a new filereader instance - file = files.pop(); + file = files.shift(); reader = new FileReader(); // XML should be readable as text @@ -1277,9 +1280,17 @@ function addFooter() { * Adds footer to all HTML pages */ + var isBetaVersion = window.location.href.includes("beta"); + + if(isBetaVersion) { + document.getElementsByClassName("navbar-brand")[0].innerHTML += " BETA*"; + // Modify the version + __VERSION__ += "-beta"; + } + document.getElementById("footer-container").innerHTML = new Array( "
    ", - "Paleomagnetism.org © " + new Date().getFullYear() + ". All Rights Reserved.", + "Paleomagnetism.org" + (isBetaVersion ? " BETA" : "" ) + " © " + new Date().getFullYear() + ". All Rights Reserved.", "
    Version v" + __VERSION__ + " (" + __DOI__ + ")
    ", "  Source Code", "  Licensed under MIT.", @@ -1957,5 +1968,46 @@ function doiLookup(doi, callback) { } +function generateColorPalette() { + + /* + * Function generateColorPalette + * Generates the color palette for site color picking + */ + + function createColorItem(color) { + + /* + * Function generateColorPalette::createColorItem + * Generates a div for a particular color that can be clicked + */ + + return "
    "; + + } + + // Choose from a nice saturated gradient + const COLOR_PALETTE = new Array( + // First row + "#F55", "#FA5", "#FF5", + "#AF5", "#5F5", "#5FA", + "#5FF", "#5AF", "#55F", + "#A5F", "#F5F", "#F5A", + // Second row + "#A00", "#A50", "#AA0", + "#5A0", "#0A0", "#0A5", + "#0AA", "#05A", "#00A", + "#50A", "#A0A", "#A05", + // Third row + "#FFF", "#DDD", "#AAA", + "#888", "#555", "#222", + "#000" + ); + + // Create color bar + return COLOR_PALETTE.map(createColorItem).join(""); + +} + // Add the footer to every page that includes the utils addFooter(); diff --git a/library/index.html b/library/index.html index ce77efa..0b5d43e 100644 --- a/library/index.html +++ b/library/index.html @@ -94,11 +94,12 @@
    Paleomagnetism.org 2 - Data Library
    Available Publications in Library
    +
    +
    Map showing the geographical distribution of a total of . Hover over publication marker to shows its geographical coverage.
    +
    -
    +
    -
    -
    Map showing the geographical distribution of publications. Hover over publication marker to shows its geographical coverage.
    @@ -117,6 +118,7 @@
    Available Publications in Library
    + diff --git a/library/js/index.js b/library/js/index.js index 5ae8ecf..162b8da 100644 --- a/library/js/index.js +++ b/library/js/index.js @@ -15,6 +15,12 @@ function loadDigitalObjects() { return notify("danger", "Could not load the list of publications."); } + var nPublications = publications.length; + var nCollections = publications.map(x => x.nCollections).reduce((a, b) => a + b, 0); + var nSpecimens = publications.map(x => x.nSpecimens).reduce((a, b) => a + b, 0); + + document.getElementById("counter").innerHTML = "" + nPublications + " publications containing " + nCollections + " collections and " + nSpecimens + " specimens"; + // Update the map and table with the returned collections addCollectionsToMap(publications); addCollectionsToTable(publications); @@ -30,36 +36,35 @@ function addCollectionsToTable(publications) { * Adds the returned publications to a table */ - const TABLE_CONTAINER = "publication-table"; + var TABLE_HEADER = new Array("Name", "Author", "Institution", "Description", "Country", "Age", "Created", "DOI"); var rows = publications.map(function(x) { - return [ - "", - " " + x.name + "", - " " + x.author + "", - " " + x.institution + "", - " " + x.description + "", - " " + x.pid.slice(0, 16) + "…", - " " + ("" + x.doi + "" || "N/A") + "", - " " + new Date(x.created).toISOString().slice(0, 10) + "", - "" - ].join("\n"); + + if(x.doiInfo) { + var author = x.doiInfo.entryTags.author.split(" and ")[0] + " et al., (" + x.doiInfo.entryTags.journal + ", " + x.doiInfo.entryTags.year + ")"; + } else { + var author = x.author; + } + + return new Array( + "" + x.name + "", + author, + x.institution, + x.description, + x.country || "Unconstrained", + x.age, + //"" + x.pid.slice(0, 8) + "", + new Date(x.created).toISOString().slice(0, 10), + "" + "DOI" + "" || "N/A" + ); }); - // Update the table container - document.getElementById(TABLE_CONTAINER).innerHTML = [ - "", - " ", - " Name", - " Author", - " Institution", - " Description", - " Persistent Identifier", - " DOI", - " Created", - " ", - "", - ].concat(rows).join("\n"); + new Table({ + "id": "publication-table", + "search": true, + "header": TABLE_HEADER, + "body": rows + }); } @@ -77,8 +82,6 @@ function addMap() { // Set map options (bounds) var mapOptions = { "minZoom": 1, - "maxBounds": new L.latLngBounds(new L.latLng(-90, -180), new L.latLng(90, 180)), - "maxBoundsViscosity": 0.5, "attributionControl": true } diff --git a/miscellaneous/index.html b/miscellaneous/index.html index da215ca..3cced7d 100644 --- a/miscellaneous/index.html +++ b/miscellaneous/index.html @@ -102,7 +102,7 @@
    Param
    Directions & Poles

    -

    This tool can be used to parametrically sample a Fisherian distribution of poles or directions and generate declination, inclination pairs.

    +

    This tool can be used to convert between magnetic directions and virtual geomagnetic poles at site locations following the GAD model.

    diff --git a/publication/js/index.js b/publication/js/index.js index aef4ed2..3adb31d 100644 --- a/publication/js/index.js +++ b/publication/js/index.js @@ -16,10 +16,10 @@ function addMap(publication) { */ return new Array( - "" + collection.name + "", + "Collection " + collection.name + "", "" + publication.description + "", "", - "Collections contains " + publication.nSpecimens + " specimens", + "Collection contains " + collection.data.specimens.length + " specimens.", "", "Author: " + publication.author, "Published: " + publication.created, @@ -39,8 +39,6 @@ function addMap(publication) { var mapOptions = { "minZoom": 1, "maxZoom": 13, - "maxBounds": new L.latLngBounds(new L.latLng(-90, -180), new L.latLng(90, 180)), - "maxBoundsViscosity": 0.5, "attributionControl": true } @@ -52,12 +50,12 @@ function addMap(publication) { publication.collections.forEach(function(collection, i) { var averageLocation = meanDirection(collection.data.specimens.map(function(x) { - return new Direction(x.latitude, x.longitude).toCartesian(); + return new Direction(x.longitude, x.latitude).toCartesian(); })); var markerInformation = createTooltip(publication, collection, i); - markerGroup.push(new L.Marker(new L.LatLng(averageLocation.dec, averageLocation.inc)).addTo(map).bindPopup(markerInformation)); + markerGroup.push(new L.Marker(new L.LatLng(averageLocation.inc, averageLocation.dec)).addTo(map).bindPopup(markerInformation)); }); @@ -136,44 +134,51 @@ function formatCollectionTable(publication) { * Formats the table containing all collections from this collection */ + // Show warning + if(!publication.accepted) { + notify("warning", "This specimen is pending review and has not yet been accepted."); + } + // Initialize the leaflet map addMap(publication); - // Create accept & reject links (behind login) - let acceptLink = "https://api.paleomagnetism.org/" + publication.pid + "?accept"; - let rejectLink = "https://api.paleomagnetism.org/" + publication.pid + "?reject"; + // Add a row for each collection + var rows = publication.collections.map(createSampleRows); - if(!publication.accepted) { - notify("warning", "This publication is pending review and has not yet been accepted.
    Accept or Reject"); - } + // Count the components + var componentSum = rows.reduce((a, b) => a + b[3], 0); // Load the metadata for this collection document.getElementById("card-table").innerHTML = metadataContent(publication); document.getElementById("pid-box").innerHTML = publication.pid; - document.getElementById("fork-link").innerHTML = createForkLink(publication.pid); - // Add a row for each collection - var rows = publication.collections.map(formatSampleRows); + // Check if there are components: offer to fork in the application + if(componentSum === 0) { + document.getElementById("fork-link").innerHTML = " No interpreted components to show."; + } else { + document.getElementById("fork-link").innerHTML = createForkLink(publication.pid); + } document.getElementById("publication-table").innerHTML = new Array( "", " ", " Collection", " Type", - " Number of Specimens", + " # Specimens", + " # Components", " SHA2", " Version", " Created", " ", "" - ).concat(rows).join("\n"); + ).concat(rows.map(formatSampleRows)).join("\n"); } -function formatSampleRows(collection, i) { +function createSampleRows(collection, i) { /* - * Function formatSampleRows + * Function createSampleRows * Creates HTML for rows of the collection table */ @@ -193,15 +198,35 @@ function formatSampleRows(collection, i) { reference = ""; } - // Format the row - return "" + new Array( + return new Array( "" + collection.name + "" + reference, locationType, collection.data.specimens.length, + countComponents(collection.data.specimens), collection.data.hash.slice(0, 16) + "…", collection.data.version, collection.data.created.slice(0, 10), - ).map(x => "" + x + "").join("\n") + ""; + ); + +} + +function formatSampleRows(x) { + + /* + * Function formatSampleRows + * Creates HTML for rows of the collection table + */ + + // Format the row + return "" + x.map(x => "" + x + "").join("\n") + ""; + +} + +function countComponents(specimens) { + + return specimens.map(function(specimen) { + return specimen.interpretations.length; + }).reduce((a, b) => a + b, 0); } diff --git a/references/index.html b/references/index.html index 4ff15be..51f416c 100644 --- a/references/index.html +++ b/references/index.html @@ -82,6 +82,9 @@
    Paleomagnetism.org & Source Code
    10.1016/j.cageo.2016.05.007

    Koymans, M.R., Langereis, C.G., Pastor-Galan, D., and van Hinsbergen, D.J.J., Paleomagnetism.org: An online multi-platform open source environment for paleomagnetic data analysis, Computers and Geosciences, Volume 93, Pages 127–137 (2016)

    +
    10.1029/2019GC008838
    +

    Koymans, M.R., van Hinsbergen, D.J.J., Pastor-Galan, D., Vaes, B., and Langereis, C.G., Towards FAIR paleomagnetic data management through Paleomagnetism.org 2.0, Geochemistry, Geophysics, Geosystems (Accepted)

    +

    The source code for this particular version () of the Paleomagnetism.org software can be cited. It may be important to include what version of the software was used for analysis with respect to data provenance.

    @@ -157,6 +160,10 @@
    Allerton, S., Vine, F.J. Spreading structure of the Troodos ophiolite, Cyprus: some paleomagnetic constraints. (1987) Geology, 15 (7), pp. 593-597.

    No DOI Available

    Morris, A., Anderson, M.W., Robertson, A.H.F. Multiple tectonic rotations and transform tectonism in an intraoceanic suture zone, SW Cyprus (1998) Tectonophysics, 299 (1-3), pp. 229-253.

    + +
    10.1130/L547.1
    +

    Pastor-Galán, D., Mulchrone, K. F., Koymans, M. R., van Hinsbergen, D. J., & Langereis, C. G. (2017). Bootstrapped total least squares orocline test: A robust method to quantify vertical-axis rotation patterns in orogens, with examples from the Cantabrian and Aegean oroclines. Lithosphere, 9(3), 499-511.

    +
    diff --git a/statistics/index.html b/statistics/index.html index fed8754..82b7e9e 100644 --- a/statistics/index.html +++ b/statistics/index.html @@ -511,6 +511,87 @@
    + + + +
    + +