gpw-data-viewer.html 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. <!doctype html>
  2. <html>
  3. <meta charset="utf-8">
  4. <head>
  5. <title>gpw data viewer</title>
  6. <style>
  7. canvas {
  8. max-width: calc(100% - 16px);
  9. }
  10. </style>
  11. </head>
  12. <body>
  13. <canvas></canvas>
  14. </body>
  15. <script type="module">
  16. async function loadFile( url ) {
  17. const req = await fetch( url );
  18. return req.text();
  19. }
  20. function parseData( text ) {
  21. const data = [];
  22. const settings = { data };
  23. let max;
  24. let min;
  25. // split into lines
  26. text.split( '\n' ).forEach( ( line ) => {
  27. // split the line by whitespace
  28. const parts = line.trim().split( /\s+/ );
  29. if ( parts.length === 2 ) {
  30. // only 2 parts, must be a key/value pair
  31. settings[ parts[ 0 ] ] = parseFloat( parts[ 1 ] );
  32. } else if ( parts.length > 2 ) {
  33. // more than 2 parts, must be data
  34. const values = parts.map( ( v ) => {
  35. const value = parseFloat( v );
  36. if ( value === settings.NODATA_value ) {
  37. return undefined;
  38. }
  39. max = Math.max( max === undefined ? value : max, value );
  40. min = Math.min( min === undefined ? value : min, value );
  41. return value;
  42. } );
  43. data.push( values );
  44. }
  45. } );
  46. return Object.assign( settings, { min, max } );
  47. }
  48. function drawData( file ) {
  49. const { min, max, ncols, nrows, data } = file;
  50. const range = max - min;
  51. const ctx = document.querySelector( 'canvas' ).getContext( '2d' );
  52. // make the canvas the same size as the data
  53. ctx.canvas.width = ncols;
  54. ctx.canvas.height = nrows;
  55. // but display it double size so it's not too small
  56. ctx.canvas.style.width = px( ncols * 2 );
  57. // fill the canvas to dark gray
  58. ctx.fillStyle = '#444';
  59. ctx.fillRect( 0, 0, ctx.canvas.width, ctx.canvas.height );
  60. // draw each data point
  61. data.forEach( ( row, latNdx ) => {
  62. row.forEach( ( value, lonNdx ) => {
  63. if ( value === undefined ) {
  64. return;
  65. }
  66. const amount = ( value - min ) / range;
  67. const hue = 1;
  68. const saturation = 1;
  69. const lightness = amount;
  70. ctx.fillStyle = hsl( hue, saturation, lightness );
  71. ctx.fillRect( lonNdx, latNdx, 1, 1 );
  72. } );
  73. } );
  74. }
  75. function px( v ) {
  76. return `${v | 0}px`;
  77. }
  78. function hsl( h, s, l ) {
  79. return `hsl(${h * 360 | 0},${s * 100 | 0}%,${l * 100 | 0}%)`;
  80. }
  81. loadFile( 'resources/data/gpw/gpw_v4_basic_demographic_characteristics_rev10_a000_014mt_2010_cntm_1_deg.asc' )
  82. .then( parseData )
  83. .then( drawData );
  84. </script>
  85. </html>