---
title: Map page views by region in a custom app
source: https://docs.newrelic.com/docs/new-relic-solutions/tutorials/map-pageviews-region
---

New Relic has powerful and flexible tools for building custom apps and populating them with data. This guide shows you how to build a custom app and populate it with page view data using New Relic's Query Language (NRQL - pronounced 'nurkle'). Then you make your data interactive. And last, if you have a little more time and want to install a third-party React library, you can display the page view data you collect on a map of the world.

In this guide, you build an app to display page view data in two ways:

-   In a table
-   On a map

Please review the **Before you begin** section to make sure you have everything you need and don't get stuck halfway through.

## Before you begin [#begin]

In order to get the most out of this guide, you must have:

-   A New Relic account, API key, and the command-line tool.
-   New Relic Browser page view data to populate the app. Without this data, you won't be able to complete this guide.

To add your data to a world map in the second half of the guide:

-   npm, which you'll use during this section of the guide to install [Leaflet](https://www.npmjs.com/package/leaflet), a third-party JavaScript React library used to build interactive maps. If you're new to React and npm, you can go here to [install Node.js and npm](https://nodejs.org/en/download/).

## New Relic terminology [#terminology]

The following are some terms used in this guide:

-   New Relic application: The finished product where data is rendered in New Relic. This might look like a series of interactive charts or a map of the world.
-   Nerdpack: New Relic's standard collection of JavaScript, JSON, CSS, and other files that control the functionality and look of your application. For more information, see [Nerdpack file structure](https://docs.newrelic.com/docs/new-relic-solutions/build-nr-ui/nerdpack-file-structure).
-   Launcher: The button in New Relic that launches your application.
-   Nerdlets: New Relic React components used to build your application. The three default files are `index.js`, `nr1.json`, and `styles.scss`, but you can customize and add your own.

## Build a custom app with a table chart [#build-app-table-chart]

### Query your browser data [#query-data]

Use Query builder to write a NRQL query to see your page view data, as follows.

In New Relic, select **Query your data** (in the top right corner). That puts you in **NRQL** mode. You'll use NRQL to test your query before dropping the data into your table.

Copy and paste this query into a clear query field, and then select **Run**.

````sql
FROM PageView SELECT count(*), average(duration) WHERE appName = 'WebPortal' FACET countryCode, regionCode SINCE 1 week ago LIMIT 1000
```

If you have PageView data, this query shows a week of average page views broken down by country and limited to a thousand items. The table will be full width and use the "chart" class defined in the CSS.

If you don't have any results at this point, ensure your query doesn't have any errors. If your query is correct, you might not have the [Browser agent](/docs/browser/browser-monitoring/installation/install-browser-monitoring-agent/) installed.

````

### Create and serve a new Nerdpack [#create-nerdpack]

To get started, create a new Nerdpack, and serve it up to New Relic from your local development environment:

1.  Update `nr1` and create a new Nerdpack for this app:

    ```bash
    nr1 update
    nr1 create --type nerdpack --name pageviews-app
    [output] {success}✔  {plain}Component created successfully!
    [output]    {purple}nerdpack {blue}pageviews-app {plain}is available at {green}"./pageviews-app"
    ```

2.  Serve the project up to New Relic:

    ```bash animate
    cd pageviews-app && nr1 nerdpack:serve
    [output] Found and loaded {green}2 {plain}nr1.json files on PageviewsApp ({purple}00e0f043-1fc3-42cd-a8ca-7eef5fc9cd45{plain}) Nerdpack.
    [output]
    [output] {purple}Nerdpack:
    [output] {success}✔  PageviewsApp {purple}(00e0f043-1fc3-42cd-a8ca-7eef5fc9cd45) {blue}nr1.json
    [output]
    [output] {purple}Launchers:
    [output] {success}✔  {green}pageviews-app-launcher {blue}launchers/pageviews-app-launcher/nr1.json
    [output]
    [output] {purple}Nerdlets:
    [output] {success}✔  {green}pageviews-app-nerdlet {blue}nerdlets/pageviews-app-nerdlet/nr1.json
    [output]
    [output] 🛠  Built artifact files for:
    [output] {yellow}⁎  {purple}00e0f043-1fc3-42cd-a8ca-7eef5fc9cd45--pageviews-app-nerdlet {plain}built {success}✔
    [output]
    [output] {success}✔  {plain}Nerdpack built successfully!
    [output] {yellow}★  {plain}Starting as orchestrator...
    [output]
    [output] {success}✔  {plain}Server ready! Test it at: https://staging-one.newrelic.com/?nerdpacks=local
    [output] {blue}↩  Server will reload automatically if you modify any file!
    [output]
    [output] 🛠  Built artifact files for:
    [output] {yellow}⁎  {purple}00e0f043-1fc3-42cd-a8ca-7eef5fc9cd45--pageviews-app-nerdlet {plain}built {success}✔
    [output]
    [output] {success}✔  {plain}Nerdpack built successfully!
    ```

### Review your app files and view your app locally [#review-files]

1.  Navigate to your `pageviews-app` to see how it's structured.
    It contains a launcher folder, where you can customize the description and icon that will be displayed on the app's launcher in New Relic. It also contains `nerdlets`, which each contain three default files: `index.js`, `nr1.json`, and `styles.scss`. You'll edit some of these files as part of this guide. For more information, see [Nerdpack file structure](https://docs.newrelic.com/docs/new-relic-solutions/build-nr-ui/nerdpack-file-structure).

2.  Now in your browser, open `https://one.newrelic.com/?nerdpacks=local`, and then click **Apps** to see the `pageview-apps` Nerdpack that you served up.

    When you select the launcher, you see a `Hello` message.

### Hard code your account ID [#account-id]

For the purposes of this exercise and for your convenience, hard code your account ID. In the `pageview-app-nerdlet` directory, in the `index.js` file, add this code between the `import` and `export` lines. ([Read about finding your account ID here](https://docs.newrelic.com/docs/accounts/install-new-relic/account-setup/account-id)).

````jsx fileName=pageview-app-nerdlet/index.js
import React from 'react';

const accountId = 0; // Replace with your account ID

export default class PageViewApp extends React.Component {
  render() {
    return <h1>Hello, pageview-app-nerdlet Nerdlet!</h1>;
  }
}
```

````

### Import the `TableChart` component [#import-table-component]

To show your data in a table chart, import the `TableChart` component from New Relic. To do so, in `index.js`, add this code under `import React`.

````jsx fileName=pageview-app-nerdlet/index.js
import React from 'react';
import { TableChart } from 'nr1';

const accountId = 0; // Replace with your account ID

export default class PageViewApp extends React.Component {
  render() {
    return <h1>Hello, pageview-app-nerdlet Nerdlet!</h1>;
  }
}
```

````

### Add a table with a single row [#add-single-row-table]

To add a table with a single row, in the `index.js` file, replace this line with this `export` code:

````jsx fileName=pageview-app-nerdlet/index.js
import React from 'react';
import { TableChart } from 'nr1';

const accountId = 0; // Replace with your account ID

export default class PageViewApp extends React.Component {
  render() {
    return (
      <div className="container">
        <div className="row"></div>
      </div>
    );
  }
}
```

````

### Customize the look of your table (optional) [#customize-table]

You can use standard CSS to customize the look of your components.

In the `styles.scss` file, add this CSS.
Feel free to customize this CSS to your taste.

````css fileName=pageview-app-nerdlet/styles.scss
.container {
  width: 100%;
  height: 99vh;
  display: flex;
  flex-direction: column;
  .row {
    margin: 10px;
    display: flex;
    flex-direction: row;
  }
  .chart {
    height: 250px;
  }
}
```

````

### Get your data into that table [#add-data-table]

Now that you've got a table, you can drop a `TableChart` populated with data from the NRQL query you wrote at the very beginning of this guide.

Put this code into the `row` div.

````jsx fileName=pageview-app-nerdlet/index.js
import React from 'react';
import { TableChart } from 'nr1';

const accountId = 0; // Replace with your account ID

export default class PageViewApp extends React.Component {
  render() {
    return (
      <div className="container">
        <div className="row">
          <TableChart
            accountId={accountId}
            query={`FROM PageView SELECT count(*), average(duration) WHERE appName = 'WebPortal' SINCE 1 week ago LIMIT 1000`}
            fullWidth
            className="chart"
          />
        </div>
      </div>
    );
  }
}
```

Go to New Relic and click your app to see your data in the table. (You might need to serve your app to New Relic again.)

Congratulations! You made your app! Continue on to make it interactive and show your data on a map.

````

## Make your app interactive with a text field [#app-text-field]

Once you confirm that data is getting to New Relic from your app, you can start customizing it and making it interactive. To do this, you add a text field to filter your data. Later, you use a third-party library called `Leaflet` to show that data on a world map.

### Import the `TextField` component [#import-textfield]

Like you did with the `TableChart` component, you need to import a [`TextField` component](https://docs.newrelic.com/docs/new-relic-solutions/build-nr-ui/sdk-component/controls/TextField/) from New Relic.

````jsx fileName=pageview-app-nerdlet/index.js
import React from 'react';
import { TableChart, TextField } from 'nr1';

const accountId = 0; // Replace with your account ID

export default class PageViewApp extends React.Component {
  render() {
    return (
      <div className="container">
        <div className="row">
          <TableChart
            accountId={accountId}
            query={`FROM PageView SELECT count(*), average(duration) WHERE appName = 'WebPortal' SINCE 1 week ago LIMIT 1000`}
            fullWidth
            className="chart"
          />
        </div>
      </div>
    );
  }
}
```

````

### Add a row for your text field [#add-row-textfield]

To add a text field filter above the table, put this code above the `TableChart` div.
The text field will have a default value of "US".

````jsx fileName=pageview-app-nerdlet/index.js
import React from 'react';
import { TableChart, TextField } from 'nr1';

const accountId = 0; // Replace with your account ID

export default class PageViewApp extends React.Component {
  render() {
    return (
      <div className="container">
        <div className="row">
          <div className="row">
            <TextField
              placeholder="US"
              onChange={(event) => {
                this.setState({ countryCode: event.target.value });
              }}
            />
          </div>
          <TableChart
            accountId={accountId}
            query={`FROM PageView SELECT count(*), average(duration) WHERE appName = 'WebPortal' SINCE 1 week ago LIMIT 1000`}
            fullWidth
            className="chart"
          />
        </div>
      </div>
    );
  }
}
```

````

### Build the text field object [#build-text-field]

Above the `render()` function, add a `constructor` to build the text field object.

````jsx fileName=pageview-app-nerdlet/index.js
import React from 'react';
import { TableChart, TextField } from 'nr1';

const accountId = 0; // Replace with your account ID

export default class PageViewApp extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      countryCode: null,
    };
  }

  render() {
    return (
      <div className="container">
        <div className="row">
          <div className="row">
            <TextField
              placeholder="US"
              onChange={(event) => {
                this.setState({ countryCode: event.target.value });
              }}
            />
          </div>
          <TableChart
            accountId={accountId}
            query={`FROM PageView SELECT count(*), average(duration) WHERE appName = 'WebPortal' SINCE 1 week ago LIMIT 1000`}
            fullWidth
            className="chart"
          />
        </div>
      </div>
    );
  }
}
```

Above `return`, add:

```jsx fileName=pageview-app-nerdlet/index.js
import React from 'react';
import { TableChart, TextField } from 'nr1';

const accountId = 0; // Replace with your account ID

export default class PageViewApp extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      countryCode: null,
    };
  }

  render() {
    const { countryCode } = this.state;

    return (
      <div className="container">
        <div className="row">
          <div className="row">
            <TextField
              placeholder="US"
              onChange={(event) => {
                this.setState({ countryCode: event.target.value });
              }}
            />
          </div>
          <TableChart
            accountId={accountId}
            query={`FROM PageView SELECT count(*), average(duration) WHERE appName = 'WebPortal' SINCE 1 week ago LIMIT 1000`}
            fullWidth
            className="chart"
          />
        </div>
      </div>
    );
  }
}
```

Now add `countryCode` to your table chart query.

```jsx fileName=pageview-app-nerdlet/index.js
import React from "react";
import { TableChart, TextField } from "nr1";

const accountId = 0; // Replace with your account ID

export default class PageViewApp extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      countryCode: null,
    };
  }

  render() {
    const { countryCode } = this.state;

    return (
      <div className="container">
        <div className="row">
          <div className="row">
            <TextField
              placeholder="US"
              onChange={(event) => {
                this.setState({ countryCode: event.target.value });
              }}
            />
          </div>
          <TableChart
            accountId={accountId}
            query={`FROM PageView SELECT count(*), average(duration) WHERE appName = 'WebPortal' ${
              countryCode ? ` WHERE countryCode LIKE '%${countryCode}%' ` : ""
            } FACET countryCode, regionCode SINCE 1 week ago LIMIT 1000`}
            fullWidth
            className="chart"
          />
        </div>
      </div>
    );
  }
}
```

Reload your app to try out the text field.

````

## Get your data on a map [#add-data-map]

To create the map, you use npm to install `Leaflet`.

### Install `Leaflet` [#install-leaflet]

In your terminal, type:

````bash
npm install --save leaflet react-leaflet
```

In your nerdlets `styles.scss` file, import the `Leaflet` CSS:

```css fileName=pageview-app-nerdlet/styles.scss
@import `~leaflet/dist/leaflet.css`;

.container {
  width: 100%;
  height: 99vh;
  display: flex;
  flex-direction: column;
  .row {
    margin: 10px;
    display: flex;
    flex-direction: row;
  }
  .chart {
    height: 250px;
  }
}
```

While you're in `styles.scss`, fix the width and height of your map:

```css fileName=pageview-app-nerdlet/styles.scss
@import `~leaflet/dist/leaflet.css`;

.container {
  width: 100%;
  height: 99vh;
  display: flex;
  flex-direction: column;
  .row {
    margin: 10px;
    display: flex;
    flex-direction: row;
  }
  .chart {
    height: 250px;
  }
}

.containerMap {
  width: 100%;
  z-index: 0;
  height: 70vh;
}
```

````

### Add a webpack config file for `Leaflet`

Add a webpack configuration file `.extended-webpackrc.js` to the top-level folder in your nerdpack. This supports your use of map tiling information data from `Leaflet`.

````jsx fileName=.extended-webpackrc.js
module.exports = {
  module: {
    rules: [
      {
        test: /\.(png|jpe?g|gif)$/,
        use: [
          {
            loader: 'file-loader',
            options: {},
          },
          {
            loader: 'url-loader',
            options: { limit: 25000 },
          },
        ],
      },
    ],
  },
};
```

````

### Import modules from `Leaflet`

In `index.js`, import modules from `Leaflet`.

````jsx fileName=pageview-app-nerdlet/index.js
import React from 'react';
import { TableChart, TextField } from 'nr1';
import { Map, CircleMarker, TileLayer } from 'react-leaflet';

const accountId = 0; // Replace with your account ID

export default class PageViewApp extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      countryCode: null,
    };
  }

  render() {
    const { countryCode } = this.state;

    return (
      <div className="container">
        <div className="row">
          <div className="row">
            <TextField
              placeholder="US"
              onChange={(event) => {
                this.setState({ countryCode: event.target.value });
              }}
            />
          </div>
          <TableChart
            accountId={accountId}
            query={`FROM PageView SELECT count(*), average(duration) WHERE appName = 'WebPortal' ${
              countryCode ? ` WHERE countryCode LIKE '%${countryCode}%' ` : ''
            } FACET countryCode, regionCode SINCE 1 week ago LIMIT 1000`}
            fullWidth
            className="chart"
          />
        </div>
      </div>
    );
  }
}
```

````

### Import additional modules from New Relic

You need several more modules from New Relic to make the `Leaflet` map work well. Import them with this code:

````jsx fileName=pageview-app-nerdlet/index.js
import React from 'react';
import {
  TableChart,
  TextField,
  NerdGraphQuery,
  Spinner,
  Button,
  BlockText,
} from 'nr1';
import { Map, CircleMarker, TileLayer } from 'react-leaflet';

const accountId = 0; // Replace with your account ID

export default class PageViewApp extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      countryCode: null,
    };
  }

  render() {
    const { countryCode } = this.state;

    return (
      <div className="container">
        <div className="row">
          <div className="row">
            <TextField
              placeholder="US"
              onChange={(event) => {
                this.setState({ countryCode: event.target.value });
              }}
            />
          </div>
          <TableChart
            accountId={accountId}
            query={`FROM PageView SELECT count(*), average(duration) WHERE appName = 'WebPortal' ${
              countryCode ? ` WHERE countryCode LIKE '%${countryCode}%' ` : ''
            } FACET countryCode, regionCode SINCE 1 week ago LIMIT 1000`}
            fullWidth
            className="chart"
          />
        </div>
      </div>
    );
  }
}
```

