• EnglishEspañol日本語한국어Português
  • Inicia sesiónComenzar ahora

Te ofrecemos esta traducción automática para facilitar la lectura.

In the event of any inconsistency between the English version and the translated version, the English versionwill take priority. Please visit this page for more information.

Crea una propuesta

Personalice su visualización con componentes SDK

Sugerencia

Esta lección es parte de un curso que le muestra cómo crear una visualización personalizada en la plataforma New Relic.

Emplee visualizaciones personalizadas de New Relic para mostrar sus datos, ya sea de la base de datos de New Relic o de una fuente externa, de maneras únicas que son distintas de los gráficos que ofrece la plataforma New Relic.

En esta lección, creará una visualización que muestra sus datos en uno de dos tipos de gráficos: RadarChart o Treemap. Luego, implementa un componente SegmentedControl del SDK de New Relic One, que le permite alternar entre los dos tipos de gráficos. En última instancia, esto le brinda libertad para ver sus datos de una manera dinámica que no es posible con las ofertas básicas de New Relic.

Sugerencia

Si se pierde en el proyecto de código y le gustaría ver cómo deberían ver los archivos cuando terminó con cada lección, consulte el proyecto del curso en Github.

Antes de que empieces

Finalmente, si aún no lo hiciste:

Crea tu visualización

Cerciorar de estar trabajando con la última versión de New Relic CLI:

bash
$
nr1 update

Cree una visualización, llamada radar-or-treemap, en un Nerdpack, llamado alternate-viz:

bash
$
nr1 create --type visualization --name radar-or-treemap
You’re trying to create a visualization outside of a Nerdpack. We’ll create a Nerdpack for you—what do you want to name it? … alternate-viz
nerdpack created successfully!
nerdpack alternate-viz is available at "./alternate-viz"
visualization created successfully!
visualization radar-or-treemap is available at "./alternate-viz/visualizations/radar-or-treemap"

Sugerencia

Si recibe un RequestError para un certificado autofirmado cuando ejecuta nr1 create, es posible que deba agregar un certificado a la cadena de certificados de Node.

Como resultado, tiene un nuevo directorio visualizations/radar-or-treemap en alternate-viz:

