From e1f4cd0057879db9b1034561680322799979eff1 Mon Sep 17 00:00:00 2001 From: Bilawal Hameed Date: Sat, 2 May 2020 14:37:37 +0200 Subject: [PATCH 1/8] feature: split tech-radar api to component/plugin props --- plugins/tech-radar/src/api.ts | 65 ++++++++++++++++++++++++----------- 1 file changed, 45 insertions(+), 20 deletions(-) diff --git a/plugins/tech-radar/src/api.ts b/plugins/tech-radar/src/api.ts index 78f07bfd4b..4893901342 100644 --- a/plugins/tech-radar/src/api.ts +++ b/plugins/tech-radar/src/api.ts @@ -16,6 +16,10 @@ import { ApiRef } from '@backstage/core'; +/** + * Types related to the Radar's visualization. + */ + export interface RadarRing { id: string; name: string; @@ -37,42 +41,63 @@ export interface RadarEntry { url: string; } +/** + * Types related to data collection for the Radar. + */ + export interface TechRadarLoaderResponse { quadrants: RadarQuadrant[]; rings: RadarRing[]; entries: RadarEntry[]; } -export interface TechRadarAdditionalOptions { - title?: string; - subtitle?: string; +/** + * Set up the Radar as a Backstage component. + */ + +export interface TechRadarComponentProps { + width: number; + height: number; + getData?: () => Promise; svgProps?: object; } -export interface TechRadarApi { - width: number; - height: number; - load: () => Promise; - additionalOpts: TechRadarAdditionalOptions; +/** + * Set up the Radar as a Backstage plugin. + */ + +export interface TechRadarApi extends TechRadarComponentProps { + title?: string; + subtitle?: string; } export const techRadarApiRef = new ApiRef({ id: 'plugin.techradar', - description: 'Used by the Tech Radar to render the diagram', + description: 'Used by the Tech Radar to render the visualization', }); export class TechRadar implements TechRadarApi { - private defaultAdditionalOpts: Partial = { - title: 'Tech Radar', - subtitle: 'Welcome to the Tech Radar!', - }; + // Default columns + public width: TechRadarApi['width']; + public height: TechRadarApi['height']; + public getData: TechRadarApi['getData']; + public svgProps: TechRadarApi['svgProps']; + public title: TechRadarApi['title']; + public subtitle: TechRadarApi['subtitle']; - constructor( - public width: number, - public height: number, - public load: () => Promise, - public additionalOpts: TechRadarAdditionalOptions = {}, - ) { - this.additionalOpts = { ...this.defaultAdditionalOpts, ...additionalOpts }; + constructor(overrideOptions: TechRadarApi) { + const defaultOptions: Partial = { + title: 'Tech Radar', + subtitle: 'Welcome to the Tech Radar!', + }; + + const options = { ...defaultOptions, ...overrideOptions }; + + this.width = options.width; + this.height = options.height; + this.getData = options.getData; + this.svgProps = options.svgProps; + this.title = options.title; + this.subtitle = options.subtitle; } } From ef9e6ba6a8d9bd910bd6e5bbc1ad9cd37c0be613 Mon Sep 17 00:00:00 2001 From: Bilawal Hameed Date: Sat, 2 May 2020 14:39:07 +0200 Subject: [PATCH 2/8] feature: add RadarComponent and export as TechRadarComponent --- .../src/components/RadarComponent.tsx | 85 +++++++++++++++++++ plugins/tech-radar/src/index.ts | 10 +-- 2 files changed, 88 insertions(+), 7 deletions(-) create mode 100644 plugins/tech-radar/src/components/RadarComponent.tsx diff --git a/plugins/tech-radar/src/components/RadarComponent.tsx b/plugins/tech-radar/src/components/RadarComponent.tsx new file mode 100644 index 0000000000..ffa6953986 --- /dev/null +++ b/plugins/tech-radar/src/components/RadarComponent.tsx @@ -0,0 +1,85 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import React, { useEffect, useState, FC } from 'react'; +import { Progress, useApi, errorApiRef, ErrorApi } from '@backstage/core'; +import Radar from '../components/Radar'; +import { TechRadarComponentProps, TechRadarLoaderResponse } from '../api'; +import getSampleData from '../sampleData'; + +const useTechRadarLoader = (props: TechRadarComponentProps) => { + const [state, setState] = useState<{ + loading: boolean; + error?: Error; + data?: TechRadarLoaderResponse; + }>({ + loading: true, + error: undefined, + data: undefined, + }); + + useEffect(() => { + if (!props.getData) { + return; + } + + props + .getData() + .then((payload: TechRadarLoaderResponse) => { + setState({ loading: false, error: undefined, data: payload }); + }) + .catch((err: Error) => { + setState({ + loading: false, + error: err, + data: undefined, + }); + }); + }, []); + + return state; +}; + +const RadarComponent: FC = props => { + const errorApi = useApi(errorApiRef); + const { loading, error, data } = useTechRadarLoader(props); + + useEffect(() => { + if (error) { + errorApi.post(error); + } + }, [error && error.message]); + + return ( + <> + {loading && } + {!loading && !error && ( + + )} + + ); +}; + +RadarComponent.defaultProps = { + getData: getSampleData, +}; + +export default RadarComponent; diff --git a/plugins/tech-radar/src/index.ts b/plugins/tech-radar/src/index.ts index 926a7b410f..df22e57558 100644 --- a/plugins/tech-radar/src/index.ts +++ b/plugins/tech-radar/src/index.ts @@ -17,15 +17,11 @@ export { plugin } from './plugin'; /** - * The API for configuring the Tech Radar in a Backstage deployment. + * The TypeScript API for configuring Tech Radar. */ export * from './api'; /** - * Load sample data for Backstage users to get setup quickly. - * - * @example - * import { techRadarApiRef, TechRadar, loadSampleData } from '@backstage/plugin-tech-radar'; - * builder.add(techRadarApiRef, new TechRadar(800, 500, loadSampleData)); + * The React component for more advanced use cases. */ -export { default as loadSampleData } from './sampleData'; +export { default as TechRadarComponent } from './components/RadarComponent'; From 2c146cc86b3b485f387a52936f2cddf6f3c84d2c Mon Sep 17 00:00:00 2001 From: Bilawal Hameed Date: Sat, 2 May 2020 14:39:31 +0200 Subject: [PATCH 3/8] fix: rename loadSampleData to getSampleData --- plugins/tech-radar/src/sampleData.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/tech-radar/src/sampleData.ts b/plugins/tech-radar/src/sampleData.ts index dc8c67106e..8372e8a69f 100644 --- a/plugins/tech-radar/src/sampleData.ts +++ b/plugins/tech-radar/src/sampleData.ts @@ -98,7 +98,7 @@ entries.push({ quadrant: 'infrastructure', }); -export default function loadSampleData(): Promise { +export default function getSampleData(): Promise { return Promise.resolve({ rings, quadrants, From d04855e98afbea5b2e63dafe32f5141a99b029b4 Mon Sep 17 00:00:00 2001 From: Bilawal Hameed Date: Sat, 2 May 2020 14:40:12 +0200 Subject: [PATCH 4/8] fix: RadarPage uses RadarComponent under the hood --- .../tech-radar/src/components/RadarPage.tsx | 71 ++----------------- 1 file changed, 6 insertions(+), 65 deletions(-) diff --git a/plugins/tech-radar/src/components/RadarPage.tsx b/plugins/tech-radar/src/components/RadarPage.tsx index 0ea3d8743a..395939845b 100644 --- a/plugins/tech-radar/src/components/RadarPage.tsx +++ b/plugins/tech-radar/src/components/RadarPage.tsx @@ -14,81 +14,22 @@ * limitations under the License. */ -import React, { useEffect, useState, FC } from 'react'; +import React, { FC } from 'react'; import { Grid } from '@material-ui/core'; -import { - Progress, - Page, - Header, - Content, - pageTheme, - useApi, - errorApiRef, - ErrorApi, -} from '@backstage/core'; -import Radar from '../components/Radar'; -import { techRadarApiRef, TechRadarApi, TechRadarLoaderResponse } from '../api'; - -const useTechRadarLoader = (techRadarApi: TechRadarApi) => { - const [state, setState] = useState<{ - loading: boolean; - error?: Error; - data?: TechRadarLoaderResponse; - }>({ - loading: true, - error: undefined, - data: undefined, - }); - - useEffect(() => { - techRadarApi - .load() - .then((payload: TechRadarLoaderResponse) => { - setState({ loading: false, error: undefined, data: payload }); - }) - .catch((err: Error) => { - setState({ - loading: false, - error: err, - data: undefined, - }); - }); - }, []); - - return state; -}; +import { Page, Header, Content, pageTheme, useApi } from '@backstage/core'; +import RadarComponent from '../components/RadarComponent'; +import { techRadarApiRef, TechRadarApi } from '../api'; const RadarPage: FC<{}> = () => { - const errorApi = useApi(errorApiRef); const techRadarApi = useApi(techRadarApiRef); - const { loading, error, data } = useTechRadarLoader(techRadarApi); - - useEffect(() => { - if (error) { - errorApi.post(error); - } - }, [error && error.message]); return ( -
+
- {loading && } - {!loading && !error && ( - - )} + From a4c05f203fd2dd8006ea1deeb4e3fbecb218ff1f Mon Sep 17 00:00:00 2001 From: Bilawal Hameed Date: Sat, 2 May 2020 14:40:31 +0200 Subject: [PATCH 5/8] fix: updated tests for RadarPage and RadarComponent --- .../src/components/RadarComponent.test.tsx | 102 ++++++++++++++++++ .../src/components/RadarPage.test.tsx | 20 +++- 2 files changed, 117 insertions(+), 5 deletions(-) create mode 100644 plugins/tech-radar/src/components/RadarComponent.test.tsx diff --git a/plugins/tech-radar/src/components/RadarComponent.test.tsx b/plugins/tech-radar/src/components/RadarComponent.test.tsx new file mode 100644 index 0000000000..2f3fcff198 --- /dev/null +++ b/plugins/tech-radar/src/components/RadarComponent.test.tsx @@ -0,0 +1,102 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import React from 'react'; +import { render, waitForElement } from '@testing-library/react'; +import { ThemeProvider } from '@material-ui/core'; +import { lightTheme } from '@backstage/theme'; +import { ApiRegistry, ApiProvider, errorApiRef } from '@backstage/core'; +import { withLogCollector } from '@backstage/test-utils-core'; + +import GetBBoxPolyfill from '../utils/polyfills/getBBox'; +import RadarComponent from './RadarComponent'; + +describe('RadarComponent', () => { + beforeAll(() => { + GetBBoxPolyfill.create(0, 0, 1000, 500); + }); + + afterAll(() => { + GetBBoxPolyfill.remove(); + }); + + it('should render a progress bar', async () => { + const errorApi = { post: () => {} }; + + const { getByTestId, queryByTestId } = render( + + + + + , + ); + + expect(getByTestId('progress')).toBeInTheDocument(); + + await waitForElement(() => queryByTestId('tech-radar-svg')); + }); + + it('should call the errorApi if load fails', async () => { + const errorApi = { post: jest.fn() }; + const techRadarLoadFail = () => + Promise.reject(new Error('404 Page Not Found')); + + const { queryByTestId } = render( + + + + + , + ); + + await waitForElement(() => !queryByTestId('progress')); + + expect(errorApi.post).toHaveBeenCalledTimes(1); + expect(errorApi.post).toHaveBeenCalledWith(new Error('404 Page Not Found')); + expect(queryByTestId('tech-radar-svg')).not.toBeInTheDocument(); + }); + + it('should not render without errorApiRef', () => { + expect( + withLogCollector(['error'], () => { + expect(() => { + render( + + + + + , + ); + }).toThrow(); + }).error[0], + ).toMatch( + /^Error: Uncaught \[Error: No implementation available for apiRef{core.error}\]/, + ); + }); +}); diff --git a/plugins/tech-radar/src/components/RadarPage.test.tsx b/plugins/tech-radar/src/components/RadarPage.test.tsx index 9913895949..5ef71d1693 100644 --- a/plugins/tech-radar/src/components/RadarPage.test.tsx +++ b/plugins/tech-radar/src/components/RadarPage.test.tsx @@ -22,7 +22,7 @@ import { ApiRegistry, ApiProvider, errorApiRef } from '@backstage/core'; import { withLogCollector } from '@backstage/test-utils-core'; import GetBBoxPolyfill from '../utils/polyfills/getBBox'; -import { techRadarApiRef, TechRadar, loadSampleData } from '../index'; +import { techRadarApiRef, TechRadar } from '../index'; import RadarPage from './RadarPage'; describe('RadarPage', () => { @@ -36,7 +36,9 @@ describe('RadarPage', () => { it('should render a progress bar', async () => { const errorApi = { post: () => {} }; - const techRadarApi = new TechRadar(1200, 800, loadSampleData, { + const techRadarApi = new TechRadar({ + width: 1200, + height: 800, svgProps: { 'data-testid': 'tech-radar-svg' }, }); @@ -60,7 +62,9 @@ describe('RadarPage', () => { it('should render a header with a svg', async () => { const errorApi = { post: () => {} }; - const techRadarApi = new TechRadar(1200, 800, loadSampleData, { + const techRadarApi = new TechRadar({ + width: 1200, + height: 800, svgProps: { 'data-testid': 'tech-radar-svg' }, }); @@ -87,7 +91,10 @@ describe('RadarPage', () => { const errorApi = { post: jest.fn() }; const techRadarLoadFail = () => Promise.reject(new Error('404 Page Not Found')); - const techRadarApi = new TechRadar(1200, 800, techRadarLoadFail, { + const techRadarApi = new TechRadar({ + width: 1200, + height: 800, + getData: techRadarLoadFail, svgProps: { 'data-testid': 'tech-radar-svg' }, }); @@ -112,7 +119,10 @@ describe('RadarPage', () => { }); it('should not render without errorApiRef', () => { - const techRadarApi = new TechRadar(1200, 800, loadSampleData); + const techRadarApi = new TechRadar({ + width: 1200, + height: 800, + }); expect( withLogCollector(['error'], () => { From 27aa58470a4283358b995157ded445ed9ff467da Mon Sep 17 00:00:00 2001 From: Bilawal Hameed Date: Sat, 2 May 2020 14:40:43 +0200 Subject: [PATCH 6/8] fix: updated docs --- plugins/tech-radar/README.md | 164 ++++++++++++++++++++--------------- 1 file changed, 95 insertions(+), 69 deletions(-) diff --git a/plugins/tech-radar/README.md b/plugins/tech-radar/README.md index d48cd969a8..ea3faf8e19 100644 --- a/plugins/tech-radar/README.md +++ b/plugins/tech-radar/README.md @@ -1,89 +1,120 @@ # @backstage/plugin-tech-radar -Screenshot of Tech Radar plugin +Screenshot of Tech Radar plugin The Backstage integration for the Tech Radar based on [Zalando's Tech Radar](https://opensource.zalando.com/tech-radar/) open sourced on [GitHub](https://github.com/zalando/tech-radar). This is used at [Spotify](https://spotify.github.io) for visualizing the official guidelines of different areas of software development such as languages, frameworks, infrastructure and processes. ## Purpose -Zalando explains it very well on their website: +Zalando has a fantastic description [on their website](https://opensource.zalando.com/tech-radar/): > The Tech Radar is a tool to inspire and support engineering teams at Zalando to pick the best technologies for new projects; it provides a platform to share knowledge and experience in technologies, to reflect on technology decisions and continuously evolve our technology landscape. Based on the pioneering work of ThoughtWorks, our Tech Radar sets out the changes in technologies that are interesting in software development — changes that we think our engineering teams should pay attention to and consider using in their projects. -It serves well for teams and companies of all sizes that want to have alignment and wish to visualize it. It scales well for companies who have dozens of different technologies in place. +It serves and scales well for teams and companies of all sizes that want to have alignment across dozens of technologies and visualize it in a simple way. ## Getting Started -In your installation, add the dependency to your Backstage installation: +The Tech Radar can be used in two ways: + +- **Simple (Recommended)** - This gives you an out-of-the-box Tech Radar experience. It lives on the `/tech-radar` URL of your Backstage installation, and you can set a variety of configuration directly in your `apis.ts`. +- **Advanced** - This gives you the React UI component directly. It enables you to insert the Radar on your own layout or page for a more customized feel. + +### Install + +For either simple or advanced installations, you'll need to add the dependency using Yarn: ```sh yarn add @backstage/plugin-tech-radar ``` -In your `apis.ts` set up the "out of the box" implementation for Tech Radar: +### Simple Configuration + +In your `apis.ts` set up the simple "out of the box" implementation for Tech Radar: ```ts import { ApiHolder, ApiRegistry } from '@backstage/core'; import { techRadarApiRef, TechRadar, - loadSampleData, } from '@backstage/plugin-tech-radar'; const builder = ApiRegistry.builder(); -builder.add(techRadarApiRef, new TechRadar(1400, 800, loadSampleData)); +builder.add(techRadarApiRef, new TechRadar({ + width: 1400, + height: 800 +)); export default builder.build() as ApiHolder; ``` -It will then be available on your Backstage installation over at +Congrats, you're done! We'll just load it with [example data](src/sampleData.ts) to get you started. Just go to to see it live in action. -## Configuration - -The implementation for the TechRadar class is: +And if you'd like to configure it more, such as providing it with your own data, see the `TechRadarApi` TypeScript interface below for the options: ```ts -export interface TechRadarAdditionalOptions { - title?: string; - subtitle?: string; +export interface TechRadarComponentProps { + width: number; + height: number; + getData?: () => Promise; svgProps?: object; } -export interface TechRadarLoaderResponse { - quadrants: RadarQuadrant[]; - rings: RadarRing[]; - entries: RadarEntry[]; +export interface TechRadarApi extends TechRadarComponentProps { + title?: string; + subtitle?: string; } - -export interface TechRadarApi { - width: number; - height: number; - load: () => Promise; - additionalOpts: TechRadarAdditionalOptions; -} - -// Constructor signature for the `TechRadar` class -// constructor( -// public width: number, -// public height: number, -// public load: () => Promise, -// public additionalOpts: TechRadarAdditionalOptions = {}, -// ) ``` -The source code is available in [api.ts](src/api.ts). +You can see the API directly over at . -## Code Samples +### Advanced Configuration -### Set up Tech Radar with sample data +This way won't expose an `/tech-radar` path. Instead, you'll need to create your own Backstage plugin and use the Tech Radar as any other React UI component. -See example above. +In your Backstage app, run the following command: -### Set up Tech Radar with hard-coded values +```sh +yarn create-plugin +``` + +In your plugin, in any React component you'd like to import the Tech Radar, do the following: + +```tsx +import { TechRadarComponent } from '@backstage/plugin-tech-radar'; + +function MyCustomRadar() { + return ; +} +``` + +If you'd like to configure it more, see the `TechRadarComponentProps` TypeScript interface for options: ```ts -const hardCodedData = () => +export interface TechRadarComponentProps { + width: number; + height: number; + getData?: () => Promise; + svgProps?: object; +} +``` + +You can see the API directly over at . + +## Frequently Asked Questions + +### Who created the Tech Radar? + +[ThoughtWorks](https://thoughtworks.com/radar) created the Tech Radar concept, and [Zalando created the visualization](https://opensource.zalando.com/tech-radar/) that we use at Spotify and in this plugin. + +### How do I load in my own data? + +It's simple. In both the Simple (Backstage plugin) and Advanced (React component) configurations, you can pass through a `getData` prop which expects a `Promise` signature. See more in . + +Here's an example: + +```tsx +const getHardCodedData = () => Promise.resolve({ quadrants: [{ id: 'infrastructure', name: 'Infrastructure' }], rings: [{ id: 'use', name: 'USE', color: '#93c47d' }], @@ -100,48 +131,43 @@ const hardCodedData = () => ], }); -builder.add(techRadarApiRef, new TechRadar(1400, 800, hardCodedData)); +// Simple +builder.add(techRadarApiRef, new TechRadar({ + width: 1400, + height: 800 + getData: getHardCodedData +)); + +// Advanced + ``` -### Set up Tech Radar with an API call - -```ts -const apiRetrievedData = async () => { - const response = await fetch('http://example.com/tech-radar-values.json'); - const json = await response.json(); - return json as TechRadarLoaderResponse; -}; - -builder.add(techRadarApiRef, new TechRadar(1400, 800, apiRetrievedData)); -``` - -### Use a custom title and subtitle +### How do I write tests? + +You can use the `svgProps` option to pass custom React props to the `` element we create for the Tech Radar. This complements well with the `data-testid` attribute and the `@testing-library/react` library we use in Backstage. ```ts +// Simple builder.add( techRadarApiRef, - new TechRadar(1400, 800, loadSampleData, { - title: 'My Company Tech Radar', - subtitle: 'Learn about what technologies we use at My Company.', - }), -); -``` - -### Use custom props - -Great for testing through adding a `data-testid` for being able to test with `@testing-library/react` - -```ts -builder.add( - techRadarApiRef, - new TechRadar(1400, 800, loadSampleData, { + new TechRadar({ + width: 1400, + height: 800, svgProps: { - // for the main tag of the visualization 'data-testid': 'tech-radar-svg', }, }), ); +// Advanced +; + // Then, in your tests... // const { getByTestId } = render(...); // expect(getByTestId('tech-radar-svg')).toBeInTheDocument(); From 8c1fd6e7d1f6a352caf76fe2176d5d218918ae28 Mon Sep 17 00:00:00 2001 From: Bilawal Hameed Date: Sat, 2 May 2020 14:45:49 +0200 Subject: [PATCH 7/8] fix: update app to use new Radar API --- packages/app/src/apis.ts | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/packages/app/src/apis.ts b/packages/app/src/apis.ts index a24a25e205..2ec865fac3 100644 --- a/packages/app/src/apis.ts +++ b/packages/app/src/apis.ts @@ -30,11 +30,7 @@ import { LighthouseRestApi, } from '@backstage/plugin-lighthouse'; -import { - techRadarApiRef, - TechRadar, - loadSampleData, -} from '@backstage/plugin-tech-radar'; +import { techRadarApiRef, TechRadar } from '@backstage/plugin-tech-radar'; const builder = ApiRegistry.builder(); @@ -47,6 +43,13 @@ builder.add(errorApiRef, errorApiForwarder); builder.add(featureFlagsApiRef, new FeatureFlags()); builder.add(lighthouseApiRef, new LighthouseRestApi('http://localhost:3003')); -builder.add(techRadarApiRef, new TechRadar(1800, 800, loadSampleData)); + +builder.add( + techRadarApiRef, + new TechRadar({ + width: 1500, + height: 800, + }), +); export default builder.build() as ApiHolder; From d0e245ee3b29cf3e7043ad747e42239946757fe5 Mon Sep 17 00:00:00 2001 From: Bilawal Hameed Date: Sat, 2 May 2020 15:05:41 +0200 Subject: [PATCH 8/8] fix: some incorrectly formatted markdown --- plugins/tech-radar/README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/plugins/tech-radar/README.md b/plugins/tech-radar/README.md index ea3faf8e19..49a5bb3add 100644 --- a/plugins/tech-radar/README.md +++ b/plugins/tech-radar/README.md @@ -66,7 +66,7 @@ export interface TechRadarApi extends TechRadarComponentProps { } ``` -You can see the API directly over at . +You can see the API directly over at [src/api.ts](./src/api.ts). ### Advanced Configuration @@ -99,7 +99,7 @@ export interface TechRadarComponentProps { } ``` -You can see the API directly over at . +You can see the API directly over at [src/api.ts](./src/api.ts). ## Frequently Asked Questions @@ -109,7 +109,7 @@ You can see the API directly over at . ### How do I load in my own data? -It's simple. In both the Simple (Backstage plugin) and Advanced (React component) configurations, you can pass through a `getData` prop which expects a `Promise` signature. See more in . +It's simple. In both the Simple (Backstage plugin) and Advanced (React component) configurations, you can pass through a `getData` prop which expects a `Promise` signature. See more in [src/api.ts](./src/api.ts). Here's an example: @@ -134,7 +134,7 @@ const getHardCodedData = () => // Simple builder.add(techRadarApiRef, new TechRadar({ width: 1400, - height: 800 + height: 800, getData: getHardCodedData ));