`NerdGraphQuery` lets you make multiple NRQL queries at once and is what will populate the map with data. `Spinner` adds a loading spinner. `Button` gives you button components. `BlockText` give you block text components.

````

### Get data for the map [#get-data-map]

Using latitude and longitude with country codes, you can put New Relic data on a map.

````jsx fileName=pageview-app-nerdlet/index.js
import React from 'react';
import {
  TableChart,
  TextField,
  NerdGraphQuery,
  Spinner,
  Button,
  BlockText,
} from 'nr1';
import { Map, CircleMarker, TileLayer } from 'react-leaflet';

const accountId = 0; // Replace with your account ID

export default class PageViewApp extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      countryCode: null,
    };
  }

  mapData() {
    const { countryCode } = this.state;
    const query = `{
      actor {
        account(id: 1606862) {
          mapData: nrql(query: "SELECT count(*) AS 'x', average(duration) AS 'y', sum(asnLatitude)/count(*) AS 'lat', sum(asnLongitude)/count(*) AS 'lng' FROM PageView FACET regionCode, countryCode WHERE appName = 'WebPortal' ${
            countryCode ? ` WHERE countryCode LIKE '%${countryCode}%' ` : ''
          } LIMIT 1000 ") {
            results
            nrql
          }
        }
      }
    }`;

    return query;
  }

  render() {
    const { countryCode } = this.state;

    return (
      <div className="container">
        <div className="row">
          <div className="row">
            <TextField
              placeholder="US"
              onChange={(event) => {
                this.setState({ countryCode: event.target.value });
              }}
            />
          </div>
          <TableChart
            accountId={accountId}
            query={`FROM PageView SELECT count(*), average(duration) WHERE appName = 'WebPortal' ${
              countryCode ? ` WHERE countryCode LIKE '%${countryCode}%' ` : ''
            } FACET countryCode, regionCode SINCE 1 week ago LIMIT 1000`}
            fullWidth
            className="chart"
          />
        </div>
      </div>
    );
  }
}
```

````

### Customize the map marker colors [#customize-map-colors]

Above the `mapData` function, add this code to customize the map marker colors.

````jsx fileName=pageview-app-nerdlet/index.js
import React from 'react';
import {
  TableChart,
  TextField,
  NerdGraphQuery,
  Spinner,
  Button,
  BlockText,
} from 'nr1';
import { Map, CircleMarker, TileLayer } from 'react-leaflet';

const accountId = 0; // Replace with your account ID

export default class PageViewApp extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      countryCode: null,
    };
  }

  getMarkerColor(measure, apdexTarget = 1.7) {
    if (measure <= apdexTarget) {
      return '#11A600';
    } else if (measure >= apdexTarget && measure <= apdexTarget * 4) {
      return '#FFD966';
    } else {
      return '#BF0016';
    }
  }

  mapData() {
    const { countryCode } = this.state;
    const query = `{
      actor {
        account(id: 1606862) {
          mapData: nrql(query: "SELECT count(*) AS 'x', average(duration) AS 'y', sum(asnLatitude)/count(*) AS 'lat', sum(asnLongitude)/count(*) AS 'lng' FROM PageView FACET regionCode, countryCode WHERE appName = 'WebPortal' ${
            countryCode ? ` WHERE countryCode LIKE '%${countryCode}%' ` : ''
          } LIMIT 1000 ") {
            results
            nrql
          }
        }
      }
    }`;

    return query;
  }

  render() {
    const { countryCode } = this.state;

    return (
      <div className="container">
        <div className="row">
          <div className="row">
            <TextField
              placeholder="US"
              onChange={(event) => {
                this.setState({ countryCode: event.target.value });
              }}
            />
          </div>
          <TableChart
            accountId={accountId}
            query={`FROM PageView SELECT count(*), average(duration) WHERE appName = 'WebPortal' ${
              countryCode ? ` WHERE countryCode LIKE '%${countryCode}%' ` : ''
            } FACET countryCode, regionCode SINCE 1 week ago LIMIT 1000`}
            fullWidth
            className="chart"
          />
        </div>
      </div>
    );
  }
}
```

