diff --git a/demo/ts/components/victory-legend-demo.tsx b/demo/ts/components/victory-legend-demo.tsx index ea34f5153..92a987b09 100644 --- a/demo/ts/components/victory-legend-demo.tsx +++ b/demo/ts/components/victory-legend-demo.tsx @@ -1,6 +1,7 @@ -import React from "react"; +import React, { useState } from "react"; import { VictoryLabel, Border, VictoryTheme } from "victory-core"; import { VictoryLegend } from "victory-legend"; +import { FaMoon, FaSun, FaStar } from 'react-icons/fa' const legendStyle = { labels: { fontSize: 14, fontFamily: "Palatino" }, @@ -73,6 +74,65 @@ const data = [ }, ]; +const customIconData = [ + { + name: "Series 1", + symbol: { + size: symbolSize, + fill: "green", + }, + }, + { + name: "Long Series Name -- so long", + symbol: { + size: symbolSize, + fill: "blue", + }, + }, + { + name: "Series 3", + symbol: { + size: symbolSize, + fill: "pink", + }, + }] + +const CustomSun = (props) => { + return ; +}; + +const CustomMoon = (props) => { + const [iconColor, setIconColor] = useState(props?.style?.fill || "green"); + const [icon, setIcon] = useState("moon"); + if (icon === "moon") { + return ( + { + setIcon("star"); + setIconColor("red"); + }} + /> + ); + } + return ( + { + setIcon("moon"); + setIconColor("blue"); + }} + /> + ); +}; + + const LegendDemo = () => (
@@ -176,8 +236,11 @@ const LegendDemo = () => ( } + borderComponent={} centerTitle + x={25} + y={20} + standalone={false} title={["TITLE"]} gutter={30} symbolSpacer={symbolSpacer} @@ -185,7 +248,40 @@ const LegendDemo = () => ( data={data} style={legendStyle} /> - + + {/* CustomIcon */} + + } + data={customIconData} + style={legendStyle} + /> + + {/* CustomIcon with events*/} + + } + symbolSpacer={symbolSpacer} + titleComponent={ + + } + /> +
); diff --git a/demo/ts/components/victory-scatter-demo.tsx b/demo/ts/components/victory-scatter-demo.tsx index 10d2f99c4..afdcd22d5 100644 --- a/demo/ts/components/victory-scatter-demo.tsx +++ b/demo/ts/components/victory-scatter-demo.tsx @@ -1,5 +1,5 @@ /* eslint-disable no-magic-numbers,react/no-multi-comp */ -import React from "react"; +import React, { useState } from "react"; import PropTypes from "prop-types"; import { random, range } from "lodash"; import { VictoryScatter } from "victory-scatter"; @@ -11,6 +11,11 @@ import { } from "victory-core"; import bubbleData from "./bubble-data"; import symbolData from "./symbol-data"; +import { + FaMoon, + FaFootballBall, + FaSun, +} from "react-icons/fa"; type DataType = { x?: string | number; @@ -94,6 +99,41 @@ const symbolStyle = { fill: "grey", }, }; +const CustomSunIcon = (props) => ( + +); + +const CustomCustomIconWithEvents = (props) => { + const [iconColor, setIconColor] = useState(props?.style?.fill || "green"); + const [icon, setIcon] = useState("moon"); + if (icon === "moon") { + return ( + { + setIcon("star"); + setIconColor("red"); + }} + /> + ); + } + return ( + { + setIcon("moon"); + setIconColor("blue"); + }} + /> + ); +}; + class CatPoint extends React.Component { static propTypes = { @@ -289,6 +329,28 @@ export default class VictoryScatterDemo extends React.Component< x="a.x" y="a.b[0]y" /> + {/* custom icons */} + } + /> + } + size={25} + samples={10} + />
); } diff --git a/docs/package.json b/docs/package.json index 1160c4ef1..088825cb3 100644 --- a/docs/package.json +++ b/docs/package.json @@ -42,6 +42,7 @@ "prism-react-renderer": "^2.3.1", "react-cool-inview": "^3.0.1", "react-copy-to-clipboard": "^5.1.0", + "react-icons": "^5.3.0", "react-inlinesvg": "^4.1.1", "react-live": "^4.1.6", "react-markdown": "^9.0.1", diff --git a/docs/src/content/docs/victory-legend.md b/docs/src/content/docs/victory-legend.md index e0f629d95..88b7e7915 100644 --- a/docs/src/content/docs/victory-legend.md +++ b/docs/src/content/docs/victory-legend.md @@ -3,7 +3,8 @@ id: 16 title: VictoryLegend category: more type: docs -scope: null +scope: + - reactIconsFa --- # VictoryLegend @@ -112,7 +113,7 @@ containerComponent={} `type: array[{ name, symbol, labels }]` -Specify data via the `data` prop. `VictoryLegend` expects data as an array of objects with `name` (required), `symbol`, and `labels` properties. The `data` prop must be given as an array. The symbol rendered may be changed by altering the `type` property of the `symbol` object. Valid types include: circle", "diamond", "plus", "minus", "square", "star", "triangleDown", and "triangleUp" +Specify data via the `data` prop. `VictoryLegend` expects data as an array of objects with `name` (required), `symbol`, and `labels` properties. The `data` prop must be given as an array. The symbol rendered may be changed by altering the `type` property of the `symbol` object. Valid types include: circle", "diamond", "plus", "minus", "square", "star", "triangleDown", and "triangleUp".If you want to use SVG icons from a custom component or an SVG based icon library like [react-icons](https://react-icons.github.io/react-icons/) use `dataComponent` property.[Read about it here](#datacomponent) _default:_ `data={[{ name: "Series 1" }, { name: "Series 2" }]}` @@ -135,6 +136,99 @@ _default:_ `data={[{ name: "Series 1" }, { name: "Series 2" }]}` `VictoryLegend` uses the standard `dataComponent` prop. [Read about it here](/docs/common-props#datacomponent) +An example of using Custom icons as `dataComponent` in `VictoryLegend`. + +```playground_norender +const { FaSun, FaMoon } = reactIconsFa; + +const CustomMoon = (props) => { + const [iconColor, setIconColor] = React.useState( + props?.style?.fill || "green", + ); + const [icon, setIcon] = React.useState("moon"); + if (icon === "moon") { + return ( + { + setIcon("sun"); + setIconColor("red"); + }} + /> + ); + } + return ( + { + setIcon("moon"); + setIconColor("blue"); + }} + /> + ); +}; + +function App() { + return ( + + } + /> + + ); +} + +render(); +``` + +An example of using multiple Custom icons as `dataComponent` in `VictoryLegend`. + +```playground_norender +const { FaSun, FaMoon, FaStar } = reactIconsFa; + +const CustomMultipleIcon = (props) => { + const { x, y, datum } = props; + if (datum.name === "One") { + return ; + } + if (datum.name === "Two") { + return ; + } + return ; +}; + +function App() { + return ( + + } + /> + + ); +} + +render(); + +``` + `VictoryLegend` supplies the following props to its `dataComponent`: `data`, `datum`, `events`, `index`, `x`, `y`, `size`, `style`, and `symbol`. `VictoryLegend` renders a [Point component][] by default. See the [Custom Components Guide][] for more detail on creating your own `dataComponents` diff --git a/docs/src/content/docs/victory-scatter.md b/docs/src/content/docs/victory-scatter.md index 029bdeeef..8b186d9b7 100644 --- a/docs/src/content/docs/victory-scatter.md +++ b/docs/src/content/docs/victory-scatter.md @@ -5,6 +5,7 @@ category: charts type: docs scope: - sampleData + - reactIconsFa --- # VictoryScatter @@ -99,6 +100,8 @@ See the [Data Accessors Guide][] for more detail on formatting and processing da In addition to svg style properties and `label`, `VictoryScatter` will also preferentially use `symbol` and `size` properties supplied via data objects. +If you want to use SVG icons from a custom component or an SVG based icon library like [react-icons](https://react-icons.github.io/react-icons/) use `dataComponent` property.[Read about it here](#datacomponent) + ```playground ); ``` +An example of using Custom icons as `dataComponent` in `VictoryScatter`. + +```playground_norender +const { FaCat, FaStar } = reactIconsFa; +const CustomCatStarIcon = (props) => { + const { x, y, datum } = props; + if (datum._y >= 0.5) { + return ; + } + return ; +}; + +function App() { + return ( + + } samples={15} /> + + ); +} +render(); +``` ## domain `type: array[low, high] || { x: [low, high], y: [low, high] }` @@ -532,6 +556,8 @@ _default (provided by default theme):_ See [grayscale theme][] for more detail The `symbol` prop determines which symbol should be drawn to represent data points. Options are: "circle", "cross", "diamond", "plus", "minus", "square", "star", "triangleDown", "triangleUp". When this prop is given as a function, it will be evaluated for each point with the props corresponding to that point. If no `symbol` prop is specified, a circle will be rendered. `symbol` may also be set directly on each data object. +If you want to use SVG icons from a custom component or an SVG based icon library like [react-icons](https://react-icons.github.io/react-icons/) use dataComponent property.[Read about it here](#datacomponent) + _default:_ `symbol="circle"` ```playground diff --git a/docs/src/content/guides/custom-components.md b/docs/src/content/guides/custom-components.md index 066dadfd2..82fbd5768 100644 --- a/docs/src/content/guides/custom-components.md +++ b/docs/src/content/guides/custom-components.md @@ -5,6 +5,7 @@ category: guides scope: - range - random + - reactIconsFa --- # Custom Components @@ -106,6 +107,39 @@ function App() { ); } render(); +``` +An example of using Custom icons as `dataComponent` in `VictoryScatter`. + +```playground_norender +const { FaCat } = reactIconsFa; + +const CustomCatIcon = (props) => { + const { x, y } = props; + const [iconColor, setIconColor] = React.useState( + props?.style?.fill || "black", + ); + return ( + { + setIconColor("orange"); + }} + /> + ); +}; + +function App() { + return ( + + } samples={15} /> + + ); +} +render(); + ``` More complex components may be supplied as direct children of `VictoryChart`. These components will have access to shared chart props such as `scale`. In the example below, the custom `Polygon` components draws a polygon based on a collection of points. The scale provided by `VictoryChart` is used to correctly position the points within the chart. diff --git a/docs/src/partials/markdown/scope-map.js b/docs/src/partials/markdown/scope-map.js index 0393626a7..4381183ce 100644 --- a/docs/src/partials/markdown/scope-map.js +++ b/docs/src/partials/markdown/scope-map.js @@ -5,6 +5,7 @@ import _ from "lodash"; import * as d3Array from "d3-array"; import * as d3Scale from "d3-scale"; import * as d3Time from "d3-time"; +import * as reactIconsFa from 'react-icons/fa' import styled from "styled-components"; import basketballData from "../../data/basketball-data"; @@ -25,6 +26,7 @@ const scopeMap = { Slider, basketballData, listeningData, + reactIconsFa, sampleData: [ { x: 1, diff --git a/package.json b/package.json index 1dfdcf200..3338d8e42 100644 --- a/package.json +++ b/package.json @@ -90,6 +90,7 @@ "react": "^18.1.0", "react-dom": "^18.1.0", "react-hot-loader": "4.13.0", + "react-icons": "^5.3.0", "react-test-renderer": "^18.1.0", "remark-parse": "^7.0.1", "remark-stringify": "^7.0.3", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f57fd7d14..0638a089e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -72,6 +72,7 @@ importers: react: ^18.1.0 react-dom: ^18.1.0 react-hot-loader: 4.13.0 + react-icons: ^5.3.0 react-test-renderer: ^18.1.0 remark-parse: ^7.0.1 remark-stringify: ^7.0.3 @@ -156,6 +157,7 @@ importers: react: 18.2.0 react-dom: 18.2.0_react@18.2.0 react-hot-loader: 4.13.0_bb2bxwco6ptpubzwpazr52qf6i + react-icons: 5.3.0_react@18.2.0 react-test-renderer: 18.2.0_react@18.2.0 remark-parse: 7.0.2 remark-stringify: 7.0.4 @@ -301,6 +303,7 @@ importers: react-cool-inview: ^3.0.1 react-copy-to-clipboard: ^5.1.0 react-dom: ^18 + react-icons: ^5.3.0 react-inlinesvg: ^4.1.1 react-live: ^4.1.6 react-markdown: ^9.0.1 @@ -345,6 +348,7 @@ importers: prism-react-renderer: 2.3.1_react@18.2.0 react-cool-inview: 3.0.1_react@18.2.0 react-copy-to-clipboard: 5.1.0_react@18.2.0 + react-icons: 5.3.0_react@18.2.0 react-inlinesvg: 4.1.3_react@18.2.0 react-live: 4.1.6_biqbaboplfbrettd7655fr4n2y react-markdown: 9.0.1_3hx2ussxxho4jajbwrd6gq34qe @@ -361,6 +365,7 @@ importers: packages/victory: specifiers: + react: '>=16.6.0' victory-area: 37.1.1 victory-axis: 37.1.1 victory-bar: 37.1.1 @@ -388,7 +393,6 @@ importers: victory-voronoi: 37.1.1 victory-voronoi-container: 37.1.1 victory-zoom-container: 37.1.1 - react: '>=16.6.0' dependencies: react: 18.2.0 victory-area: link:../victory-area @@ -437,8 +441,8 @@ importers: packages/victory-axis: specifiers: lodash: ^4.17.19 - victory-core: 37.1.1 react: '>=16.6.0' + victory-core: 37.1.1 dependencies: lodash: 4.17.21 react: 18.2.0 @@ -516,9 +520,9 @@ importers: packages/victory-canvas: specifiers: lodash: ^4.17.19 + react: '>=16.6.0' victory-bar: 37.1.1 victory-core: 37.1.1 - react: '>=16.6.0' dependencies: lodash: 4.17.21 react: 18.2.0 @@ -558,13 +562,13 @@ importers: packages/victory-create-container: specifiers: lodash: ^4.17.19 + react: '>=16.6.0' victory-brush-container: 37.1.1 victory-core: 37.1.1 victory-cursor-container: 37.1.1 victory-selection-container: 37.1.1 victory-voronoi-container: 37.1.1 victory-zoom-container: 37.1.1 - react: '>=16.6.0' dependencies: lodash: 4.17.21 react: 18.2.0 @@ -578,8 +582,8 @@ importers: packages/victory-cursor-container: specifiers: lodash: ^4.17.19 - victory-core: 37.1.1 react: '>=16.6.0' + victory-core: 37.1.1 dependencies: lodash: 4.17.21 react: 18.2.0 @@ -588,8 +592,8 @@ importers: packages/victory-errorbar: specifiers: lodash: ^4.17.19 - victory-core: 37.1.1 react: '>=16.6.0' + victory-core: 37.1.1 victory-vendor: '*' dependencies: lodash: 4.17.21 @@ -634,8 +638,8 @@ importers: packages/victory-legend: specifiers: lodash: ^4.17.19 - victory-core: 37.1.1 react: '>=16.6.0' + victory-core: 37.1.1 dependencies: lodash: 4.17.21 react: 18.2.0 @@ -734,9 +738,9 @@ importers: packages/victory-pie: specifiers: lodash: ^4.17.19 + react: '>=16.6.0' victory-core: 37.1.1 victory-vendor: 37.1.1 - react: '>=16.6.0' dependencies: lodash: 4.17.21 react: 18.2.0 @@ -746,8 +750,8 @@ importers: packages/victory-polar-axis: specifiers: lodash: ^4.17.19 - victory-core: 37.1.1 react: '>=16.6.0' + victory-core: 37.1.1 dependencies: lodash: 4.17.21 react: 18.2.0 @@ -756,8 +760,8 @@ importers: packages/victory-scatter: specifiers: lodash: ^4.17.19 - victory-core: 37.1.1 react: '>=16.6.0' + victory-core: 37.1.1 dependencies: lodash: 4.17.21 react: 18.2.0 @@ -816,8 +820,8 @@ importers: packages/victory-tooltip: specifiers: lodash: ^4.17.19 - victory-core: 37.1.1 react: '>=16.6.0' + victory-core: 37.1.1 dependencies: lodash: 4.17.21 react: 18.2.0 @@ -876,8 +880,8 @@ importers: specifiers: d3-voronoi: ^1.1.4 lodash: ^4.17.19 - victory-core: 37.1.1 react: '>=16.6.0' + victory-core: 37.1.1 dependencies: d3-voronoi: 1.1.4 lodash: 4.17.21 @@ -903,8 +907,8 @@ importers: packages/victory-zoom-container: specifiers: lodash: ^4.17.19 - victory-core: 37.1.1 react: '>=16.6.0' + victory-core: 37.1.1 dependencies: lodash: 4.17.21 react: 18.2.0 @@ -16720,6 +16724,14 @@ packages: source-map: 0.7.4 dev: true + /react-icons/5.3.0_react@18.2.0: + resolution: {integrity: sha512-DnUk8aFbTyQPSkCfF8dbX6kQjXA9DktMeJqfjrg6cK9vwQVMxmcA3BfP4QoiztVmEHtwlTgLFsPuH2NskKT6eg==} + peerDependencies: + react: '*' + dependencies: + react: 18.2.0 + dev: true + /react-inlinesvg/4.1.3_react@18.2.0: resolution: {integrity: sha512-p1+wkr1UQZyLw/3bdpnHO3v3tMNVWyxWnAEY6ML/Ql9ldDYTBTy6HqAyNl7u3au925XPffLMiXKnQrqZeJAldw==} peerDependencies: