<div id="viewDiv">
</div>
<div id="infoDiv">
  <h2>Worldwide Earthquakes</h2>
</div>
<div id="avgDiv">
  <h2>Average Reports</h2>
  <h3 id="avgValue"></h3>
</div>
html,
body,
#viewDiv {
  padding: 0;
  margin: 0;
  height: 100%;
  width: 100%;
}

#infoDiv {
  position: absolute;
  bottom: 15px;
  right: 0;
  max-height: 80%;
  max-width: 300px;
  background-color: black;
  padding: 8px;
  border-top-left-radius: 5px;
  color: white;
  opacity: 0.8;
}

#avgDiv {
  font-family: "Avenir Next";
  text-align: center;
  position: absolute;
  top: 0;
  right: 0;
  min-height: 50px;
  min-width: 300px;
  max-height: 80%;
  max-width: 300px;
  background-color: black;
  padding: 8px;
  border-top-left-radius: 5px;
  color: white;
  opacity: 0.8;
}
require([
  "esri/views/MapView",
  "esri/Map",
  "esri/layers/FeatureLayer",
  "esri/geometry/Point",
  "esri/widgets/Legend",
  "esri/core/watchUtils"
], function(MapView, Map, FeatureLayer, Point, Legend, watchUtils) {
  const url =
    "https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_week.geojson";
  const avgValue = document.getElementById("avgValue");
  const fields = [
    {
      name: "ObjectID",
      alias: "ObjectID",
      type: "oid"
    },
    {
      name: "title",
      alias: "title",
      type: "string"
    },
    {
      name: "type",
      alias: "type",
      type: "string"
    },
    {
      name: "place",
      alias: "place",
      type: "string"
    },
    {
      name: "depth",
      alias: "depth",
      type: "string"
    },
    {
      name: "time",
      alias: "time",
      type: "date"
    },
    {
      name: "mag",
      alias: "Magnitude",
      type: "double"
    },
    {
      name: "url",
      alias: "url",
      type: "string"
    },
    {
      name: "mmi",
      alias: "intensity",
      type: "double"
    },
    {
      name: "felt",
      alias: "Number of felt reports",
      type: "double"
    },
    {
      name: "sig",
      alias: "significance",
      type: "double"
    }
  ];

  const pTemplate = {
    title: "{title}",
    content: [
      {
        type: "fields",
        fieldInfos: [
          {
            fieldName: "place",
            label: "Location",
            visible: true
          },
          {
            fieldName: "time",
            label: "Date and time",
            visible: true
          },
          {
            fieldName: "mag",
            label: "Magnitude",
            visible: true
          },
          {
            fieldName: "mmi",
            label: "Intensity",
            visible: true
          },
          {
            fieldName: "depth",
            label: "Depth",
            visible: true
          },
          {
            fieldName: "felt",
            label: "Number who felt the quake",
            visible: true,
            format: {
              digitSeparator: true,
              places: 0
            }
          },
          {
            fieldName: "sig",
            label: "Significance",
            visible: true
          },
          {
            fieldName: "url",
            label: "More info",
            visible: true
          }
        ]
      }
    ],
    fieldInfos: [
      {
        fieldName: "time",
        format: {
          dateFormat: "short-date-short-time"
        }
      }
    ]
  };

  const quakesRenderer = {
    type: "simple",
    symbol: {
      type: "simple-marker",
      style: "circle",
      size: 20,
      color: [211, 255, 255, 0.3],
      outline: {
        width: 1,
        color: "#FF0055",
        style: "solid"
      }
    },
    visualVariables: [
      {
        type: "size",
        field: "mag", // earthquake magnitude
        valueUnit: "unknown",
        minDataValue: 2,
        maxDataValue: 7,
        // Define size of mag 2 quakes based on scale
        minSize: {
          type: "size",
          valueExpression: "$view.scale",
          stops: [
            {
              value: 1128,
              size: 12
            },
            {
              value: 36111,
              size: 12
            },
            {
              value: 9244649,
              size: 6
            },
            {
              value: 73957191,
              size: 4
            },
            {
              value: 591657528,
              size: 2
            }
          ]
        },
        // Define size of mag 7 quakes based on scale
        maxSize: {
          type: "size",
          valueExpression: "$view.scale",
          stops: [
            {
              value: 1128,
              size: 80
            },
            {
              value: 36111,
              size: 60
            },
            {
              value: 9244649,
              size: 50
            },
            {
              value: 73957191,
              size: 50
            },
            {
              value: 591657528,
              size: 25
            }
          ]
        }
      }
    ]
  };
  
    const layer = new FeatureLayer({
      geometryType: "point",
      source: [],
      fields: fields,
      objectIdField: "ObjectID",
      renderer: quakesRenderer,
      popupTemplate: pTemplate
    });

  const map = new Map({
    basemap: "dark-gray-vector",
    layers: [layer]
  });

  // Create MapView
  const view = new MapView({
    container: "viewDiv",
    map: map,
    center: [-97.22, 34.0523],
    zoom: 3,
    // customize ui padding for legend placement
    ui: {
      padding: {
        bottom: 15,
        right: 0
      }
    }
  });
  
    const legend = new Legend({
      view,
      container: "infoDiv",
      layerInfos: [
        {
          layer: layer,
          title: "Earthquake"
        }
      ]
    });

  const fetchGeoJson = () => fetch(url).then(response => response.json());

  const createGraphics = geoJson => {
    // Create an array of Graphics from each GeoJSON feature
    return geoJson.features.map((feature, i) => {
      return {
        geometry: new Point({
          x: feature.geometry.coordinates[0],
          y: feature.geometry.coordinates[1]
        }),
        // select only the attributes you care about
        attributes: {
          ObjectID: i,
          title: feature.properties.title,
          type: feature.properties.type,
          place: feature.properties.place,
          depth: feature.geometry.coordinates[2] + " km",
          time: feature.properties.time,
          mag: feature.properties.mag,
          mmi: feature.properties.mmi,
          felt: feature.properties.felt,
          sig: feature.properties.sig,
          url: feature.properties.url
        }
      };
    });
  };

  const updateLayer = graphics => {
    return layer.applyEdits({
      addFeatures: graphics
    });
  };
  
  let highlight;
  
  const queryLayer = () => {
    view.whenLayerView(layer).then(layerView => {
      watchUtils.whenFalseOnce(layerView, "updating").then(() => {
        view.on(["click", "drag"], event => {
          event.stopPropagation();
          const query = layer.createQuery();
          query.set({
            geometry: view.toMap(event),
            distance: 100,
            units: "miles",
            outStatistics: [{
              onStatisticField: "felt",
              outStatisticFieldName: "felt_avg",
              statisticType: "avg"
            }]
          });
          layerView.queryFeatures(query).then(({ features }) => {
            const result = features[0];
            if (result) {
              avgValue.innerText = result.attributes.felt_avg.toFixed(2);
            }
            else {
              avgValue.innerText = 0.00;
            }
          })
          layerView.queryObjectIds(query).then(ids => {
            if (highlight) {
              highlight.remove();
              highlight = null;
            }
            highlight = layerView.highlight(ids);
          });
        });
      });
    });
  };
  
  view.when(() => {
    fetchGeoJson()
      .then(createGraphics)
      .then(updateLayer)
      .then(queryLayer);
  });
  
});

External CSS

  1. https://js.arcgis.com/4.10/esri/css/main.css

External JavaScript

  1. https://js.arcgis.com/4.10