Feel free to change the HTML color code values to your taste. In this example, `#11A600` is green, `#FFD966` is sort of yellow, and `#BF0016` is red.

````

### Set your map's default center point

Set a default center point for your map using latitude and longitude.

````jsx fileName=pageview-app-nerdlet/index.js
import React from 'react';
import {
  TableChart,
  TextField,
  NerdGraphQuery,
  Spinner,
  Button,
  BlockText,
} from 'nr1';
import { Map, CircleMarker, TileLayer } from 'react-leaflet';

const accountId = 0; // Replace with your account ID

export default class PageViewApp extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      countryCode: null,
    };
  }

  getMarkerColor(measure, apdexTarget = 1.7) {
    if (measure <= apdexTarget) {
      return '#11A600';
    } else if (measure >= apdexTarget && measure <= apdexTarget * 4) {
      return '#FFD966';
    } else {
      return '#BF0016';
    }
  }

  mapData() {
    const { countryCode } = this.state;
    const query = `{
      actor {
        account(id: 1606862) {
          mapData: nrql(query: "SELECT count(*) AS 'x', average(duration) AS 'y', sum(asnLatitude)/count(*) AS 'lat', sum(asnLongitude)/count(*) AS 'lng' FROM PageView FACET regionCode, countryCode WHERE appName = 'WebPortal' ${
            countryCode ? ` WHERE countryCode LIKE '%${countryCode}%' ` : ''
          } LIMIT 1000 ") {
            results
            nrql
          }
        }
      }
    }`;

    return query;
  }

  render() {
    const { countryCode } = this.state;
    const defaultMapCenter = [10.5731, -7.5898];

    return (
      <div className="container">
        <div className="row">
          <div className="row">
            <TextField
              placeholder="US"
              onChange={(event) => {
                this.setState({ countryCode: event.target.value });
              }}
            />
          </div>
          <TableChart
            accountId={accountId}
            query={`FROM PageView SELECT count(*), average(duration) WHERE appName = 'WebPortal' ${
              countryCode ? ` WHERE countryCode LIKE '%${countryCode}%' ` : ''
            } FACET countryCode, regionCode SINCE 1 week ago LIMIT 1000`}
            fullWidth
            className="chart"
          />
        </div>
      </div>
    );
  }
}
```

````

### Add a row for your map [#add-row-map]

Between the text field row and the table chart row, insert a new row for the map content using `NerdGraphQuery`.

````jsx fileName=pageview-app-nerdlet/index.js
import React from 'react';
import {
  TableChart,
  TextField,
  NerdGraphQuery,
  Spinner,
  Button,
  BlockText,
} from 'nr1';
import { Map, CircleMarker, TileLayer } from 'react-leaflet';

const accountId = 0; // Replace with your account ID

export default class PageViewApp extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      countryCode: null,
    };
  }

  getMarkerColor(measure, apdexTarget = 1.7) {
    if (measure <= apdexTarget) {
      return '#11A600';
    } else if (measure >= apdexTarget && measure <= apdexTarget * 4) {
      return '#FFD966';
    } else {
      return '#BF0016';
    }
  }

  mapData() {
    const { countryCode } = this.state;
    const query = `{
      actor {
        account(id: 1606862) {
          mapData: nrql(query: "SELECT count(*) AS 'x', average(duration) AS 'y', sum(asnLatitude)/count(*) AS 'lat', sum(asnLongitude)/count(*) AS 'lng' FROM PageView FACET regionCode, countryCode WHERE appName = 'WebPortal' ${
            countryCode ? ` WHERE countryCode LIKE '%${countryCode}%' ` : ''
          } LIMIT 1000 ") {
            results
            nrql
          }
        }
      }
    }`;

    return query;
  }

  render() {
    const { countryCode } = this.state;
    const defaultMapCenter = [10.5731, -7.5898];

    return (
      <div className="container">
        <div className="row">
          <div className="row">
            <TextField
              placeholder="US"
              onChange={(event) => {
                this.setState({ countryCode: event.target.value });
              }}
            />
          </div>
          <div className="row">
            <NerdGraphQuery query={this.mapData()}>
              {({ loading, error, data }) => {
                if (loading) {
                  return <Spinner fillContainer />;
                }
                if (error) {
                  return 'Error';
                }
                const { results } = data.actor.account.mapData;
                console.debug(results);
                return 'Hello';
              }}
            </NerdGraphQuery>
          </div>
          <TableChart
            accountId={accountId}
            query={`FROM PageView SELECT count(*), average(duration) WHERE appName = 'WebPortal' ${
              countryCode ? ` WHERE countryCode LIKE '%${countryCode}%' ` : ''
            } FACET countryCode, regionCode SINCE 1 week ago LIMIT 1000`}
            fullWidth
            className="chart"
          />
        </div>
      </div>
    );
  }
}
```