bash
$
cd alternate-viz
$
ls visualizations/radar-or-treemap
index.js nr1.json styles.scss
import React from 'react';
import PropTypes from 'prop-types';
import {
Radar,
RadarChart,
PolarGrid,
PolarAngleAxis,
PolarRadiusAxis,
} from 'recharts';
import {Card, CardBody, HeadingText, NrqlQuery, Spinner, AutoSizer} from 'nr1';
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 = {
/**
* 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,
})
),
};
/**
* 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();
};
render() {
const {nrqlQueries, stroke, fill} = this.props;
const nrqlQueryPropsAvailable =
nrqlQueries &&
nrqlQueries[0] &&
nrqlQueries[0].accountId &&
nrqlQueries[0].query;
if (!nrqlQueryPropsAvailable) {
return <EmptyState />;
}
return (
<AutoSizer>
{({width, height}) => (
<NrqlQuery
query={nrqlQueries[0].query}
accountId={parseInt(nrqlQueries[0].accountId)}
pollInterval={NrqlQuery.AUTO_POLL_INTERVAL}
>
{({data, loading, error}) => {
if (loading) {
return <Spinner />;
}
if (error) {
return <ErrorState />;
}
const transformedData = this.transformData(data);
return (
<RadarChart
width={width}
height={height}
data={transformedData}
>
<PolarGrid />
<PolarAngleAxis dataKey="name" />
<PolarRadiusAxis tickFormatter={this.formatTick} />
<Radar
dataKey="value"
stroke={stroke || '#51C9B7'}
fill={fill || '#51C9B7'}
fillOpacity={0.6}
/>
</RadarChart>
);
}}
</NrqlQuery>
)}
</AutoSizer>
);
}
}
const EmptyState = () => (
<Card className="EmptyState">
<CardBody className="EmptyState-cardBody">
<HeadingText
spacingType={[HeadingText.SPACING_TYPE.LARGE]}
type={HeadingText.TYPE.HEADING_3}
>
Please provide at least one NRQL query & account ID pair
</HeadingText>
<HeadingText
spacingType={[HeadingText.SPACING_TYPE.MEDIUM]}
type={HeadingText.TYPE.HEADING_4}
>
An example NRQL query you can try is:
</HeadingText>
<code>FROM NrUsage SELECT sum(usage) FACET metric SINCE 1 week ago</code>
</CardBody>
</Card>
);
const ErrorState = () => (
<Card className="ErrorState">
<CardBody className="ErrorState-cardBody">
<HeadingText
className="ErrorState-headingText"
spacingType={[HeadingText.SPACING_TYPE.LARGE]}
type={HeadingText.TYPE.HEADING_3}
>
Oops! Something went wrong.
</HeadingText>
</CardBody>
</Card>
);
visualizations/radar-or-treemap/index.js

Configure el estado de su componente

Agregue el estado del componente a la plantilla de visualización predeterminada que nr1 creó para usted.

Navegue hasta alternate-viz/visualizations/radar-or-treemap/index.js. Trabajará aquí durante el resto de esta lección.

Agregue una constante llamada CHART_TYPES:

import React from 'react';
import PropTypes from 'prop-types';
import {
Radar,
RadarChart,
PolarGrid,
PolarAngleAxis,
PolarRadiusAxis,
} from 'recharts';
import {Card, CardBody, HeadingText, NrqlQuery, Spinner, AutoSizer} from 'nr1';
const CHART_TYPES = {
'Radar': 'radar',
'Treemap': 'treemap'
}
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 = {
/**
* 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,
})
),
};
/**
* 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();
};
render() {
const {nrqlQueries, stroke, fill} = this.props;
const nrqlQueryPropsAvailable =
nrqlQueries &&
nrqlQueries[0] &&
nrqlQueries[0].accountId &&
nrqlQueries[0].query;
if (!nrqlQueryPropsAvailable) {
return <EmptyState />;
}
return (
<AutoSizer>
{({width, height}) => (
<NrqlQuery
query={nrqlQueries[0].query}
accountId={parseInt(nrqlQueries[0].accountId)}
pollInterval={NrqlQuery.AUTO_POLL_INTERVAL}
>
{({data, loading, error}) => {
if (loading) {
return <Spinner />;
}
if (error) {
return <ErrorState />;
}
const transformedData = this.transformData(data);
return (
<RadarChart
width={width}
height={height}
data={transformedData}
>
<PolarGrid />
<PolarAngleAxis dataKey="name" />
<PolarRadiusAxis tickFormatter={this.formatTick} />
<Radar
dataKey="value"
stroke={stroke || '#51C9B7'}
fill={fill || '#51C9B7'}
fillOpacity={0.6}
/>
</RadarChart>
);
}}
</NrqlQuery>
)}
</AutoSizer>
);
}
}
const EmptyState = () => (
<Card className="EmptyState">
<CardBody className="EmptyState-cardBody">
<HeadingText
spacingType={[HeadingText.SPACING_TYPE.LARGE]}
type={HeadingText.TYPE.HEADING_3}
>
Please provide at least one NRQL query & account ID pair
</HeadingText>
<HeadingText
spacingType={[HeadingText.SPACING_TYPE.MEDIUM]}
type={HeadingText.TYPE.HEADING_4}
>
An example NRQL query you can try is:
</HeadingText>
<code>FROM NrUsage SELECT sum(usage) FACET metric SINCE 1 week ago</code>
</CardBody>
</Card>
);
const ErrorState = () => (
<Card className="ErrorState">
<CardBody className="ErrorState-cardBody">
<HeadingText
className="ErrorState-headingText"
spacingType={[HeadingText.SPACING_TYPE.LARGE]}
type={HeadingText.TYPE.HEADING_3}
>
Oops! Something went wrong.
</HeadingText>
</CardBody>
</Card>
);
visualizations/radar-or-treemap/index.js

CHART_TYPES enumera los dos tipos de gráficos que alternará en su visualización.

Inicialice selectedChart en el state de su componente:

import React from 'react';
import PropTypes from 'prop-types';
import {
Radar,
RadarChart,
PolarGrid,
PolarAngleAxis,
PolarRadiusAxis,
} from 'recharts';
import {Card, CardBody, HeadingText, NrqlQuery, Spinner, AutoSizer} from 'nr1';
const CHART_TYPES = {
'Radar': 'radar',
'Treemap': 'treemap'
}
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 = {
/**
* 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,
})
),
};
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();
};
render() {
const {nrqlQueries, stroke, fill} = this.props;
const nrqlQueryPropsAvailable =
nrqlQueries &&
nrqlQueries[0] &&
nrqlQueries[0].accountId &&
nrqlQueries[0].query;
if (!nrqlQueryPropsAvailable) {
return <EmptyState />;
}
return (
<AutoSizer>
{({width, height}) => (
<NrqlQuery
query={nrqlQueries[0].query}
accountId={parseInt(nrqlQueries[0].accountId)}
pollInterval={NrqlQuery.AUTO_POLL_INTERVAL}
>
{({data, loading, error}) => {
if (loading) {
return <Spinner />;
}
if (error) {
return <ErrorState />;
}
const transformedData = this.transformData(data);
return (
<RadarChart
width={width}
height={height}
data={transformedData}
>
<PolarGrid />
<PolarAngleAxis dataKey="name" />
<PolarRadiusAxis tickFormatter={this.formatTick} />
<Radar
dataKey="value"
stroke={stroke || '#51C9B7'}
fill={fill || '#51C9B7'}
fillOpacity={0.6}
/>
</RadarChart>
);
}}
</NrqlQuery>
)}
</AutoSizer>
);
}
}
const EmptyState = () => (
<Card className="EmptyState">
<CardBody className="EmptyState-cardBody">
<HeadingText
spacingType={[HeadingText.SPACING_TYPE.LARGE]}
type={HeadingText.TYPE.HEADING_3}
>
Please provide at least one NRQL query & account ID pair
</HeadingText>
<HeadingText
spacingType={[HeadingText.SPACING_TYPE.MEDIUM]}
type={HeadingText.TYPE.HEADING_4}
>
An example NRQL query you can try is:
</HeadingText>
<code>FROM NrUsage SELECT sum(usage) FACET metric SINCE 1 week ago</code>
</CardBody>
</Card>
);
const ErrorState = () => (
<Card className="ErrorState">
<CardBody className="ErrorState-cardBody">
<HeadingText
className="ErrorState-headingText"
spacingType={[HeadingText.SPACING_TYPE.LARGE]}
type={HeadingText.TYPE.HEADING_3}
>
Oops! Something went wrong.
</HeadingText>
</CardBody>
</Card>
);
visualizations/radar-or-treemap/index.js

Este valor state almacena el tipo de gráfico en el que desea mostrar sus datos.

Ahora que creó un objeto que enumera las opciones de tipo de gráfico para su visualización e inicializó state.selectedChart, está listo para implementar una UI de control para cambiar entre los dos tipos de gráfico.

Agregar SegmentedControl componentes

state.selectedChart no es útil a menos que el usuario de su visualización pueda seleccionar un tipo de gráfico. Emplee SegmentedControl y SegmentedControlItem para cambiar entre los dos tipos de gráficos.

Importar SegmentedControl y SegmentedControlItem desde nr1:

import React from 'react';
import PropTypes from 'prop-types';
import {
Radar,
RadarChart,
PolarGrid,
PolarAngleAxis,
PolarRadiusAxis,
} from 'recharts';
import {
AutoSizer,
Card,
CardBody,
HeadingText,
NrqlQuery,
SegmentedControl,
SegmentedControlItem,
Spinner,
} from 'nr1';
const CHART_TYPES = {
'Radar': 'radar',
'Treemap': 'treemap'
}
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 = {
/**
* 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,
})
),
};
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();
};
render() {
const {nrqlQueries, stroke, fill} = this.props;
const nrqlQueryPropsAvailable =
nrqlQueries &&
nrqlQueries[0] &&
nrqlQueries[0].accountId &&
nrqlQueries[0].query;
if (!nrqlQueryPropsAvailable) {
return <EmptyState />;
}
return (
<AutoSizer>
{({width, height}) => (
<NrqlQuery
query={nrqlQueries[0].query}
accountId={parseInt(nrqlQueries[0].accountId)}
pollInterval={NrqlQuery.AUTO_POLL_INTERVAL}
>
{({data, loading, error}) => {
if (loading) {
return <Spinner />;
}
if (error) {
return <ErrorState />;
}
const transformedData = this.transformData(data);
return (
<RadarChart
width={width}
height={height}
data={transformedData}
>
<PolarGrid />
<PolarAngleAxis dataKey="name" />
<PolarRadiusAxis tickFormatter={this.formatTick} />
<Radar
dataKey="value"
stroke={stroke || '#51C9B7'}
fill={fill || '#51C9B7'}
fillOpacity={0.6}
/>
</RadarChart>
);
}}
</NrqlQuery>
)}
</AutoSizer>
);
}
}
const EmptyState = () => (
<Card className="EmptyState">
<CardBody className="EmptyState-cardBody">
<HeadingText
spacingType={[HeadingText.SPACING_TYPE.LARGE]}
type={HeadingText.TYPE.HEADING_3}
>
Please provide at least one NRQL query & account ID pair
</HeadingText>
<HeadingText
spacingType={[HeadingText.SPACING_TYPE.MEDIUM]}
type={HeadingText.TYPE.HEADING_4}
>
An example NRQL query you can try is:
</HeadingText>
<code>FROM NrUsage SELECT sum(usage) FACET metric SINCE 1 week ago</code>
</CardBody>
</Card>
);
const ErrorState = () => (
<Card className="ErrorState">
<CardBody className="ErrorState-cardBody">
<HeadingText
className="ErrorState-headingText"
spacingType={[HeadingText.SPACING_TYPE.LARGE]}
type={HeadingText.TYPE.HEADING_3}
>
Oops! Something went wrong.
</HeadingText>
</CardBody>
</Card>
);
visualizations/radar-or-treemap/index.js

En render(), envuelve RadarChart en un React.Fragment:

import React from 'react';
import PropTypes from 'prop-types';
import {
Radar,
RadarChart,
PolarGrid,
PolarAngleAxis,
PolarRadiusAxis,
} from 'recharts';
import {
AutoSizer,
Card,
CardBody,
HeadingText,
NrqlQuery,
SegmentedControl,
SegmentedControlItem,
Spinner,
} from 'nr1';
const CHART_TYPES = {
'Radar': 'radar',
'Treemap': 'treemap'
}
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 = {
/**
* 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,
})
),
};
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();
};
render() {
const {nrqlQueries, stroke, fill} = this.props;
const nrqlQueryPropsAvailable =
nrqlQueries &&
nrqlQueries[0] &&
nrqlQueries[0].accountId &&
nrqlQueries[0].query;
if (!nrqlQueryPropsAvailable) {
return <EmptyState />;
}
return (
<AutoSizer>
{({width, height}) => (
<NrqlQuery
query={nrqlQueries[0].query}
accountId={parseInt(nrqlQueries[0].accountId)}
pollInterval={NrqlQuery.AUTO_POLL_INTERVAL}
>
{({data, loading, error}) => {
if (loading) {
return <Spinner />;
}
if (error) {
return <ErrorState />;
}
const transformedData = this.transformData(data);
return (
<React.Fragment>
<RadarChart
width={width}
height={height}
data={transformedData}
>
<PolarGrid />
<PolarAngleAxis dataKey="name" />
<PolarRadiusAxis tickFormatter={this.formatTick} />
<Radar
dataKey="value"
stroke={stroke || '#51C9B7'}
fill={fill || '#51C9B7'}
fillOpacity={0.6}
/>
</RadarChart>
</React.Fragment>
);
}}
</NrqlQuery>
)}
</AutoSizer>
);
}
}
const EmptyState = () => (
<Card className="EmptyState">
<CardBody className="EmptyState-cardBody">
<HeadingText
spacingType={[HeadingText.SPACING_TYPE.LARGE]}
type={HeadingText.TYPE.HEADING_3}
>
Please provide at least one NRQL query & account ID pair
</HeadingText>
<HeadingText
spacingType={[HeadingText.SPACING_TYPE.MEDIUM]}
type={HeadingText.TYPE.HEADING_4}
>
An example NRQL query you can try is:
</HeadingText>
<code>FROM NrUsage SELECT sum(usage) FACET metric SINCE 1 week ago</code>
</CardBody>
</Card>
);
const ErrorState = () => (
<Card className="ErrorState">
<CardBody className="ErrorState-cardBody">
<HeadingText
className="ErrorState-headingText"
spacingType={[HeadingText.SPACING_TYPE.LARGE]}
type={HeadingText.TYPE.HEADING_3}
>
Oops! Something went wrong.
</HeadingText>
</CardBody>
</Card>
);
visualizations/radar-or-treemap/index.js

Esto le permite devolver varios componentes del mismo render().

Agregue un SegmentedControl y dos SegmentedControlItem componentes, cada uno con un value y un label:

import React from 'react';
import PropTypes from 'prop-types';
import {
Radar,
RadarChart,
PolarGrid,
PolarAngleAxis,
PolarRadiusAxis,
} from 'recharts';
import {
AutoSizer,
Card,
CardBody,
HeadingText,
NrqlQuery,
SegmentedControl,
SegmentedControlItem,
Spinner,
} from 'nr1';
const CHART_TYPES = {
'Radar': 'radar',
'Treemap': 'treemap'
}
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 = {
/**
* 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,
})
),
};
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();
};
render() {
const {nrqlQueries, stroke, fill} = this.props;
const nrqlQueryPropsAvailable =
nrqlQueries &&
nrqlQueries[0] &&
nrqlQueries[0].accountId &&
nrqlQueries[0].query;
if (!nrqlQueryPropsAvailable) {
return <EmptyState />;
}
return (
<AutoSizer>
{({width, height}) => (
<NrqlQuery
query={nrqlQueries[0].query}
accountId={parseInt(nrqlQueries[0].accountId)}
pollInterval={NrqlQuery.AUTO_POLL_INTERVAL}
>
{({data, loading, error}) => {
if (loading) {
return <Spinner />;
}
if (error) {
return <ErrorState />;
}
const transformedData = this.transformData(data);
return (
<React.Fragment>
<SegmentedControl
onChange={(event, value) => console.log(value)}
>
<SegmentedControlItem
value={CHART_TYPES.Radar}
label="Radar chart"
/>
<SegmentedControlItem
value={CHART_TYPES.Treemap}
label="Treemap chart"
/>
</SegmentedControl>
<RadarChart
width={width}
height={height}
data={transformedData}
>
<PolarGrid />
<PolarAngleAxis dataKey="name" />
<PolarRadiusAxis tickFormatter={this.formatTick} />
<Radar
dataKey="value"
stroke={stroke || '#51C9B7'}
fill={fill || '#51C9B7'}
fillOpacity={0.6}
/>
</RadarChart>
</React.Fragment>
);
}}
</NrqlQuery>
)}
</AutoSizer>
);
}
}
const EmptyState = () => (
<Card className="EmptyState">
<CardBody className="EmptyState-cardBody">
<HeadingText
spacingType={[HeadingText.SPACING_TYPE.LARGE]}
type={HeadingText.TYPE.HEADING_3}
>
Please provide at least one NRQL query & account ID pair
</HeadingText>
<HeadingText
spacingType={[HeadingText.SPACING_TYPE.MEDIUM]}
type={HeadingText.TYPE.HEADING_4}
>
An example NRQL query you can try is:
</HeadingText>
<code>FROM NrUsage SELECT sum(usage) FACET metric SINCE 1 week ago</code>
</CardBody>
</Card>
);
const ErrorState = () => (
<Card className="ErrorState">
<CardBody className="ErrorState-cardBody">
<HeadingText
className="ErrorState-headingText"
spacingType={[HeadingText.SPACING_TYPE.LARGE]}
type={HeadingText.TYPE.HEADING_3}
>
Oops! Something went wrong.
</HeadingText>
</CardBody>
</Card>
);
visualizations/radar-or-treemap/index.js

Aquí, su SegmentedControl registra el SegmentedControlItem.value en la consola cuando cambia su selección. Los valores que definió para sus componentes SegmentedControlItem corresponden a los dos CHART_TYPES que creó en un paso anterior.

Navega hasta la raíz de tu Nerdpack en alternate-viz.

Sirve tu Nerdpack localmente:

bash
$
nr1 nerdpack:serve

Abra el enlace a su visualización que se muestra en la terminal cuando se inicia el servidor de Node:

bash
Visualizations:
radar-or-treemap https://one.nr/012ab3cd4Ef

Configure su visualización con un ID de cuenta y una consulta.

Con algunos datos necesarios para que su gráfico los procese, ahora verá un RadarChart con el SegmentedControl en la parte superior de la vista.

Mire la consola de su browser para ver su log SegmentedControl.

Conecte state de su componente al SegmentedControl

Agregue un método para actualizar state y conecte ese método con el SegmentedControl que agregó en la última sección.

Agregue un método de componente, llamado updateSelectedChart():

import React from 'react';
import PropTypes from 'prop-types';
import {
Radar,
RadarChart,
PolarGrid,
PolarAngleAxis,
PolarRadiusAxis,
} from 'recharts';
import {
AutoSizer,
Card,
CardBody,
HeadingText,
NrqlQuery,
SegmentedControl,
SegmentedControlItem,
Spinner,
} from 'nr1';
const CHART_TYPES = {
'Radar': 'radar',
'Treemap': 'treemap'
}
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 = {
/**
* 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,
})
),
};
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} = this.props;
const nrqlQueryPropsAvailable =
nrqlQueries &&
nrqlQueries[0] &&
nrqlQueries[0].accountId &&
nrqlQueries[0].query;
if (!nrqlQueryPropsAvailable) {
return <EmptyState />;
}
return (
<AutoSizer>
{({width, height}) => (
<NrqlQuery
query={nrqlQueries[0].query}
accountId={parseInt(nrqlQueries[0].accountId)}
pollInterval={NrqlQuery.AUTO_POLL_INTERVAL}
>
{({data, loading, error}) => {
if (loading) {
return <Spinner />;
}
if (error) {
return <ErrorState />;
}
const transformedData = this.transformData(data);
return (
<React.Fragment>
<SegmentedControl
onChange={(event, value) => console.log(value)}
>
<SegmentedControlItem
value={CHART_TYPES.Radar}
label="Radar chart"
/>
<SegmentedControlItem
value={CHART_TYPES.Treemap}
label="Treemap chart"
/>
</SegmentedControl>
<RadarChart
width={width}
height={height}
data={transformedData}
>
<PolarGrid />
<PolarAngleAxis dataKey="name" />
<PolarRadiusAxis tickFormatter={this.formatTick} />
<Radar
dataKey="value"
stroke={stroke || '#51C9B7'}
fill={fill || '#51C9B7'}
fillOpacity={0.6}
/>
</RadarChart>
</React.Fragment>
);
}}
</NrqlQuery>
)}
</AutoSizer>
);
}
}
const EmptyState = () => (
<Card className="EmptyState">
<CardBody className="EmptyState-cardBody">
<HeadingText
spacingType={[HeadingText.SPACING_TYPE.LARGE]}
type={HeadingText.TYPE.HEADING_3}
>
Please provide at least one NRQL query & account ID pair
</HeadingText>
<HeadingText
spacingType={[HeadingText.SPACING_TYPE.MEDIUM]}
type={HeadingText.TYPE.HEADING_4}
>
An example NRQL query you can try is:
</HeadingText>
<code>FROM NrUsage SELECT sum(usage) FACET metric SINCE 1 week ago</code>
</CardBody>
</Card>
);
const ErrorState = () => (
<Card className="ErrorState">
<CardBody className="ErrorState-cardBody">
<HeadingText
className="ErrorState-headingText"
spacingType={[HeadingText.SPACING_TYPE.LARGE]}
type={HeadingText.TYPE.HEADING_3}
>
Oops! Something went wrong.
</HeadingText>
</CardBody>
</Card>
);
visualizations/radar-or-treemap/index.js

Este nuevo método toma un argumento value y establece state.selectedChart en ese valor.

Establezca SegmentedControl.onChange en updateSelectedChart():

import React from 'react';
import PropTypes from 'prop-types';
import {
Radar,
RadarChart,
PolarGrid,
PolarAngleAxis,
PolarRadiusAxis,
} from 'recharts';
import {
AutoSizer,
Card,
CardBody,
HeadingText,
NrqlQuery,
SegmentedControl,
SegmentedControlItem,
Spinner,
} from 'nr1';
const CHART_TYPES = {
'Radar': 'radar',
'Treemap': 'treemap'
}
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 = {
/**
* 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,
})
),
};
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} = this.props;
const nrqlQueryPropsAvailable =
nrqlQueries &&
nrqlQueries[0] &&
nrqlQueries[0].accountId &&
nrqlQueries[0].query;
if (!nrqlQueryPropsAvailable) {
return <EmptyState />;
}
return (
<AutoSizer>
{({width, height}) => (
<NrqlQuery
query={nrqlQueries[0].query}
accountId={parseInt(nrqlQueries[0].accountId)}
pollInterval={NrqlQuery.AUTO_POLL_INTERVAL}
>
{({data, loading, error}) => {
if (loading) {
return <Spinner />;
}
if (error) {
return <ErrorState />;
}
const transformedData = this.transformData(data);
return (
<React.Fragment>
<SegmentedControl
onChange={this.updateSelectedChart}
>
<SegmentedControlItem
value={CHART_TYPES.Radar}
label="Radar chart"
/>
<SegmentedControlItem
value={CHART_TYPES.Treemap}
label="Treemap chart"
/>
</SegmentedControl>
<RadarChart
width={width}
height={height}
data={transformedData}
>
<PolarGrid />
<PolarAngleAxis dataKey="name" />
<PolarRadiusAxis tickFormatter={this.formatTick} />
<Radar
dataKey="value"
stroke={stroke || '#51C9B7'}
fill={fill || '#51C9B7'}
fillOpacity={0.6}
/>
</RadarChart>
</React.Fragment>
);
}}
</NrqlQuery>
)}
</AutoSizer>
);
}
}
const EmptyState = () => (
<Card className="EmptyState">
<CardBody className="EmptyState-cardBody">
<HeadingText
spacingType={[HeadingText.SPACING_TYPE.LARGE]}
type={HeadingText.TYPE.HEADING_3}
>
Please provide at least one NRQL query & account ID pair
</HeadingText>
<HeadingText
spacingType={[HeadingText.SPACING_TYPE.MEDIUM]}
type={HeadingText.TYPE.HEADING_4}
>
An example NRQL query you can try is:
</HeadingText>
<code>FROM NrUsage SELECT sum(usage) FACET metric SINCE 1 week ago</code>
</CardBody>
</Card>
);
const ErrorState = () => (
<Card className="ErrorState">
<CardBody className="ErrorState-cardBody">
<HeadingText
className="ErrorState-headingText"
spacingType={[HeadingText.SPACING_TYPE.LARGE]}
type={HeadingText.TYPE.HEADING_3}
>
Oops! Something went wrong.
</HeadingText>
</CardBody>
</Card>
);
visualizations/radar-or-treemap/index.js

Ahora, cuando cambie su selección en SegmentedControl, su selección se establecerá en state.

Implementar una opción Treemap

Agregue un Treemap a su visualización. Este mapa será una alternativa al RadarChart existente.

Detalle técnico

Esta guía emplea componentes Recharts para gráficos de terceros, pero puede usar cualquier otra biblioteca de gráficos JavaScript que sea compatible con la versión actual de React cuando crea visualizaciones y aplicaciones de New Relic.

Importar Treemap desde recharts:

import React from 'react';
import PropTypes from 'prop-types';
import {
Radar,
RadarChart,
PolarGrid,
PolarAngleAxis,
PolarRadiusAxis,
Treemap,
} from 'recharts';
import {
AutoSizer,
Card,
CardBody,
HeadingText,
NrqlQuery,
SegmentedControl,
SegmentedControlItem,
Spinner,
} from 'nr1';
const CHART_TYPES = {
'Radar': 'radar',
'Treemap': 'treemap'
}
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 = {
/**
* 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,
})
),
};
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} = this.props;
const nrqlQueryPropsAvailable =
nrqlQueries &&
nrqlQueries[0] &&
nrqlQueries[0].accountId &&
nrqlQueries[0].query;
if (!nrqlQueryPropsAvailable) {
return <EmptyState />;
}
return (
<AutoSizer>
{({width, height}) => (
<NrqlQuery
query={nrqlQueries[0].query}
accountId={parseInt(nrqlQueries[0].accountId)}
pollInterval={NrqlQuery.AUTO_POLL_INTERVAL}
>
{({data, loading, error}) => {
if (loading) {
return <Spinner />;
}
if (error) {
return <ErrorState />;
}
const transformedData = this.transformData(data);
return (
<React.Fragment>
<SegmentedControl
onChange={this.updateSelectedChart}
>
<SegmentedControlItem
value={CHART_TYPES.Radar}
label="Radar chart"
/>
<SegmentedControlItem
value={CHART_TYPES.Treemap}
label="Treemap chart"
/>
</SegmentedControl>
<RadarChart
width={width}
height={height}
data={transformedData}
>
<PolarGrid />
<PolarAngleAxis dataKey="name" />
<PolarRadiusAxis tickFormatter={this.formatTick} />
<Radar
dataKey="value"
stroke={stroke || '#51C9B7'}
fill={fill || '#51C9B7'}
fillOpacity={0.6}
/>
</RadarChart>
</React.Fragment>
);
}}
</NrqlQuery>
)}
</AutoSizer>
);
}
}
const EmptyState = () => (
<Card className="EmptyState">
<CardBody className="EmptyState-cardBody">
<HeadingText
spacingType={[HeadingText.SPACING_TYPE.LARGE]}
type={HeadingText.TYPE.HEADING_3}
>
Please provide at least one NRQL query & account ID pair
</HeadingText>
<HeadingText
spacingType={[HeadingText.SPACING_TYPE.MEDIUM]}
type={HeadingText.TYPE.HEADING_4}
>
An example NRQL query you can try is:
</HeadingText>
<code>FROM NrUsage SELECT sum(usage) FACET metric SINCE 1 week ago</code>
</CardBody>
</Card>
);
const ErrorState = () => (
<Card className="ErrorState">
<CardBody className="ErrorState-cardBody">
<HeadingText
className="ErrorState-headingText"
spacingType={[HeadingText.SPACING_TYPE.LARGE]}
type={HeadingText.TYPE.HEADING_3}
>
Oops! Something went wrong.
</HeadingText>
</CardBody>
</Card>
);
visualizations/radar-or-treemap/index.js

Ahora puede emplear Treemap en su componente de visualización.

En render(), agregue un componente Treemap :

import React from 'react';
import PropTypes from 'prop-types';
import {
Radar,
RadarChart,
PolarGrid,
PolarAngleAxis,
PolarRadiusAxis,
Treemap,
} from 'recharts';
import {
AutoSizer,
Card,
CardBody,
HeadingText,
NrqlQuery,
SegmentedControl,
SegmentedControlItem,
Spinner,
} from 'nr1';
const CHART_TYPES = {
'Radar': 'radar',
'Treemap': 'treemap'
}
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 = {
/**
* 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,
})
),
};
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} = this.props;
const nrqlQueryPropsAvailable =
nrqlQueries &&
nrqlQueries[0] &&
nrqlQueries[0].accountId &&
nrqlQueries[0].query;
if (!nrqlQueryPropsAvailable) {
return <EmptyState />;
}
return (
<AutoSizer>
{({width, height}) => (
<NrqlQuery
query={nrqlQueries[0].query}
accountId={parseInt(nrqlQueries[0].accountId)}
pollInterval={NrqlQuery.AUTO_POLL_INTERVAL}
>
{({data, loading, error}) => {
if (loading) {
return <Spinner />;
}
if (error) {
return <ErrorState />;
}
const transformedData = this.transformData(data);
return (
<React.Fragment>
<SegmentedControl
onChange={this.updateSelectedChart}
>
<SegmentedControlItem
value={CHART_TYPES.Radar}
label="Radar chart"
/>
<SegmentedControlItem
value={CHART_TYPES.Treemap}
label="Treemap chart"
/>
</SegmentedControl>
<RadarChart
width={width}
height={height}
data={transformedData}
>
<PolarGrid />
<PolarAngleAxis dataKey="name" />
<PolarRadiusAxis tickFormatter={this.formatTick} />
<Radar
dataKey="value"
stroke={stroke || '#51C9B7'}
fill={fill || '#51C9B7'}
fillOpacity={0.6}
/>
</RadarChart>
<Treemap
width={width}
height={height}
data={transformedData}
dataKey="value"
ratio={4 / 3}
stroke={stroke || '#000000'}
fill={fill || '#51C9B7'}
/>
</React.Fragment>
);
}}
</NrqlQuery>
)}
</AutoSizer>
);
}
}
const EmptyState = () => (
<Card className="EmptyState">
<CardBody className="EmptyState-cardBody">
<HeadingText
spacingType={[HeadingText.SPACING_TYPE.LARGE]}
type={HeadingText.TYPE.HEADING_3}
>
Please provide at least one NRQL query & account ID pair
</HeadingText>
<HeadingText
spacingType={[HeadingText.SPACING_TYPE.MEDIUM]}
type={HeadingText.TYPE.HEADING_4}
>
An example NRQL query you can try is:
</HeadingText>
<code>FROM NrUsage SELECT sum(usage) FACET metric SINCE 1 week ago</code>
</CardBody>
</Card>
);
const ErrorState = () => (
<Card className="ErrorState">
<CardBody className="ErrorState-cardBody">
<HeadingText
className="ErrorState-headingText"
spacingType={[HeadingText.SPACING_TYPE.LARGE]}
type={HeadingText.TYPE.HEADING_3}
>
Oops! Something went wrong.
</HeadingText>
</CardBody>
</Card>
);
visualizations/radar-or-treemap/index.js

Aquí, definió un nuevo componente Treemap con algunos accesorios, incluidos height, width, fill y stroke.

Con su Nerdpack servido localmente, vea su visualización. SegmentedControl y RadarChart están en la parte superior de la vista, pero si te desplazas hacia abajo, verás tu nuevo Treemap.

Cambie entre gráficos con los de su componente state

Emplee state.selectedChart para determinar qué gráfico mostrar: el RadarChart o el Treemap.

Desestructura this.state para acceder a selectedChart como una constante independiente. Luego, compare selectedChart con CHART_TYPES.Radar. Si son iguales, renderice un RadarChart. De lo contrario, renderice un Treemap:

import React from 'react';
import PropTypes from 'prop-types';
import {
Radar,
RadarChart,
PolarGrid,
PolarAngleAxis,
PolarRadiusAxis,
Treemap,
} from 'recharts';
import {
AutoSizer,
Card,
CardBody,
HeadingText,
NrqlQuery,
SegmentedControl,
SegmentedControlItem,
Spinner,
} from 'nr1';
const CHART_TYPES = {
'Radar': 'radar',
'Treemap': 'treemap'
}
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 = {
/**
* 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,
})
),
};
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} = this.props;
const {selectedChart} = this.state;
const nrqlQueryPropsAvailable =
nrqlQueries &&
nrqlQueries[0] &&
nrqlQueries[0].accountId &&
nrqlQueries[0].query;
if (!nrqlQueryPropsAvailable) {
return <EmptyState />;
}
return (
<AutoSizer>
{({width, height}) => (
<NrqlQuery
query={nrqlQueries[0].query}
accountId={parseInt(nrqlQueries[0].accountId)}
pollInterval={NrqlQuery.AUTO_POLL_INTERVAL}
>
{({data, loading, error}) => {
if (loading) {
return <Spinner />;
}
if (error) {
return <ErrorState />;
}
const transformedData = this.transformData(data);
return (
<React.Fragment>
<SegmentedControl
onChange={this.updateSelectedChart}
>
<SegmentedControlItem
value={CHART_TYPES.Radar}
label="Radar chart"
/>
<SegmentedControlItem
value={CHART_TYPES.Treemap}
label="Treemap chart"
/>
</SegmentedControl>
{selectedChart === CHART_TYPES.Radar ? (
<RadarChart
width={width}
height={height}
data={transformedData}
>
<PolarGrid />
<PolarAngleAxis dataKey="name" />
<PolarRadiusAxis tickFormatter={this.formatTick} />
<Radar
dataKey="value"
stroke={stroke || '#51C9B7'}
fill={fill || '#51C9B7'}
fillOpacity={0.6}
/>
</RadarChart>
) : (
<Treemap
width={width}
height={height}
data={transformedData}
dataKey="value"
ratio={4 / 3}
stroke={stroke || '#000000'}
fill={fill || '#51C9B7'}
/>
)}
</React.Fragment>
);
}}
</NrqlQuery>
)}
</AutoSizer>
);
}
}
const EmptyState = () => (
<Card className="EmptyState">
<CardBody className="EmptyState-cardBody">
<HeadingText
spacingType={[HeadingText.SPACING_TYPE.LARGE]}
type={HeadingText.TYPE.HEADING_3}
>
Please provide at least one NRQL query & account ID pair
</HeadingText>
<HeadingText
spacingType={[HeadingText.SPACING_TYPE.MEDIUM]}
type={HeadingText.TYPE.HEADING_4}
>
An example NRQL query you can try is:
</HeadingText>
<code>FROM NrUsage SELECT sum(usage) FACET metric SINCE 1 week ago</code>
</CardBody>
</Card>
);
const ErrorState = () => (
<Card className="ErrorState">
<CardBody className="ErrorState-cardBody">
<HeadingText
className="ErrorState-headingText"
spacingType={[HeadingText.SPACING_TYPE.LARGE]}
type={HeadingText.TYPE.HEADING_3}
>
Oops! Something went wrong.
</HeadingText>
</CardBody>
</Card>
);
visualizations/radar-or-treemap/index.js

Aquí, usaste una expresión ternaria para representar un RadarChart o un Treemap. El gráfico representado está determinado por el valor de selectedChart.

Con su Nerdpack servido localmente, vea su visualización.

Seleccione Radar chart de SegmentedControl.

Seleccione el Treemap chart de SegmentedControl.

Resumen

¡Felicidades! En esta lección, aprendió cómo:

  • Personalice su visualización empleando los componentes del SDK de New Relic One
  • Agregue un nuevo tipo de gráfico a su visualización
  • Crea una interacción de usuario en tu visualización.

Sugerencia

Esta lección es parte de un curso que le muestra cómo crear una visualización personalizada en la plataforma New Relic. Cuando esté listo, continúe con la siguiente lección: Personalizar visualizaciones con configuración.

Copyright © 2024 New Relic Inc.

This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.