diff --git a/src/data/nav.yml b/src/data/nav.yml
index 4b8e4eab1..53c5276b6 100644
--- a/src/data/nav.yml
+++ b/src/data/nav.yml
@@ -67,7 +67,6 @@
- title: Add, query, and mutate data using NerdStorage
url: '/build-apps/add-query-mutate-data-nerdstorage'
- title: Display your data in different ways with a custom visualization
- url: '/build-apps/custom-viz-alternate-charts'
pages:
- title: Custom visualizations and the New Relic One SDK
url: '/build-apps/custom-visualizations-and-the-new-relic-one-sdk'
diff --git a/src/images/build-an-app/click-add-to-dashboard.png b/src/images/build-an-app/click-add-to-dashboard.png
deleted file mode 100644
index cc490bcea..000000000
Binary files a/src/images/build-an-app/click-add-to-dashboard.png and /dev/null differ
diff --git a/src/images/build-an-app/click-app-button.png b/src/images/build-an-app/click-app-button.png
deleted file mode 100644
index 85e703ed2..000000000
Binary files a/src/images/build-an-app/click-app-button.png and /dev/null differ
diff --git a/src/images/build-an-app/configure-viz.png b/src/images/build-an-app/configure-viz.png
deleted file mode 100644
index a63081ff3..000000000
Binary files a/src/images/build-an-app/configure-viz.png and /dev/null differ
diff --git a/src/images/build-an-app/delete-viz.png b/src/images/build-an-app/delete-viz.png
deleted file mode 100644
index e078d01ca..000000000
Binary files a/src/images/build-an-app/delete-viz.png and /dev/null differ
diff --git a/src/images/build-an-app/select-dashboard.png b/src/images/build-an-app/select-dashboard.png
deleted file mode 100644
index 158f87398..000000000
Binary files a/src/images/build-an-app/select-dashboard.png and /dev/null differ
diff --git a/src/images/build-an-app/select-viz.png b/src/images/build-an-app/select-viz.png
deleted file mode 100644
index 3383a5956..000000000
Binary files a/src/images/build-an-app/select-viz.png and /dev/null differ
diff --git a/src/images/custom-viz/add-radar-or-treemap-to-dashboard.png b/src/images/custom-viz/add-radar-or-treemap-to-dashboard.png
new file mode 100644
index 000000000..e51d228dc
Binary files /dev/null and b/src/images/custom-viz/add-radar-or-treemap-to-dashboard.png differ
diff --git a/src/images/custom-viz/configure-radar-or-treemap-viz.png b/src/images/custom-viz/configure-radar-or-treemap-viz.png
new file mode 100644
index 000000000..9faa97b89
Binary files /dev/null and b/src/images/custom-viz/configure-radar-or-treemap-viz.png differ
diff --git a/src/images/custom-viz/confirm-delete-radar-viz.png b/src/images/custom-viz/confirm-delete-radar-viz.png
new file mode 100644
index 000000000..155e0c360
Binary files /dev/null and b/src/images/custom-viz/confirm-delete-radar-viz.png differ
diff --git a/src/images/custom-viz/create-sweet-new-dashboard.png b/src/images/custom-viz/create-sweet-new-dashboard.png
new file mode 100644
index 000000000..0a5150625
Binary files /dev/null and b/src/images/custom-viz/create-sweet-new-dashboard.png differ
diff --git a/src/images/build-an-app/custom-chart-type-configuration-prop.png b/src/images/custom-viz/custom-chart-type-configuration-prop.png
similarity index 100%
rename from src/images/build-an-app/custom-chart-type-configuration-prop.png
rename to src/images/custom-viz/custom-chart-type-configuration-prop.png
diff --git a/src/images/custom-viz/delete-radar-viz.png b/src/images/custom-viz/delete-radar-viz.png
new file mode 100644
index 000000000..b91a20612
Binary files /dev/null and b/src/images/custom-viz/delete-radar-viz.png differ
diff --git a/src/images/custom-viz/select-chart-config-option.png b/src/images/custom-viz/select-chart-config-option.png
new file mode 100644
index 000000000..79205f332
Binary files /dev/null and b/src/images/custom-viz/select-chart-config-option.png differ
diff --git a/src/images/custom-viz/select-published-radar-or-treemap-viz.png b/src/images/custom-viz/select-published-radar-or-treemap-viz.png
new file mode 100644
index 000000000..7f3f3c968
Binary files /dev/null and b/src/images/custom-viz/select-published-radar-or-treemap-viz.png differ
diff --git a/src/images/custom-viz/view-sweet-new-dashboard.png b/src/images/custom-viz/view-sweet-new-dashboard.png
new file mode 100644
index 000000000..10bf951c7
Binary files /dev/null and b/src/images/custom-viz/view-sweet-new-dashboard.png differ
diff --git a/src/markdown-pages/build-apps/add-visualizations-to-dashboard.mdx b/src/markdown-pages/build-apps/add-visualizations-to-dashboard.mdx
index 44e5cca89..31cbd11ed 100644
--- a/src/markdown-pages/build-apps/add-visualizations-to-dashboard.mdx
+++ b/src/markdown-pages/build-apps/add-visualizations-to-dashboard.mdx
@@ -5,20 +5,14 @@ title: 'Add custom visualizations to your dashboards'
template: 'GuideTemplate'
description: 'Add your custom visualization to a New Relic dashboard'
resources:
- - title: Build custom visualizations for dashboards
+ - title: Build a custom visualization for dashboards
url: '/build-apps/build-visualization'
- - title: Custom visualizations and the New Relic One SDK
- url: '/build-apps/custom-visualizations-and-the-new-relic-one-sdk'
- - title: Customize visualizations with configuration
- url: '/build-apps/customize-visualizations-with-configuration'
- - title: Add custom visualizations to your dashboards
- url: '/build-apps/add-visualizations-to-dashboard'
- - title: 'Build on New Relic One'
- url: https://docs.newrelic.com/docs/new-relic-one/use-new-relic-one/build-new-relic-one/new-relic-one-build-your-own-custom-new-relic-one-application
- - title: New Relic One VSCode extension
- url: https://marketplace.visualstudio.com/items?itemName=new-relic.nr1
- - title: New Relic VSCode extension pack
- url: https://marketplace.visualstudio.com/items?itemName=new-relic.new-relic-extension-pack
+ - title: Dashboards and Custom Visualizations
+ url: https://www.youtube.com/watch?v=_F61mxtKfGA
+ - title: 'Configuring custom visualizations for dashboards'
+ url: https://www.youtube.com/watch?v=sFpG_iG7Xa8
+ - title: Custom Data Visualizations on New Relic
+ url: https://www.youtube.com/watch?v=HuR0EdHGz24
tags:
- nr1 cli
- NR One Catalog
@@ -27,136 +21,138 @@ tags:
-This lesson builds off of the previous [Customize visualizations with configuration](/build-apps/customize-visualizations-with-configuration) lesson. If you haven't followed that lesson, please start there as this lesson assumes you have the code you built there to get started.
+In the previous lesson, you added a configuration option to your visualization that allows you to choose how you want to represent your data. This was different from the previous version of your code because, while you can still choose your chart type, you can now only only do it before you create an instance of your visualization. But what does it mean to create an instance of your visualization? How do you use a visualization once you've configured it?
-If you don't have a visualization to follow the examples in this gude, a accompanying example visualization is available on [GitHub](https://github.com/newrelic/nru-custom-visualization-course)
+In this lesson, you'll learn how to create an instance of your visualization and add that instance to dashboard.
-Following the previous lesson, you reconfigured your visualization to use the platform configurations panel removing the unneeded `SegmentedControl` component. Now that you can customize your visualization using nr1.json configuration, in the following steps, you will configure and add your custom visualization to a New Relic dashboard.
+
+
+If you got lost in the previous steps and would like to see what your files should look like to start this lesson, check out the [course project](https://github.com/newrelic/nru-custom-visualization-course) on Github.
+
+
-## Before you begin
+## Add your custom visualization to a dashboard
+
+Once you've published your custom visualization to your account, in the following steps you'll configure your visualization and add it to a dashboard. You can add a visualization to a new or existing dashboard within your New Relic account.
+
+
+
+
-To get started, follow the [Customize visualizations with configuration](/build-apps/customize-visualizations-with-configuration) lesson. Then, [publish and subscribe to your Nerdpack](/build-apps/publish-deploy).
+From the root directory of your Nerdpack, [publish and subscribe](/build-apps/publish-deploy) to your visualization:
-
+```sh
+nr1 nerdpack:publish
+nr1 nerdpack:subscribe
+```
-To publish a Nerdpack you must be a Full user and granted the Nerdpacks “modify” privilege (which is granted by default).
+
-Read our documentation to learn more about [Nerdpacks privileges](https://developer.newrelic.com/build-apps/permission-manage-apps/).
+To publish a Nerdpack you must be a Full user with the Nerdpacks “modify” privilege (this is granted by default).
+
+Read our [Nerdpacks privileges](https://developer.newrelic.com/build-apps/permission-manage-apps/) documentation to learn more.
-## Add your custom visualization to a dashboard
+Next, find your published visualization in the New Relic One app catalog.
-Once you've published your custom visualization to your account, in the following steps you'll configure your visualization and add it to a dashboard. You can add a visualization to a new or existing dashboard within your New Relic account.
+
-
+
+
+From the [New Relic homepage](https://one.newrelic.com), select the **Apps** button in the top right navigation bar:
-
+![Click the apps button in New Relic One](../../images/build-an-app/nav-to-apps.png)
- To find the **My Awesome Visualization** that you have deployed, you need to look for your visualization in the app catalog. From the [New Relic One homepage](https://one.newrelic.com), select the **Apps** button in the top right navigation bar:
+
-
+
+
+From the **Apps** page, click the **Custom Visualizations** launcher:
+
+![Select the custom visualization launcher](../../images/build-an-app/nav-to-custom-viz.png)
- Once on the **Apps** page, click the **Custom Visualizations** launcher:
+Select **RadarOrTreemap**:
-
+![Select your desired visualization](../../images/custom-viz/select-published-radar-or-treemap-viz.png)
+
-
+
- If you don't see the **Custom Visualizations** tile, use the search to locate it.
+In the previous lesson, you changed your visualization to use the platform configurations panel for selecting a chart type. Use this panel options to configure your chart:
-
+![Configure your visualization](../../images/custom-viz/configure-radar-or-treemap.png)
-
+
-
+
- In **Custom Visualizations**, you will see all of the visualization that have been deployed to your account and any visualizations you are serving locally.
+Click **Add to dashboard** and then select a dashboard from the list of available dashboards, or select **New dashboard**:
- Select the **My Awesome Visualization** to add to a dashboard and then enable it:
+![Click the add to dashboard button](../../images/custom-viz/add-radar-or-treemap-to-dashboard.png)
-
+If you decide to create a new dashboard, select an account and a name:
-
+![Select the dashboard](../../images/custom-viz/create-sweet-new-dashboard.png)
-
+Click **Add to dashboard**.
- In the previous lesson, you reconfigured your visualization to use the platform configurations panel. Use the configuration options to select your desired chart, select your account, insert a NRQL query, and any other configurations you desire.
+
- As you make your selections, the visualization will update with your changes:
+
-
+Go to your dashboard to see your custom visualization:
-
+![View the dashboard](../../images/custom-viz/view-sweet-new-dashboard.png)
-
+
- Click **Add to dashboard** and then select a dashboard from the list of available dashboards, or select **New dashboard**:
+
-
+## Delete your visualization
- If you decide to create a new dashboard, select the account where you want to run the dashboard, and give the dashboard a name:
+Once you've added your visualization to a dashboard, you can't edit it. You can't change the underyling query, account ID, chart type, or any other previously configurable option. So, if you're not happy with your visualization, delete it from your dashboard and walk through the steps in this guide again to add a new instance.
-
+
-
+
-
+Click the ellipses button in the right-hand corner of the visualization, and click **Delete**:
- Click **Add to dashboard**, then click the link to your dashboard to see the custom visualization:
+![Delete your visualization](../../images/custom-viz/delete-radar-viz.png)
-
+
-
+
-
+Confirm that you want to delete your visualization:
-## Manage your dashboard visualizations
-**Deleting:** To remove a visualization from a dashboard, click the ellipses button in the right-hand corner of the visualization and click delete.
+![Confirm](../../images/custom-viz/confirm-delete-radar-viz.png)
-
+
-**Editing:** If your visualization needs some tweaking, delete the visualization, then follow the steps above to re-add the visualization, making any updates in Custom Visualizations.
+
## Summary
-Congratulations on completing this final lesson and adding your custom visualization to a New Relic dashboard. In the previous lessons, you've used the tools in the New Relic SDK to create a new custom visualization, configured the visualization using the SDK and using the platform configuration panel.
+Congratulations on completing this final lesson! Throughout this course, you:
+
+- Created a new custom visualization with the New Relic One SDK
+- Configured your visualization using the SDK and configuration options
+- Added your visualization to a dashboard
-## Additional resources
+To learn more about custom visualizations, check out the following resources:
- New Relic Quick Tips video: [Dashboards and Custom Visualizations](https://www.youtube.com/watch?v=_F61mxtKfGA) (6 minutes)
- New Relic NerdBytes video: [Configuring custom visualizations for dashboards](https://www.youtube.com/watch?v=sFpG_iG7Xa8) (7 minutes)
- New Relic Nerdlog live stream: [Custom Data Visualizations on New Relic](https://www.youtube.com/watch?v=HuR0EdHGz24) (30 minutes)
- New Relic One SDK components: Intro to New Relic One SDK Component library
+Or, to learn more about other cool things you can build with the New Relic One SDK, check out our [apps course](/ab-test)!
diff --git a/src/markdown-pages/build-apps/customize-visualization-with-New-Relic-components.mdx b/src/markdown-pages/build-apps/customize-visualization-with-New-Relic-components.mdx
index c1ed65918..6d7f6f3f0 100644
--- a/src/markdown-pages/build-apps/customize-visualization-with-New-Relic-components.mdx
+++ b/src/markdown-pages/build-apps/customize-visualization-with-New-Relic-components.mdx
@@ -19,11 +19,9 @@ tags:
- Subscribe visualizations
---
-
+
-This lesson is part of a course that teaches you how to build a New Relic One custom visualization from the ground up. If you haven't already, check out the [course introduction](/build-apps/ab-test).
-
-Each lesson in the course builds upon the last, so make sure you've completed the last lesson, [_Present an end test confirmation modal_](../confirmation-modal), before starting this one.
+This lesson is part of a course that teaches you how to build a custom visualization in the New Relic One platform
@@ -33,6 +31,12 @@ Use New Relic One custom visualizations to display your data, whether it's from
In this lesson, you build a visualization that displays your data in one of two chart types: [`RadarChart`](https://recharts.org/en-US/api/RadarChart) or [`Treemap`](https://recharts.org/en-US/api/Treemap). You then implement a `SegmentedControl` component from the New Relic One SDK, which allows you to alternate between the two chart types. Ultimately, this gives you freedom to view your data in a dynamic way that isn't possible with New Relic's base offerings.
+
+
+If you get lost in the code project and would like to see what the files should look like when you're done with each lesson, check out the [course project](https://github.com/newrelic/nru-custom-visualization-course) on Github.
+
+
+
## Before you begin
@@ -2045,7 +2049,7 @@ Use `state.selectedChart` to determine which chart to show: the `RadarChart` or
-Compare `state.selectedChart` to `CHART_TYPES.Radar`. If they are the same, render a `RadarChart`. Otherwise, render a `Treemap`:
+Destructure `this.state` to access `selectedChart` as a separate constant. Then, compare `selectedChart` to `CHART_TYPES.Radar`. If they are the same, render a `RadarChart`. Otherwise, render a `Treemap`:
```js fileName=visualizations/radar-or-treemap/index.js
import React from 'react';
@@ -2131,6 +2135,7 @@ export default class RadarOrTreemapVisualization extends React.Component {
render() {
const {nrqlQueries, stroke, fill} = this.props;
+ const {selectedChart} = this.state;
const nrqlQueryPropsAvailable =
nrqlQueries &&
@@ -2175,7 +2180,7 @@ export default class RadarOrTreemapVisualization extends React.Component {
label="Treemap chart"
/>
- {this.state.selectedChart === CHART_TYPES.Radar ? (
+ {selectedChart === CHART_TYPES.Radar ? (
-This guide builds off of the previous Custom visualizations and the New Relic One SDK guide. If you haven't followed that guide, please start there as this guide assumes you have the code you built there to get started.
+In the previous lesson, you built a custom visualization that shows queried data in one of two chart types:
-Following the previous guide, your current visualization should be able to switch between two charts types. Your current implementation takes up some space in the visualization but offers your users the choice to switch between two chart types at any point in the visualization lifecycle. What if you only need to be able to select an option once, when adding it to the dashboard? In that case, you can use the `configuration` key in your visualization's nr1.json file. In the following steps, you'll replace the `SegmentedControl` component with an option in the `configuration` array.
+- [`RadarChart`](https://recharts.org/en-US/api/RadarChart)
+- [`Treemap`](https://recharts.org/en-US/api/Treemap)
+
+You used a `SegmentedControl` to switch between the two chart types in the visualization UI. This implementation takes up space in the visualization, but it offers your users the choice to switch between two chart types even after you've created an instance of your chart. But what if you only need to be able to select an option once, when initializing the visualization?
+
+In this lesson you'll learn how to add a configuration option to your visualization which replaces the `SegmentedControl`.
+
+
+
+If you get lost in the code project and would like to see what the files should look like when you're done with each lesson, check out the [course project](https://github.com/newrelic/nru-custom-visualization-course) on Github.
+
+
@@ -31,7 +42,7 @@ Following the previous guide, your current visualization should be able to switc
-```jsx fileName=visualizations/your-visualization/index.js
+```js fileName=visualizations/radar-or-treemap/index.js
import React from 'react';
import PropTypes from 'prop-types';
import {
@@ -43,20 +54,22 @@ import {
Treemap,
} from 'recharts';
import {
- Card,
- CardBody,
- HeadingText,
- NrqlQuery,
- SegmentedControl,
- SegmentedControlItem,
- Spinner,
- AutoSizer
+ AutoSizer,
+ Card,
+ CardBody,
+ HeadingText,
+ NrqlQuery,
+ SegmentedControl,
+ SegmentedControlItem,
+ Spinner,
} from 'nr1';
+
const CHART_TYPES = {
'Radar': 'radar',
'Treemap': 'treemap'
}
-export default class YourAwesomeVisualization extends React.Component {
+
+export default class RadarOrTreemapVisualization extends React.Component {
// Custom props you wish to be configurable in the UI must also be defined in
// the nr1.json file for the visualization. See docs for more details.
static propTypes = {
@@ -65,6 +78,7 @@ export default class YourAwesomeVisualization extends React.Component {
* a custom chart configuration.
*/
fill: PropTypes.string,
+
/**
* A stroke color to override the default stroke color. This is an example of
* a custom chart configuration.
@@ -80,14 +94,12 @@ export default class YourAwesomeVisualization extends React.Component {
query: PropTypes.string,
})
),
- /**
- * A chart type configuration to switch between "Radar" and "Treemap" chart types
- */
- selectedChart: PropTypes.string
};
+
state = {
- selectedChart: CHART_TYPES.Radar
- }
+ selectedChart: CHART_TYPES.Radar,
+ };
+
/**
* Restructure the data for a non-time-series, facet-based NRQL query into a
* form accepted by the Recharts library's RadarChart.
@@ -100,6 +112,7 @@ export default class YourAwesomeVisualization extends React.Component {
value: entry.data[0].y,
}));
};
+
/**
* Format the given axis tick's numeric value into a string for display.
*/
@@ -113,15 +126,18 @@ export default class YourAwesomeVisualization extends React.Component {
render() {
const {nrqlQueries, stroke, fill} = this.props;
- const { selectedChart } = this.state;
+ const {selectedChart} = this.state;
+
const nrqlQueryPropsAvailable =
nrqlQueries &&
nrqlQueries[0] &&
nrqlQueries[0].accountId &&
nrqlQueries[0].query;
+
if (!nrqlQueryPropsAvailable) {
return ;
}
+
return (
{({width, height}) => (
@@ -134,25 +150,29 @@ export default class YourAwesomeVisualization extends React.Component {
if (loading) {
return ;
}
+
if (error) {
return ;
}
+
const transformedData = this.transformData(data);
+
return (
-
-
-
-
- {
- selectedChart === CHART_TYPES.Radar ?
- (
+
+
+
+ {selectedChart === CHART_TYPES.Radar ? (
+
- )
- :
- (
+ ) : (
+ )}
+ stroke={stroke || '#000000'}
+ fill={fill || '#51C9B7'}
+ />
+ )}
);
}}
@@ -187,7 +208,6 @@ export default class YourAwesomeVisualization extends React.Component {
}
}
-
const EmptyState = () => (
@@ -207,6 +227,7 @@ const EmptyState = () => (
);
+
const ErrorState = () => (
@@ -222,11 +243,11 @@ const ErrorState = () => (
);
```
-```json fileName=visualizations/your-visualization/nr1.json lineHighlight=7-22 lineNumbers=true
+```js fileName=visualizations/radar-or-treemap/nr1.json
{
"schemaType": "VISUALIZATION",
- "id": "your-awesome-visualization",
- "displayName": "Your Awesome Visualization",
+ "id": "radar-or-treemap",
+ "displayName": "RadarOrTreemap",
"description": "",
"configuration": [
{
@@ -266,23 +287,19 @@ const ErrorState = () => (
-## Before you begin
-
-To get started, make sure you follow the Custom visualizations and the New Relic One SDK guide. You should have that code as your starting point for this guide.
-
-## Replace the SegmentedControl with configuration
+## Add a new configuration option
-
+
-In you visualization's root folder, open the `nr1.json` file. Add an `enum` configuration object for `selectedChart`:
+In your visualization's _nr1.json_ file, add an `enum` configuration object for `selectedChart`:
-```json fileName=visualizations/your-visualization/nr1.json
+```js fileName=visualizations/radar-or-treemap/nr1.json
{
"schemaType": "VISUALIZATION",
- "id": "your-awesome-visualization",
- "displayName": "Your Awesome Visualization",
+ "id": "radar-or-treemap",
+ "displayName": "RadarOrTreemap",
"description": "",
"configuration": [
{
@@ -336,408 +353,83 @@ In you visualization's root folder, open the `nr1.json` file. Add an `enum` conf
}
```
-This should look familiar to the component state options you added in the previous guide.
+
-
+
-
+Navigate to the root of your Nerdpack at _alternate-viz_.
-In your visualization's root folder, open `index.js`. You'll be working in this file for the rest of the guide:
+
-```jsx fileName=visualizations/your-visualization/index.js
-import React from 'react';
-import PropTypes from 'prop-types';
-import {
- Radar,
- RadarChart,
- PolarGrid,
- PolarAngleAxis,
- PolarRadiusAxis,
- Treemap,
-} from 'recharts';
-import {
- Card,
- CardBody,
- HeadingText,
- NrqlQuery,
- SegmentedControl,
- SegmentedControlItem,
- Spinner,
- AutoSizer
-} from 'nr1';
-const CHART_TYPES = {
- 'Radar': 'radar',
- 'Treemap': 'treemap'
-}
-export default class YourAwesomeVisualization extends React.Component {
- // Custom props you wish to be configurable in the UI must also be defined in
- // the nr1.json file for the visualization. See docs for more details.
- static propTypes = {
- /**
- * A fill color to override the default fill color. This is an example of
- * a custom chart configuration.
- */
- fill: PropTypes.string,
- /**
- * A stroke color to override the default stroke color. This is an example of
- * a custom chart configuration.
- */
- stroke: PropTypes.string,
- /**
- * An array of objects consisting of a nrql `query` and `accountId`.
- * This should be a standard prop for any NRQL based visualizations.
- */
- nrqlQueries: PropTypes.arrayOf(
- PropTypes.shape({
- accountId: PropTypes.number,
- query: PropTypes.string,
- })
- ),
- /**
- * A chart type configuration to switch between "Radar" and "Treemap" chart types
- */
- selectedChart: PropTypes.string
- };
- state = {
- selectedChart: CHART_TYPES.Radar
- }
- /**
- * Restructure the data for a non-time-series, facet-based NRQL query into a
- * form accepted by the Recharts library's RadarChart.
- * (https://recharts.org/api/RadarChart).
- */
- transformData = (rawData) => {
- return rawData.map((entry) => ({
- name: entry.metadata.name,
- // Only grabbing the first data value because this is not time-series data.
- value: entry.data[0].y,
- }));
- };
- /**
- * Format the given axis tick's numeric value into a string for display.
- */
- formatTick = (value) => {
- return value.toLocaleString();
- };
+
- updateSelectedChart = (evt, value) => {
- this.setState({ selectedChart: value })
- };
+[Serve your Nerdpack locally](/build-apps/publish-deploy/serve/):
- render() {
- const {nrqlQueries, stroke, fill} = this.props;
- const { selectedChart } = this.state;
- const nrqlQueryPropsAvailable =
- nrqlQueries &&
- nrqlQueries[0] &&
- nrqlQueries[0].accountId &&
- nrqlQueries[0].query;
- if (!nrqlQueryPropsAvailable) {
- return ;
- }
- return (
-
- {({width, height}) => (
-
- {({data, loading, error}) => {
- if (loading) {
- return ;
- }
- if (error) {
- return ;
- }
- const transformedData = this.transformData(data);
- return (
-
-
-
-
-
- {
- selectedChart === CHART_TYPES.Radar ?
- (
-
-
-
-
- )
- :
- ()}
-
- );
- }}
-
- )}
-
- );
- }
-}
-
-const EmptyState = () => (
-
-
-
- Please provide at least one NRQL query & account ID pair
-
-
- An example NRQL query you can try is:
-
- FROM NrUsage SELECT sum(usage) FACET metric SINCE 1 week ago
-
-
-);
-const ErrorState = () => (
-
-
-
- Oops! Something went wrong.
-
-
-
-);
+```bash
+nr1 nerdpack:serve
```
+If you're still serving your Nerdpack from the last lesson, you need to stop it with `CTRL-X` and serve it again to reflect changes to _nr1.json_.
+
-In `render()`, add `selectedChart` to the prop descrtructuring and remove the state reference:
+Go to [https://one.newrelic.com/?nerdpacks=local](https://one.newrelic.com/?nerdpacks=local). The `nerdpacks=local` query string directs the UI to load your visualization from the local server.
-```jsx fileName=visualizations/your-visualization/index.js
-import React from 'react';
-import PropTypes from 'prop-types';
-import {
- Radar,
- RadarChart,
- PolarGrid,
- PolarAngleAxis,
- PolarRadiusAxis,
- Treemap,
-} from 'recharts';
-import {
- Card,
- CardBody,
- HeadingText,
- NrqlQuery,
- SegmentedControl,
- SegmentedControlItem,
- Spinner,
- AutoSizer
-} from 'nr1';
-const CHART_TYPES = {
- 'Radar': 'radar',
- 'Treemap': 'treemap'
-}
-export default class YourAwesomeVisualization extends React.Component {
- // Custom props you wish to be configurable in the UI must also be defined in
- // the nr1.json file for the visualization. See docs for more details.
- static propTypes = {
- /**
- * A fill color to override the default fill color. This is an example of
- * a custom chart configuration.
- */
- fill: PropTypes.string,
- /**
- * A stroke color to override the default stroke color. This is an example of
- * a custom chart configuration.
- */
- stroke: PropTypes.string,
- /**
- * An array of objects consisting of a nrql `query` and `accountId`.
- * This should be a standard prop for any NRQL based visualizations.
- */
- nrqlQueries: PropTypes.arrayOf(
- PropTypes.shape({
- accountId: PropTypes.number,
- query: PropTypes.string,
- })
- ),
- /**
- * A chart type configuration to switch between "Radar" and "Treemap" chart types
- */
- selectedChart: PropTypes.string
- };
- state = {
- selectedChart: CHART_TYPES.Radar
- }
- /**
- * Restructure the data for a non-time-series, facet-based NRQL query into a
- * form accepted by the Recharts library's RadarChart.
- * (https://recharts.org/api/RadarChart).
- */
- transformData = (rawData) => {
- return rawData.map((entry) => ({
- name: entry.metadata.name,
- // Only grabbing the first data value because this is not time-series data.
- value: entry.data[0].y,
- }));
- };
- /**
- * Format the given axis tick's numeric value into a string for display.
- */
- formatTick = (value) => {
- return value.toLocaleString();
- };
+
- updateSelectedChart = (evt, value) => {
- this.setState({ selectedChart: value })
- };
+
- render() {
- const {nrqlQueries, stroke, fill, selectedChart} = this.props;
- // const { selectedChart } = this.state;
- const nrqlQueryPropsAvailable =
- nrqlQueries &&
- nrqlQueries[0] &&
- nrqlQueries[0].accountId &&
- nrqlQueries[0].query;
- if (!nrqlQueryPropsAvailable) {
- return ;
- }
- return (
-
- {({width, height}) => (
-
- {({data, loading, error}) => {
- if (loading) {
- return ;
- }
- if (error) {
- return ;
- }
- const transformedData = this.transformData(data);
- return (
-
-
-
-
-
- {
- selectedChart === CHART_TYPES.Radar ?
- (
-
-
-
-
- )
- :
- ()}
-
- );
- }}
-
- )}
-
- );
- }
-}
+Open the **Apps** page:
+![Apps navigation is located in the New Relic One top navigation](../../images/build-an-app/nav-to-apps.png)
-const EmptyState = () => (
-
-
-
- Please provide at least one NRQL query & account ID pair
-
-
- An example NRQL query you can try is:
-
- FROM NrUsage SELECT sum(usage) FACET metric SINCE 1 week ago
-
-
-);
-const ErrorState = () => (
-
-
-
- Oops! Something went wrong.
-
-
-
-);
-```
+
+
+
+
+Go to **Custom Visualizations**, which is favorited by default:
+
+![Navigate to Custom Visualizations](../../images/build-an-app/nav-to-custom-viz.png)
+
+
+
+
+
+In **Custom Visualizations**, find and click your visualization:
+
+![Navigate to your visualization](../../images/custom-viz/nav-to-radar-or-treemap-viz.png)
+
+
+
+
+
+Notice the new **Select chart** configuration option:
+
+![Select chart config option](../../images/custom-viz/select-chart-config-option.png)
+
+Selecting a chart type doesn't effect your visualization. This is because you first need to introduce the `selectedChart` property to the visualization component. Then, you use `selectedChart` to determine the chart type to render.
+
+
+
+
+
+## Replace your `SegmentedControl` with the configurable property
-
+
+
+
+
+Open your visualization's _index.js_ file. You'll be working here for the rest of the guide.
-
+
+
+
-You no longer have a default chart defined at this point, but you still want the Radar chart to be the default. Add more to the ternary in the render to achieve the same default state as you had previously:
+In `render()`, include `selectedChart` as a constant you get from destructuring `props`, and remove your component's `state`:
-```jsx fileName=visualizations/your-visualization/index.js
+```js fileName=visualizations/radar-or-treemap/index.js
import React from 'react';
import PropTypes from 'prop-types';
import {
@@ -749,20 +441,22 @@ import {
Treemap,
} from 'recharts';
import {
- Card,
- CardBody,
- HeadingText,
- NrqlQuery,
- SegmentedControl,
- SegmentedControlItem,
- Spinner,
- AutoSizer
+ AutoSizer,
+ Card,
+ CardBody,
+ HeadingText,
+ NrqlQuery,
+ SegmentedControl,
+ SegmentedControlItem,
+ Spinner,
} from 'nr1';
+
const CHART_TYPES = {
'Radar': 'radar',
'Treemap': 'treemap'
}
-export default class YourAwesomeVisualization extends React.Component {
+
+export default class RadarOrTreemapVisualization extends React.Component {
// Custom props you wish to be configurable in the UI must also be defined in
// the nr1.json file for the visualization. See docs for more details.
static propTypes = {
@@ -771,6 +465,7 @@ export default class YourAwesomeVisualization extends React.Component {
* a custom chart configuration.
*/
fill: PropTypes.string,
+
/**
* A stroke color to override the default stroke color. This is an example of
* a custom chart configuration.
@@ -786,14 +481,8 @@ export default class YourAwesomeVisualization extends React.Component {
query: PropTypes.string,
})
),
- /**
- * A chart type configuration to switch between "Radar" and "Treemap" chart types
- */
- selectedChart: PropTypes.string
};
- state = {
- selectedChart: CHART_TYPES.Radar
- }
+
/**
* Restructure the data for a non-time-series, facet-based NRQL query into a
* form accepted by the Recharts library's RadarChart.
@@ -806,6 +495,7 @@ export default class YourAwesomeVisualization extends React.Component {
value: entry.data[0].y,
}));
};
+
/**
* Format the given axis tick's numeric value into a string for display.
*/
@@ -813,21 +503,19 @@ export default class YourAwesomeVisualization extends React.Component {
return value.toLocaleString();
};
- updateSelectedChart = (evt, value) => {
- this.setState({ selectedChart: value })
- };
-
render() {
const {nrqlQueries, stroke, fill, selectedChart} = this.props;
- // const { selectedChart } = this.state;
+
const nrqlQueryPropsAvailable =
nrqlQueries &&
nrqlQueries[0] &&
nrqlQueries[0].accountId &&
nrqlQueries[0].query;
+
if (!nrqlQueryPropsAvailable) {
return ;
}
+
return (
{({width, height}) => (
@@ -840,25 +528,27 @@ export default class YourAwesomeVisualization extends React.Component {
if (loading) {
return ;
}
+
if (error) {
return ;
}
+
const transformedData = this.transformData(data);
+
return (
-
-
-
-
- {
- selectedChart === CHART_TYPES.Radar || !Boolean(selectedChart) ?
- (
+
+
+
+ {selectedChart === CHART_TYPES.Radar ? (
+
- )
- :
- (
+ ) : (
+ )}
+ stroke={stroke || '#000000'}
+ fill={fill || '#51C9B7'}
+ />
+ )}
);
}}
@@ -893,7 +584,6 @@ export default class YourAwesomeVisualization extends React.Component {
}
}
-
const EmptyState = () => (
@@ -913,6 +603,7 @@ const EmptyState = () => (
);
+
const ErrorState = () => (
@@ -928,13 +619,15 @@ const ErrorState = () => (
);
```
-
+Now that you're using `selectedChart` from the configuration options instead of component `state`, you can select a chart in the web UI and watch the visualization change. Unfortunately, there's a bug. The default chart option is **Radar**, but the initial render shows a Treemap.
+
+
-
+
-You no longer need `SegmentedControl`, so remove it from `render()`:
+Update your ternary expression to account for the case where there is no `selectedChart`:
-```jsx fileName=visualizations/your-visualization/index.js
+```js fileName=visualizations/radar-or-treemap/index.js
import React from 'react';
import PropTypes from 'prop-types';
import {
@@ -946,20 +639,22 @@ import {
Treemap,
} from 'recharts';
import {
- Card,
- CardBody,
- HeadingText,
- NrqlQuery,
- SegmentedControl,
- SegmentedControlItem,
- Spinner,
- AutoSizer
+ AutoSizer,
+ Card,
+ CardBody,
+ HeadingText,
+ NrqlQuery,
+ SegmentedControl,
+ SegmentedControlItem,
+ Spinner,
} from 'nr1';
+
const CHART_TYPES = {
'Radar': 'radar',
'Treemap': 'treemap'
}
-export default class YourAwesomeVisualization extends React.Component {
+
+export default class RadarOrTreemapVisualization extends React.Component {
// Custom props you wish to be configurable in the UI must also be defined in
// the nr1.json file for the visualization. See docs for more details.
static propTypes = {
@@ -968,6 +663,7 @@ export default class YourAwesomeVisualization extends React.Component {
* a custom chart configuration.
*/
fill: PropTypes.string,
+
/**
* A stroke color to override the default stroke color. This is an example of
* a custom chart configuration.
@@ -983,14 +679,8 @@ export default class YourAwesomeVisualization extends React.Component {
query: PropTypes.string,
})
),
- /**
- * A chart type configuration to switch between "Radar" and "Treemap" chart types
- */
- selectedChart: PropTypes.string
};
- state = {
- selectedChart: CHART_TYPES.Radar
- }
+
/**
* Restructure the data for a non-time-series, facet-based NRQL query into a
* form accepted by the Recharts library's RadarChart.
@@ -1003,6 +693,7 @@ export default class YourAwesomeVisualization extends React.Component {
value: entry.data[0].y,
}));
};
+
/**
* Format the given axis tick's numeric value into a string for display.
*/
@@ -1010,21 +701,19 @@ export default class YourAwesomeVisualization extends React.Component {
return value.toLocaleString();
};
- updateSelectedChart = (evt, value) => {
- this.setState({ selectedChart: value })
- };
-
render() {
const {nrqlQueries, stroke, fill, selectedChart} = this.props;
- // const { selectedChart } = this.state;
+
const nrqlQueryPropsAvailable =
nrqlQueries &&
nrqlQueries[0] &&
nrqlQueries[0].accountId &&
nrqlQueries[0].query;
+
if (!nrqlQueryPropsAvailable) {
return ;
}
+
return (
{({width, height}) => (
@@ -1037,27 +726,27 @@ export default class YourAwesomeVisualization extends React.Component {
if (loading) {
return ;
}
+
if (error) {
return ;
}
+
const transformedData = this.transformData(data);
+
return (
- /* CAN REMOVE
-
-
-
-
- */
- {
- selectedChart === CHART_TYPES.Radar || !Boolean(selectedChart) ?
- (
+
+
+
+ {!selectedChart || selectedChart === CHART_TYPES.Radar ? (
+
- )
- :
- (
+ ) : (
+ )}
+ stroke={stroke || '#000000'}
+ fill={fill || '#51C9B7'}
+ />
+ )}
);
}}
@@ -1092,7 +782,6 @@ export default class YourAwesomeVisualization extends React.Component {
}
}
-
const EmptyState = () => (
@@ -1112,6 +801,7 @@ const EmptyState = () => (
);
+
const ErrorState = () => (
@@ -1127,13 +817,15 @@ const ErrorState = () => (
);
```
-
+Now, your data is rendered in a `RadarChart` if you haven't yet configured the option.
-
+
-Delete all of the component state code:
+
-```jsx fileName=visualizations/your-visualization/index.js
+Remove `SegmentedControl` from `render()`:
+
+```js fileName=visualizations/radar-or-treemap/index.js
import React from 'react';
import PropTypes from 'prop-types';
import {
@@ -1145,20 +837,20 @@ import {
Treemap,
} from 'recharts';
import {
- Card,
- CardBody,
- HeadingText,
- NrqlQuery,
- SegmentedControl,
- SegmentedControlItem,
- Spinner,
- AutoSizer
+ AutoSizer,
+ Card,
+ CardBody,
+ HeadingText,
+ NrqlQuery,
+ Spinner,
} from 'nr1';
+
const CHART_TYPES = {
'Radar': 'radar',
'Treemap': 'treemap'
}
-export default class YourAwesomeVisualization extends React.Component {
+
+export default class RadarOrTreemapVisualization extends React.Component {
// Custom props you wish to be configurable in the UI must also be defined in
// the nr1.json file for the visualization. See docs for more details.
static propTypes = {
@@ -1167,6 +859,7 @@ export default class YourAwesomeVisualization extends React.Component {
* a custom chart configuration.
*/
fill: PropTypes.string,
+
/**
* A stroke color to override the default stroke color. This is an example of
* a custom chart configuration.
@@ -1182,14 +875,8 @@ export default class YourAwesomeVisualization extends React.Component {
query: PropTypes.string,
})
),
- /**
- * A chart type configuration to switch between "Radar" and "Treemap" chart types
- */
- selectedChart: PropTypes.string
};
- /* state = {
- selectedChart: CHART_TYPES.Radar
- } */
+
/**
* Restructure the data for a non-time-series, facet-based NRQL query into a
* form accepted by the Recharts library's RadarChart.
@@ -1202,29 +889,27 @@ export default class YourAwesomeVisualization extends React.Component {
value: entry.data[0].y,
}));
};
+
/**
* Format the given axis tick's numeric value into a string for display.
*/
formatTick = (value) => {
return value.toLocaleString();
};
- /*
- updateSelectedChart = (evt, value) => {
- this.setState({ selectedChart: value })
- };
- */
render() {
const {nrqlQueries, stroke, fill, selectedChart} = this.props;
- // const { selectedChart } = this.state;
+
const nrqlQueryPropsAvailable =
nrqlQueries &&
nrqlQueries[0] &&
nrqlQueries[0].accountId &&
nrqlQueries[0].query;
+
if (!nrqlQueryPropsAvailable) {
return ;
}
+
return (
{({width, height}) => (
@@ -1237,15 +922,17 @@ export default class YourAwesomeVisualization extends React.Component {
if (loading) {
return ;
}
+
if (error) {
return ;
}
+
const transformedData = this.transformData(data);
+
return (
- {
- selectedChart === CHART_TYPES.Radar || !Boolean(selectedChart) ?
- (
- )
- :
- (
+ ) : (
+ )}
+ stroke={stroke || '#000000'}
+ fill={fill || '#51C9B7'}
+ />
+ )}
);
}}
@@ -1280,7 +968,6 @@ export default class YourAwesomeVisualization extends React.Component {
}
}
-
const EmptyState = () => (
@@ -1300,6 +987,7 @@ const EmptyState = () => (
);
+
const ErrorState = () => (
@@ -1315,26 +1003,20 @@ const ErrorState = () => (
);
```
-
+
-
+
-
+[Serve your Nerdpack locally](/build-apps/publish-deploy/serve/), and view it in the **Custom Visualizations** app in New Relic. Select a chart type from the dropdown in the configuration sidebar, and see your visualization update to show the matching chart type:
-[Run your visualization locally](/build-apps/build-visualization#render-the-visualization-in-local-development), and view it in the **Custom Visualizations** app in New Relic. Select a chart type from the dropdown in the configuration sidebar, and see your visualization update to show the matching chart type:
+![Final custom visualization outcome from this guide](../../images/custom-viz/custom-chart-type-configuration-prop.png)
-
+
-## Summary
+
-Congratulations on completing the steps in this example! You've learned how to customize your visualization using _nr1.json_ configuration.
+
-## Additional resources
+## Summary
-- New Relic Quick Tips video: [Dashboards and Custom Visualizations](https://www.youtube.com/watch?v=_F61mxtKfGA) (6 minutes)
-- New Relic NerdBytes video: [Configuring custom visualizations for dashboards](https://www.youtube.com/watch?v=sFpG_iG7Xa8) (7 minutes)
-- New Relic Nerdlog live stream: [Custom Data Visualizations on New Relic](https://www.youtube.com/watch?v=HuR0EdHGz24) (30 minutes)
-- New Relic One SDK components: Intro to New Relic One SDK Component library
+Congratulations on completing this lesson! You've learned how to customize your visualization using _nr1.json_ configuration.
\ No newline at end of file