Reload your application in New Relic to test that it works.

````

### Replace "Hello" with the Leaflet code [#replace-hello]

Replace `return "Hello";` with:

````jsx fileName=pageview-app-nerdlet/index.js
import React from 'react';
import {
  TableChart,
  TextField,
  NerdGraphQuery,
  Spinner,
  Button,
  BlockText,
} from 'nr1';
import { Map, CircleMarker, TileLayer } from 'react-leaflet';

const accountId = 0; // Replace with your account ID

export default class PageViewApp extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      countryCode: null,
    };
  }

  getMarkerColor(measure, apdexTarget = 1.7) {
    if (measure <= apdexTarget) {
      return '#11A600';
    } else if (measure >= apdexTarget && measure <= apdexTarget * 4) {
      return '#FFD966';
    } else {
      return '#BF0016';
    }
  }

  mapData() {
    const { countryCode } = this.state;
    const query = `{
      actor {
        account(id: 1606862) {
          mapData: nrql(query: "SELECT count(*) AS 'x', average(duration) AS 'y', sum(asnLatitude)/count(*) AS 'lat', sum(asnLongitude)/count(*) AS 'lng' FROM PageView FACET regionCode, countryCode WHERE appName = 'WebPortal' ${
            countryCode ? ` WHERE countryCode LIKE '%${countryCode}%' ` : ''
          } LIMIT 1000 ") {
            results
            nrql
          }
        }
      }
    }`;

    return query;
  }

  render() {
    const { countryCode } = this.state;
    const defaultMapCenter = [10.5731, -7.5898];

    return (
      <div className="container">
        <div className="row">
          <div className="row">
            <TextField
              placeholder="US"
              onChange={(event) => {
                this.setState({ countryCode: event.target.value });
              }}
            />
          </div>
          <div className="row">
            <NerdGraphQuery query={this.mapData()}>
              {({ loading, error, data }) => {
                if (loading) {
                  return <Spinner fillContainer />;
                }
                if (error) {
                  return 'Error';
                }
                const { results } = data.actor.account.mapData;
                console.debug(results);

                return (
                  <Map
                    className="containerMap"
                    center={defaultMapCenter}
                    zoom={2}
                    zoomControl
                  >
                    <TileLayer
                      attribution='&amp;copy <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
                      url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
                    />
                    {results.map((pt, i) => {
                      const center = [pt.lat, pt.lng];
                      return (
                        <CircleMarker
                          key={`circle-${i}`}
                          center={center}
                          color={this.getMarkerColor(pt.y)}
                          radius={Math.log(pt.x) * 3}
                          onClick={() => {
                            alert(JSON.stringify(pt));
                          }}
                        />
                      );
                    })}
                  </Map>
                );
              }}
            </NerdGraphQuery>
          </div>
          <TableChart
            accountId={accountId}
            query={`FROM PageView SELECT count(*), average(duration) WHERE appName = 'WebPortal' ${
              countryCode ? ` WHERE countryCode LIKR '%${countryCode}%' ` : ''
            } FACET countryCode, regionCode SINCE 1 week ago LIMIT 1000`}
            fullWidth
            className="chart"
          />
        </div>
      </div>
    );
  }
}
```

````

This code creates a world map centered on the latitude and longitude you chose using `OpenStreetMap` data and your marker colors.

Reload your app to see the pageview data on the map!
