diff --git a/src/data/nav.yml b/src/data/nav.yml
index ebbafcd0a..8c56d0410 100644
--- a/src/data/nav.yml
+++ b/src/data/nav.yml
@@ -65,6 +65,8 @@
url: '/build-apps/publish-deploy/catalog'
- title: Tag your Nerdpack's release version
url: '/build-apps/publish-deploy/tag'
+ - title: Customize an open-source Nerdpack
+ url: '/build-apps/customize-nerdpack'
- title: Permissions for managing apps
url: '/build-apps/permission-manage-apps'
- title: Attach your Nerdlet to your entities
diff --git a/src/images/build-an-app/add-to-dashboard.png b/src/images/build-an-app/add-to-dashboard.png
new file mode 100644
index 000000000..4544e5cdb
Binary files /dev/null and b/src/images/build-an-app/add-to-dashboard.png differ
diff --git a/src/images/build-an-app/add-victory-charts.png b/src/images/build-an-app/add-victory-charts.png
new file mode 100644
index 000000000..92b63f60f
Binary files /dev/null and b/src/images/build-an-app/add-victory-charts.png differ
diff --git a/src/images/build-an-app/circular-progress-bar-dashboard.png b/src/images/build-an-app/circular-progress-bar-dashboard.png
new file mode 100644
index 000000000..8f1b8a465
Binary files /dev/null and b/src/images/build-an-app/circular-progress-bar-dashboard.png differ
diff --git a/src/images/build-an-app/configured-progress-bar.png b/src/images/build-an-app/configured-progress-bar.png
new file mode 100644
index 000000000..09aa1b1b5
Binary files /dev/null and b/src/images/build-an-app/configured-progress-bar.png differ
diff --git a/src/images/build-an-app/progress-bar-chart-no-corner-radius.png b/src/images/build-an-app/progress-bar-chart-no-corner-radius.png
new file mode 100644
index 000000000..4156c2bd6
Binary files /dev/null and b/src/images/build-an-app/progress-bar-chart-no-corner-radius.png differ
diff --git a/src/images/build-an-app/progress-bar-chart-with-colors.png b/src/images/build-an-app/progress-bar-chart-with-colors.png
new file mode 100644
index 000000000..2152dd5de
Binary files /dev/null and b/src/images/build-an-app/progress-bar-chart-with-colors.png differ
diff --git a/src/images/build-an-app/victory-charts-nerdpack.png b/src/images/build-an-app/victory-charts-nerdpack.png
new file mode 100644
index 000000000..7aea797c5
Binary files /dev/null and b/src/images/build-an-app/victory-charts-nerdpack.png differ
diff --git a/src/images/build-an-app/victory-charts-repo.png b/src/images/build-an-app/victory-charts-repo.png
new file mode 100644
index 000000000..e134e4549
Binary files /dev/null and b/src/images/build-an-app/victory-charts-repo.png differ
diff --git a/src/markdown-pages/build-apps/customize-open-source-visualization.mdx b/src/markdown-pages/build-apps/customize-open-source-visualization.mdx
new file mode 100644
index 000000000..1e897263f
--- /dev/null
+++ b/src/markdown-pages/build-apps/customize-open-source-visualization.mdx
@@ -0,0 +1,1141 @@
+---
+path: '/build-apps/customize-nerdpack'
+title: 'Customize an open-source Nerdpack'
+template: 'GuideTemplate'
+description: 'Customize an open-source Nerdpack'
+---
+
+
+
+Most Nerdpacks in the New Relic One catalog are open source. This means you can clone or fork their repositories, customize them to suit your specific needs, and re-publish them for your account to use.
+
+
+
+## Before you begin
+
+If you haven't already:
+
+- Sign up for a [New Relic account](https://newrelic.com/signup?utm_source=developer-site)
+- Install [Node.js](https://nodejs.org/en/download/)
+- Complete the first four steps in the [`nr1` quick start](https://one.newrelic.com/launcher/developer-center.launcher?pane=eyJuZXJkbGV0SWQiOiJkZXZlbG9wZXItY2VudGVyLmRldmVsb3Blci1jZW50ZXIifQ==) to install and configure the CLI
+
+
+
+
+
+```json fileName=nr1.json
+{
+ "schemaType": "VISUALIZATION",
+ "id": "circular-progress-bar",
+ "displayName": "Circular progress bar",
+ "description": "",
+ "configuration": [
+ {
+ "name": "nrqlQueries",
+ "title": "NRQL Queries",
+ "type": "collection",
+ "items": [
+ {
+ "name": "accountId",
+ "title": "Account ID",
+ "description": "Account ID to be associated with the query",
+ "type": "account-id"
+ },
+ {
+ "name": "query",
+ "title": "Query",
+ "description": "NRQL query for visualization",
+ "type": "nrql"
+ }
+ ]
+ },
+ {
+ "name": "thresholds",
+ "title": "Thresholds",
+ "type": "namespace",
+ "items": [
+ {
+ "name": "criticalThreshold",
+ "title": "Critical threshold",
+ "description": "Value at which progress is displayed as critical",
+ "type": "number"
+ },
+ {
+ "name": "highValuesAreSuccess",
+ "title": "Above threshold is success",
+ "description": "If toggled on, values above the threshold display as successful. Otherwise, values at or above the threshold display as critical.",
+ "type": "boolean"
+ }
+ ]
+ }
+ ]
+}
+```
+
+```js fileName=index.js
+import React from 'react';
+import PropTypes from 'prop-types';
+import { VictoryPie, VictoryAnimation, VictoryLabel } from 'victory';
+import {
+ Card,
+ CardBody,
+ HeadingText,
+ NrqlQuery,
+ Spinner,
+ AutoSizer,
+} from 'nr1';
+import NrqlQueryError from '../../src/nrql-query-error';
+import { baseLabelStyles } from '../../src/theme';
+import { getUniqueAggregatesAndFacets } from '../../src/utils/nrql-validation-helper';
+import Colors from '../../src/colors';
+
+const BOUNDS = {
+ X: 400,
+ Y: 400,
+};
+
+const LABEL_SIZE = 24;
+const LABEL_PADDING = 10;
+const CHART_WIDTH = BOUNDS.X;
+const CHART_HEIGHT = BOUNDS.Y - LABEL_SIZE - LABEL_PADDING;
+
+export default class CircularProgressBar 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 = {
+ /**
+ * 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,
+ })
+ ),
+
+ /**
+ * Configuration that determines what values to display as critical or
+ * successful.
+ */
+ thresholds: PropTypes.shape({
+ criticalThreshold: PropTypes.number,
+ highValuesAreSuccess: PropTypes.bool,
+ }),
+ };
+
+ /**
+ * Restructure the data for a aggregate NRQL query with no TIMESERIES and no
+ * FACET into a for our visualization works well with.
+ */
+ transformData = (data) => {
+ const {
+ data: [series],
+ metadata: { color: colorFromData, name: label },
+ } = data[0];
+
+ const percent = series.y * 100;
+ const color = this.getColor(percent, colorFromData);
+
+ return {
+ percent,
+ label,
+ series: [
+ { x: 'progress', y: percent, color },
+ { x: 'remainder', y: 100 - percent, color: 'transparent' },
+ ],
+ };
+ };
+
+ nrqlInputIsValid = (data) => {
+ const { data: seriesEntries } = data[0];
+ const { uniqueAggregates, uniqueFacets } =
+ getUniqueAggregatesAndFacets(data);
+ const isNonTimeseries = seriesEntries.length === 1;
+
+ return (
+ uniqueAggregates.size === 1 && uniqueFacets.size === 0 && isNonTimeseries
+ );
+ };
+
+ getColor = (value, colorFromData) => {
+ const { red6: red, green6: green } = Colors.base;
+ const {
+ thresholds: { criticalThreshold, highValuesAreSuccess },
+ } = this.props;
+
+ const threshold = parseFloat(criticalThreshold);
+
+ if (isNaN(threshold)) {
+ return colorFromData;
+ }
+
+ if (highValuesAreSuccess) {
+ return value > threshold ? green : red;
+ }
+
+ return value < threshold ? green : red;
+ };
+
+ render() {
+ const { nrqlQueries } = this.props;
+
+ 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 (
+
+ );
+ }
+
+ if (!this.nrqlInputIsValid(data)) {
+ return (
+
+ );
+ }
+
+ const { percent, label, series } = this.transformData(data);
+
+ return (
+
+ );
+ }}
+
+ )}
+
+ );
+ }
+}
+
+const EmptyState = () => (
+
+
+
+ Please provide a NRQL query & account ID pair
+
+
+ This Visualization supports NRQL queries with a single SELECT clause
+ returning a percentage value (0 to 100 rather than 0 to 1). For example:
+
+
+ {'FROM Transaction SELECT percentage(count(*), WHERE duration < 0.1)'}
+
+
+
+);
+```
+
+
+
+## View a Nerdpack
+
+Subscribe to the **Victory Charts** Nerdpack and open the **Circular progress bar** visualization in New Relic.
+
+
+
+
+
+From your homepage at New Relic, navigate to **Apps**:
+
+![Navigate to apps](../../images/build-an-app/nav-to-apps.png)
+
+
+
+
+
+Click the **Victory Charts** Nerdpack in the catalog:
+
+![Victory Charts Nerdpack](../../images/build-an-app/victory-charts-nerdpack.png)
+
+
+
+
+
+[Add **Victory Charts** to your account](/build-apps/publish-deploy/subscribe/#subscribe-to-a-nerdpack):
+
+![Add Victory Charts](../../images/build-an-app/add-victory-charts.png)
+
+
+
+
+
+From **Apps**, open **Custom visualizations**:
+
+![Navigate to Custom visualizations](../../images/build-an-app/nav-to-custom-viz.png)
+
+From here, click the **Circular progress bar** visualization that you installed as part of the **Victory Charts** Nerdpack.
+
+
+
+
+
+Configure your visualization:
+
+![Configured visualization](../../images/build-an-app/configured-progress-bar.png)
+
+Now you see a circular chart that shows a percentage based on your query.
+
+
+
+Read [our documentation](https://github.com/newrelic/nr1-victory-visualizations/blob/main/catalog/documentation.md#circular-progress-bar) for instructions on how to configure the progress bar visualization.
+
+
+
+Notice a few things about this visualization:
+
+- You don't control the color of the chart
+- The sections of the chart have rounded edges
+
+For the sake of this tutorial, imagine this chart represents your data exactly how you want it to, except for two things. You'd like to use straight edges and control the chart's colors manually. In the real world you may come across Nerdpacks like this where you like what they offer, but you'd like them better if you could tweak them. Well, you can tweak them, and next, you'll learn how!
+
+
+
+
+
+Because you're going to use a tweaked version of the **Victory Charts** Nerdpack instead of the one you subscribed to, you can [unsubscribe](/build-apps/publish-deploy/subscribe/#unsubscribe-from-a-nerdpack) from our version now.
+
+
+
+
+
+## Clone a Nerdpack
+
+Find the source code repository from the Nerdpack's catalog entry and clone it to your local machine.
+
+
+
+
+
+From your homepage at New Relic, navigate to **Apps**:
+
+![Navigate to apps](../../images/build-an-app/nav-to-apps.png)
+
+
+
+
+
+Click the **Victory Charts** Nerdpack in the catalog:
+
+![Victory Charts Nerdpack](../../images/build-an-app/victory-charts-nerdpack.png)
+
+
+
+
+
+Go to the Nerdpack's source code repository:
+
+![Victory Charts repo](../../images/build-an-app/victory-charts-repo.png)
+
+All open source Nerdpacks in the catalog have links to their source code in their catalog information.
+
+
+
+
+
+Clone the repository:
+
+```sh
+nr1 nerdpack:clone -r https://github.com/newrelic/nr1-victory-visualizations.git
+```
+
+Now you have a local version of the **Victory Charts** Nerdpack! Notice that you used `nr1 nerdpack:clone` instead of `git clone` to copy the repo. `nr1 nerdpack:clone` offers built in functionality to help keep your local copy distinct from the original Nerdpack in the New Relic One public catalog. Specifically, it generates a new Nerdpack UUID so you don't have to do this yourself:
+
+```sh
+[output] Re-generating UUID...
+[output] Committing new UUID...
+```
+
+If you change to the _nr1-victory-visualizations_ directory, and look at the git log, you'll see the new commit:
+
+```sh
+git log -1 -p
+[output] {blue}commit e356bb5b10c3ecc8f93bae66d5739e1676ee21ef {plain}({green}HEAD -> main{plain})
+[output] Author: New Relic CLI
+[output] Date: Tue May 25 14:29:37 2021 -0400
+[output]
+[output] "chore: Auto-generated UUID"
+[output]
+[output] diff --git a/nr1.json b/nr1.json
+[output] index 054de52..7a107b5 100644
+[output] --- a/nr1.json
+[output] +++ b/nr1.json
+[output] @@ -1,6 +1,6 @@
+[output] {
+[output] "schemaType": "NERDPACK",
+[output] {red}- "id": "cf5f13d9-815f-4907-a21d-83d02fa2a4fb",
+[output] {green}+ "id": "ab123c45-678d-9012-efg3-45hi6jkl7890",
+[output] "displayName": "Victory charts visualizations",
+[output] "description": "Visualizations built on top of Victory charts"
+[output] }
+```
+
+
+
+
+
+## Customize a Nerdpack
+
+Tweak the **Circular progress bar** visualization to use straight edges and customizable colors.
+
+**Circular progress bar** [renders a `VictoryPie`](https://github.com/newrelic/nr1-victory-visualizations/blob/267251d936dc607a8a9eba5a19ccbd889f092fdb/visualizations/circular-progress-bar/index.js#L158) with some predefined fields. The fields you'll tweak are:
+
+- [colorScale](https://formidable.com/open-source/victory/docs/victory-pie/#colorscale)
+- [cornerRadius](https://formidable.com/open-source/victory/docs/victory-pie/#cornerradius)
+
+
+
+
+
+In your local Nerdpack, open _nr1-victory-visualizations/visualizations/circular-progress-bar/nr1.json_.
+
+_nr1.json_ is the **Circular progress bar** visualization's [metadata file](http://localhost:8000/explore-docs/custom-viz/configuration-options/). Use this file to add a configurable `colorScale` option, which corresponds to the `colorScale` field on `VictoryPie`.
+
+
+
+
+
+Add a [`collection`](/explore-docs/custom-viz/configuration-options/#collection) of [`string`](/explore-docs/custom-viz/configuration-options/#string) fields for you to customize your chart's colors:
+
+```json fileName=nr1.json
+{
+ "schemaType": "VISUALIZATION",
+ "id": "circular-progress-bar",
+ "displayName": "Circular progress bar",
+ "description": "",
+ "configuration": [
+ {
+ "name": "nrqlQueries",
+ "title": "NRQL Queries",
+ "type": "collection",
+ "items": [
+ {
+ "name": "accountId",
+ "title": "Account ID",
+ "description": "Account ID to be associated with the query",
+ "type": "account-id"
+ },
+ {
+ "name": "query",
+ "title": "Query",
+ "description": "NRQL query for visualization",
+ "type": "nrql"
+ }
+ ]
+ },
+ {
+ "name": "thresholds",
+ "title": "Thresholds",
+ "type": "namespace",
+ "items": [
+ {
+ "name": "criticalThreshold",
+ "title": "Critical threshold",
+ "description": "Value at which progress is displayed as critical",
+ "type": "number"
+ },
+ {
+ "name": "highValuesAreSuccess",
+ "title": "Above threshold is success",
+ "description": "If toggled on, values above the threshold display as successful. Otherwise, values at or above the threshold display as critical.",
+ "type": "boolean"
+ }
+ ]
+ },
+ {
+ "name": "colors",
+ "title": "Colors",
+ "type": "collection",
+ "items": [
+ {
+ "name": "segmentColor",
+ "title": "Segment color",
+ "description": "The color of a bar segment.",
+ "type": "string"
+ }
+ ]
+ }
+ ]
+}
+```
+
+The `VictoryPie` field that you'll use with this update is called [`colorScale`](https://formidable.com/open-source/victory/docs/victory-pie/#colorscale). It accepts an array of colors and applies each color to a segment of the progress bar. So, in your visualization's configuration options, you've specified a collection of strings that you use to pass colors to your chart.
+
+
+
+
+
+In the same visualization directory, open _index.js_.
+
+
+
+
+
+In `render()`, set the `VictoryPie.colorScale` value:
+
+```js fileName=index.js
+import React from 'react';
+import PropTypes from 'prop-types';
+import { VictoryPie, VictoryAnimation, VictoryLabel } from 'victory';
+import {
+ Card,
+ CardBody,
+ HeadingText,
+ NrqlQuery,
+ Spinner,
+ AutoSizer,
+} from 'nr1';
+import NrqlQueryError from '../../src/nrql-query-error';
+import { baseLabelStyles } from '../../src/theme';
+import { getUniqueAggregatesAndFacets } from '../../src/utils/nrql-validation-helper';
+import Colors from '../../src/colors';
+
+const BOUNDS = {
+ X: 400,
+ Y: 400,
+};
+
+const LABEL_SIZE = 24;
+const LABEL_PADDING = 10;
+const CHART_WIDTH = BOUNDS.X;
+const CHART_HEIGHT = BOUNDS.Y - LABEL_SIZE - LABEL_PADDING;
+
+export default class CircularProgressBar 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 = {
+ /**
+ * 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,
+ })
+ ),
+
+ /**
+ * Configuration that determines what values to display as critical or
+ * successful.
+ */
+ thresholds: PropTypes.shape({
+ criticalThreshold: PropTypes.number,
+ highValuesAreSuccess: PropTypes.bool,
+ }),
+ };
+
+ /**
+ * Restructure the data for a aggregate NRQL query with no TIMESERIES and no
+ * FACET into a for our visualization works well with.
+ */
+ transformData = (data) => {
+ const {
+ data: [series],
+ metadata: { color: colorFromData, name: label },
+ } = data[0];
+
+ const percent = series.y * 100;
+ const color = this.getColor(percent, colorFromData);
+
+ return {
+ percent,
+ label,
+ series: [
+ { x: 'progress', y: percent, color },
+ { x: 'remainder', y: 100 - percent, color: 'transparent' },
+ ],
+ };
+ };
+
+ nrqlInputIsValid = (data) => {
+ const { data: seriesEntries } = data[0];
+ const { uniqueAggregates, uniqueFacets } =
+ getUniqueAggregatesAndFacets(data);
+ const isNonTimeseries = seriesEntries.length === 1;
+
+ return (
+ uniqueAggregates.size === 1 && uniqueFacets.size === 0 && isNonTimeseries
+ );
+ };
+
+ getColor = (value, colorFromData) => {
+ const { red6: red, green6: green } = Colors.base;
+ const {
+ thresholds: { criticalThreshold, highValuesAreSuccess },
+ } = this.props;
+
+ const threshold = parseFloat(criticalThreshold);
+
+ if (isNaN(threshold)) {
+ return colorFromData;
+ }
+
+ if (highValuesAreSuccess) {
+ return value > threshold ? green : red;
+ }
+
+ return value < threshold ? green : red;
+ };
+
+ render() {
+ const { nrqlQueries, colors } = this.props;
+ const colorScale = Array.from(colors, x => x.segmentColor)
+
+ 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 (
+
+ );
+ }
+
+ if (!this.nrqlInputIsValid(data)) {
+ return (
+
+ );
+ }
+
+ const { percent, label, series } = this.transformData(data);
+
+ return (
+
+ );
+ }}
+
+ )}
+
+ );
+ }
+}
+
+const EmptyState = () => (
+
+
+
+ Please provide a NRQL query & account ID pair
+
+
+ This Visualization supports NRQL queries with a single SELECT clause
+ returning a percentage value (0 to 100 rather than 0 to 1). For example:
+
+
+ {'FROM Transaction SELECT percentage(count(*), WHERE duration < 0.1)'}
+
+
+
+);
+```
+
+First, you created a new constant, called `colorScale`, which is an array of the `segmentColor` values from `this.props.colors`. Then, you set the `VictoryPie` component's `colorScale` prop. Finall, you removed `VictoryPie.style` because the colors are now controlled by `colorScale`.
+
+
+
+
+
+From your Nerdpack's root directory, run a local server:
+
+```sh
+nr1 nerdpack:serve
+```
+
+Once the server is running, find the url for your local `circular-progress-bar`:
+
+```sh
+[output] {purple}Visualizations:
+[output] {muted}⁎ {green}circular-progress-bar {blue}https://one.nr/04ERPALBYjW
+[output] {muted}⁎ {green}range-chart {blue}https://one.nr/0oqQaxezJj1
+[output] {muted}⁎ {green}stacked-bar-chart {blue}https://one.nr/0PLRElq3bwa
+```
+
+
+
+
+
+Open your locally served visualization and configure your chart with your account, data query, and segment colors:
+
+![Progress bar with custom colors](../../images/build-an-app/progress-bar-chart-with-colors.png)
+
+Because there are two segments, you add two colors. The first color is for the progress section. The second color is for the remaining percentage.
+
+
+
+
+
+In _index.js_, remove `VictoryPie.cornerRadius`:
+
+```js fileName=index.js
+import React from 'react';
+import PropTypes from 'prop-types';
+import { VictoryPie, VictoryAnimation, VictoryLabel } from 'victory';
+import {
+ Card,
+ CardBody,
+ HeadingText,
+ NrqlQuery,
+ Spinner,
+ AutoSizer,
+} from 'nr1';
+import NrqlQueryError from '../../src/nrql-query-error';
+import { baseLabelStyles } from '../../src/theme';
+import { getUniqueAggregatesAndFacets } from '../../src/utils/nrql-validation-helper';
+import Colors from '../../src/colors';
+
+const BOUNDS = {
+ X: 400,
+ Y: 400,
+};
+
+const LABEL_SIZE = 24;
+const LABEL_PADDING = 10;
+const CHART_WIDTH = BOUNDS.X;
+const CHART_HEIGHT = BOUNDS.Y - LABEL_SIZE - LABEL_PADDING;
+
+export default class CircularProgressBar 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 = {
+ /**
+ * 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,
+ })
+ ),
+
+ /**
+ * Configuration that determines what values to display as critical or
+ * successful.
+ */
+ thresholds: PropTypes.shape({
+ criticalThreshold: PropTypes.number,
+ highValuesAreSuccess: PropTypes.bool,
+ }),
+ };
+
+ /**
+ * Restructure the data for a aggregate NRQL query with no TIMESERIES and no
+ * FACET into a for our visualization works well with.
+ */
+ transformData = (data) => {
+ const {
+ data: [series],
+ metadata: { color: colorFromData, name: label },
+ } = data[0];
+
+ const percent = series.y * 100;
+ const color = this.getColor(percent, colorFromData);
+
+ return {
+ percent,
+ label,
+ series: [
+ { x: 'progress', y: percent, color },
+ { x: 'remainder', y: 100 - percent, color: 'transparent' },
+ ],
+ };
+ };
+
+ nrqlInputIsValid = (data) => {
+ const { data: seriesEntries } = data[0];
+ const { uniqueAggregates, uniqueFacets } =
+ getUniqueAggregatesAndFacets(data);
+ const isNonTimeseries = seriesEntries.length === 1;
+
+ return (
+ uniqueAggregates.size === 1 && uniqueFacets.size === 0 && isNonTimeseries
+ );
+ };
+
+ getColor = (value, colorFromData) => {
+ const { red6: red, green6: green } = Colors.base;
+ const {
+ thresholds: { criticalThreshold, highValuesAreSuccess },
+ } = this.props;
+
+ const threshold = parseFloat(criticalThreshold);
+
+ if (isNaN(threshold)) {
+ return colorFromData;
+ }
+
+ if (highValuesAreSuccess) {
+ return value > threshold ? green : red;
+ }
+
+ return value < threshold ? green : red;
+ };
+
+ render() {
+ const { nrqlQueries, colors } = this.props;
+ const colorScale = Array.from(colors, x => x.segmentColor)
+
+ 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 (
+
+ );
+ }
+
+ if (!this.nrqlInputIsValid(data)) {
+ return (
+
+ );
+ }
+
+ const { percent, label, series } = this.transformData(data);
+
+ return (
+
+ );
+ }}
+
+ )}
+
+ );
+ }
+}
+
+const EmptyState = () => (
+
+
+
+ Please provide a NRQL query & account ID pair
+
+
+ This Visualization supports NRQL queries with a single SELECT clause
+ returning a percentage value (0 to 100 rather than 0 to 1). For example:
+
+
+ {'FROM Transaction SELECT percentage(count(*), WHERE duration < 0.1)'}
+
+
+
+);
+```
+
+This will revert the bar corners to the default 90-degrees instead of being rounded. While your local server is running, it automatically recognizes changes to _index.js_. So, view your visualization in your browser to see the update:
+
+![Progress bar with straight corners](../../images/build-an-app/progress-bar-chart-no-corner-radius.png)
+
+Perfect! You cloned and updated the open source **Circular progress bar** visualization from the New Relic One catalog. The only thing left to do is publish your version to the catalog so your accounts can subscribe to it.
+
+
+
+
+
+Now that you're ready to publish your Nerdpack, stop your local server with `CTRL+C`.
+
+
+
+
+
+## Add a custom visualization to a dashboard
+
+Publish your version of the **Victory charts** Nerdpack to the catalog. Then subscribe to it and use your visualization in a dashboard.
+
+
+
+Because you used `nr1 clone` to clone the Nerdpack's repository, your local copy already has its own UUID. This is a prerequisite for publishing your version to the New Relic One catalog. If you used `git clone` to copy, you need to update the Nerdpack's UUID manually:
+
+```sh
+nr1 nerdpack:uuid -gf
+[output] The new generated id is {purple}ab123c45-678d-9012-efg3-45hi6jkl7890
+```
+
+
+
+
+
+
+
+From its root directory, [publish](/build-apps/publish-deploy/publish/) your Nerdpack:
+
+```sh
+nr1 nerdpack:publish
+```
+
+
+
+
+
+[Subscribe](/build-apps/publish-deploy/subscribe/) to your Nerdpack:
+
+```sh
+nr1 nerdpack:subscribe
+```
+
+Here, you subscribed to your Nerdpack with the CLI. This is effectively the same action you performed earlier in this guide within the web UI, but from your terminal.
+
+
+
+
+
+Go to the **Apps** view in New Relic:
+
+![Navigate to apps](../../images/build-an-app/nav-to-apps.png)
+
+
+
+
+
+From **Apps**, open **Custom visualizations**:
+
+![Navigate to Custom visualizations](../../images/build-an-app/nav-to-custom-viz.png)
+
+From here, click the **Circular progress bar** visualization. Update your visualization's configuration options like you did when you were serving your Nerdpack locally.
+
+
+
+
+
+Click **Add to dashboard**:
+
+![Add to dashboard](../../images/build-an-app/add-to-dashboard.png)
+
+
+
+
+
+Go to your dashboard and see your new circular progress bar:
+
+![Circular progress bar in dashboard](../../images/build-an-app/circular-progress-bar-dashboard.png)
+
+
+
+
+
+
+
+## Summary
+
+In this guide, you:
+
+- Subscribed to a Nerdpack from the New Relic One catalog
+- Cloned an open source Nerdpack
+- Edited an existing visualization to meet your needs
+- Published and subscribed to your own custom Nerdpack
+- Added a Nerdpack to a dashboard
+
+Now you know how to build off the foundation of open source Nerdpacks, you can use the work of the New Relic developer community to fast-track the creation of apps and visualizations.
+
+
+
+If you want to maintain your own version in a remote repository, consider [forking](https://docs.github.com/en/github/getting-started-with-github/quickstart/fork-a-repo) the original repo.
+
+
\ No newline at end of file