├── .github └── workflows │ ├── main.yml │ └── publish.yml ├── .gitignore ├── example ├── .npmignore ├── index.css ├── index.html ├── index.tsx ├── package.json ├── tsconfig.json └── yarn.lock ├── license ├── package.json ├── readme.md ├── src ├── basis-closed.tsx ├── basis-open.tsx ├── basis.tsx ├── bundle.tsx ├── cardinal-closed.tsx ├── cardinal-open.tsx ├── cardinal.tsx ├── catmull-rom-closed.tsx ├── catmull-rom-open.tsx ├── catmull-rom.tsx ├── curve.tsx ├── index.tsx ├── line-closed.tsx ├── line.tsx ├── monotone-x.tsx ├── monotone-y.tsx ├── natural.tsx ├── step-after.tsx ├── step-before.tsx └── step.tsx ├── tsconfig.json └── yarn.lock /.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | on: [push] 3 | jobs: 4 | build: 5 | runs-on: ubuntu-latest 6 | 7 | steps: 8 | - name: Begin CI... 9 | uses: actions/checkout@v2 10 | 11 | - name: Use Node 12 12 | uses: actions/setup-node@v1 13 | with: 14 | node-version: 12.x 15 | 16 | - name: Use cached node_modules 17 | uses: actions/cache@v1 18 | with: 19 | path: node_modules 20 | key: nodeModules-${{ hashFiles('**/yarn.lock') }} 21 | restore-keys: | 22 | nodeModules- 23 | 24 | - name: Install dependencies 25 | run: yarn install --frozen-lockfile 26 | env: 27 | CI: true 28 | 29 | - name: Lint 30 | run: yarn lint 31 | env: 32 | CI: true 33 | 34 | - name: Test 35 | run: yarn test --ci --coverage --maxWorkers=2 36 | env: 37 | CI: true 38 | 39 | - name: Build 40 | run: yarn build 41 | env: 42 | CI: true 43 | -------------------------------------------------------------------------------- /.github/workflows/publish.yml: -------------------------------------------------------------------------------- 1 | name: npm-publish 2 | on: 3 | push: 4 | branches: 5 | - master 6 | jobs: 7 | npm-publish: 8 | name: npm-publish 9 | runs-on: ubuntu-latest 10 | steps: 11 | - name: Checkout repository 12 | uses: actions/checkout@master 13 | - name: Set up Node.js 14 | uses: actions/setup-node@master 15 | with: 16 | node-version: 10.13.0 17 | - run: yarn install --frozen-lockfile 18 | - name: Publish if version has been updated 19 | uses: pascalgn/npm-publish-action@4f4bf159e299f65d21cd1cbd96fc5d53228036df 20 | with: 21 | commit_pattern: "^Release (\\S+)" 22 | env: 23 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 24 | NPM_AUTH_TOKEN: ${{ secrets.NPM_AUTH_TOKEN }} 25 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.log 2 | .DS_Store 3 | node_modules 4 | .cache 5 | dist 6 | -------------------------------------------------------------------------------- /example/.npmignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .cache 3 | dist -------------------------------------------------------------------------------- /example/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, 3 | sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; 4 | text-align: center; 5 | background-color: #222; 6 | color: #f6f6f6; 7 | } 8 | 9 | .grid { 10 | display: grid; 11 | justify-content: center; 12 | grid-template-columns: repeat(auto-fit, 300px); 13 | } 14 | 15 | .grid > * { 16 | margin: 10px; 17 | padding: 0 10px 10px; 18 | background: #eee; 19 | color: #222; 20 | border-radius: 6px; 21 | } 22 | -------------------------------------------------------------------------------- /example/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Playground 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /example/index.tsx: -------------------------------------------------------------------------------- 1 | import 'react-app-polyfill/ie11'; 2 | import * as React from 'react'; 3 | import * as ReactDOM from 'react-dom'; 4 | import './index.css'; 5 | import { 6 | Line, 7 | BasisCurve, 8 | BasisClosedCurve, 9 | BasisOpenCurve, 10 | BundleCurve, 11 | CardinalCurve, 12 | CardinalClosedCurve, 13 | CardinalOpenCurve, 14 | CatmullRomCurve, 15 | CatmullRomClosedCurve, 16 | CatmullRomOpenCurve, 17 | ClosedLine, 18 | MonotoneXCurve, 19 | MonotoneYCurve, 20 | NaturalCurve, 21 | StepCurve, 22 | StepAfterCurve, 23 | StepBeforeCurve, 24 | } from '../.'; 25 | 26 | const data: [number, number][] = [ 27 | [25, 50], 28 | [50, 75], 29 | [75, 80], 30 | [100, 40], 31 | [125, 30], 32 | [150, 60], 33 | [175, 50], 34 | ]; 35 | 36 | const App = () => { 37 | const [catmullRomAlpha, setCatmullRomAlpha] = React.useState(0.5); 38 | const [bundleBeta, setBundleBeta] = React.useState(0.85); 39 | const [cardinalTension, setCardinalTension] = React.useState(0); 40 | return ( 41 | <> 42 |

react-svg-curve

43 |
44 |
45 |

46 | 47 |

48 | 49 | 50 | 51 |
52 | 53 |
54 |

55 | 56 |

57 | 58 | 59 | 60 |
61 | 62 |
63 |

64 | 65 |

66 | 67 | 68 | 69 |
70 | 71 |
72 |

73 | 74 |

75 | 76 | 77 | 78 |
79 | 80 |
81 |

82 | 83 |

84 | 85 | 86 | 87 | 93 |
94 | 95 |
96 |

97 | 98 |

99 | 100 | 101 | 102 | 108 |
109 | 110 |
111 |

112 | 113 |

114 | 115 | 116 | 117 | 123 |
124 | 125 |
126 |

127 | 128 |

129 | 130 | 131 | 132 | 138 |
139 | 140 |
141 |

142 | 143 |

144 | 145 | 146 | 147 | 153 |
154 | 155 |
156 |

157 | 158 |

159 | 160 | 161 | 162 | 168 |
169 | 170 |
171 |

172 | 173 |

174 | 175 | 176 | 177 | 183 |
184 | 185 |
186 |

187 | 188 |

189 | 190 | 191 | 192 |
193 | 194 |
195 |

196 | 197 |

198 | 199 | 200 | 201 |
202 | 203 |
204 |

205 | 206 |

207 | 208 | 209 | 210 |
211 | 212 |
213 |

214 | 215 |

216 | 217 | 218 | 219 |
220 | 221 |
222 |

223 | 224 |

225 | 226 | 227 | 228 |
229 | 230 |
231 |

232 | 233 |

234 | 235 | 236 | 237 |
238 | 239 |
240 |

241 | 242 |

243 | 244 | 245 | 246 |
247 |
248 | 249 |

Custom Point Element

250 |
251 |
252 |

253 | 254 |

255 | 256 | 257 | 258 |
259 | 260 |
261 |

262 | 263 |

264 | 265 | ( 268 | 278 | )} 279 | /> 280 | 281 |
282 | 283 |
284 |

285 | 286 |

287 | 288 | ( 291 | 300 | {i} 301 | 302 | )} 303 | /> 304 | 305 |
306 |
307 | 308 |

Custom Path Style

309 |
310 |
311 |

312 | 313 |

314 | 315 | 316 | 317 |
318 | 319 |
320 |

321 | 322 |

323 | 324 | 330 | 331 |
332 | 333 |
334 |

335 | 336 |

337 | 338 | 344 | 345 |
346 |
347 | 348 | ); 349 | }; 350 | 351 | function Range({ min = 0, max = 1, step = 0.01, value, setValue, label }) { 352 | return ( 353 |
360 | 361 |
{value}
362 | setValue(+e.target.value)} 369 | /> 370 |
371 | ); 372 | } 373 | 374 | ReactDOM.render(, document.getElementById('root')); 375 | -------------------------------------------------------------------------------- /example/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "example", 3 | "version": "1.0.0", 4 | "main": "index.js", 5 | "license": "MIT", 6 | "scripts": { 7 | "start": "parcel index.html --open", 8 | "build": "parcel build index.html" 9 | }, 10 | "dependencies": { 11 | "react-app-polyfill": "^1.0.0" 12 | }, 13 | "alias": { 14 | "react": "../node_modules/react", 15 | "react-dom": "../node_modules/react-dom/profiling", 16 | "scheduler/tracing": "../node_modules/scheduler/tracing-profiling" 17 | }, 18 | "devDependencies": { 19 | "@types/react": "^16.9.11", 20 | "@types/react-dom": "^16.8.4", 21 | "parcel": "^1.12.3", 22 | "typescript": "^3.4.5" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /example/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "allowSyntheticDefaultImports": false, 4 | "target": "es5", 5 | "module": "commonjs", 6 | "jsx": "react", 7 | "moduleResolution": "node", 8 | "noImplicitAny": false, 9 | "noUnusedLocals": false, 10 | "noUnusedParameters": false, 11 | "removeComments": true, 12 | "strictNullChecks": true, 13 | "preserveConstEnums": true, 14 | "sourceMap": true, 15 | "lib": ["es2015", "es2016", "dom"], 16 | "baseUrl": ".", 17 | "types": ["node"] 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /license: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Rodrigo Pombo 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0.2.1", 3 | "license": "MIT", 4 | "main": "dist/index.js", 5 | "typings": "dist/index.d.ts", 6 | "files": [ 7 | "dist", 8 | "src" 9 | ], 10 | "engines": { 11 | "node": ">=10" 12 | }, 13 | "scripts": { 14 | "start-lib": "tsdx watch", 15 | "start-example": "sleep 10 && yarn --cwd example start", 16 | "start": "run-p start-lib start-example", 17 | "build": "tsdx build", 18 | "test": "tsdx test --passWithNoTests", 19 | "lint": "tsdx lint", 20 | "prepare": "tsdx build" 21 | }, 22 | "peerDependencies": { 23 | "react": ">=16" 24 | }, 25 | "husky": { 26 | "hooks": { 27 | "pre-commit": "tsdx lint" 28 | } 29 | }, 30 | "prettier": { 31 | "printWidth": 80, 32 | "semi": true, 33 | "singleQuote": true, 34 | "trailingComma": "es5" 35 | }, 36 | "name": "react-svg-curve", 37 | "author": "Rodrigo Pombo", 38 | "repository": "pomber/react-svg-curve", 39 | "module": "dist/react-svg-curve.esm.js", 40 | "sideEffects": false, 41 | "devDependencies": { 42 | "@types/react": "^16.9.34", 43 | "@types/react-dom": "^16.9.6", 44 | "husky": "^4.2.5", 45 | "npm-run-all": "^4.1.5", 46 | "react": "^16.13.1", 47 | "react-dom": "^16.13.1", 48 | "tsdx": "^0.13.2", 49 | "tslib": "^1.11.1", 50 | "typescript": "^3.8.3" 51 | }, 52 | "dependencies": { 53 | "@types/d3-shape": "^1.3.2", 54 | "d3-shape": "^1.3.7" 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # react-svg-curve 2 | 3 | React components to draw different types of curves with `svg`. It wraps all the curve paths from [d3-shape](https://github.com/d3/d3-shape/blob/master/README.md#curves). 4 | 5 | Install 6 | 7 | ```bash 8 | npm install react-svg-curve 9 | ``` 10 | 11 | Use 12 | 13 | ```jsx 14 | import { BasisCurve } from 'react-svg-curve'; 15 | 16 | function App() { 17 | return ( 18 | 19 | 26 | 27 | ); 28 | } 29 | ``` 30 | 31 | `BasisCurve` is one of many types of curves available. Go to [the **demo** on codesandbox](https://codesandbox.io/embed/react-svg-curve-71nnp?fontsize=14&hidenavigation=1&theme=dark&view=preview) to see all the curves and options. 32 | -------------------------------------------------------------------------------- /src/basis-closed.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { line, curveBasisClosed } from 'd3-shape'; 3 | import { Curve, CurveProps } from './curve'; 4 | 5 | type Props = { 6 | data: [number, number][]; 7 | } & Omit; 8 | 9 | export default function({ data, ...props }: Props) { 10 | const d = line().curve(curveBasisClosed)(data) || ''; 11 | return ; 12 | } 13 | -------------------------------------------------------------------------------- /src/basis-open.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { line, curveBasisOpen } from 'd3-shape'; 3 | import { Curve, CurveProps } from './curve'; 4 | 5 | type Props = { 6 | data: [number, number][]; 7 | } & Omit; 8 | 9 | export default function({ data, ...props }: Props) { 10 | const d = line().curve(curveBasisOpen)(data) || ''; 11 | return ; 12 | } 13 | -------------------------------------------------------------------------------- /src/basis.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { line, curveBasis } from 'd3-shape'; 3 | import { Curve, CurveProps } from './curve'; 4 | 5 | type Props = { 6 | data: [number, number][]; 7 | } & Omit; 8 | 9 | export default function({ data, ...props }: Props) { 10 | const d = line().curve(curveBasis)(data) || ''; 11 | return ; 12 | } 13 | -------------------------------------------------------------------------------- /src/bundle.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { line, curveBundle } from 'd3-shape'; 3 | import { Curve, CurveProps } from './curve'; 4 | 5 | type Props = { 6 | data: [number, number][]; 7 | beta?: number; 8 | } & Omit; 9 | 10 | export default function({ data, beta = 0.85, ...props }: Props) { 11 | const d = line().curve(curveBundle.beta(beta))(data) || ''; 12 | return ; 13 | } 14 | -------------------------------------------------------------------------------- /src/cardinal-closed.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { line, curveCardinalClosed } from 'd3-shape'; 3 | import { Curve, CurveProps } from './curve'; 4 | 5 | type Props = { 6 | data: [number, number][]; 7 | tension?: number; 8 | } & Omit; 9 | 10 | export default function({ data, tension = 0, ...props }: Props) { 11 | const d = line().curve(curveCardinalClosed.tension(tension))(data) || ''; 12 | return ; 13 | } 14 | -------------------------------------------------------------------------------- /src/cardinal-open.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { line, curveCardinalOpen } from 'd3-shape'; 3 | import { Curve, CurveProps } from './curve'; 4 | 5 | type Props = { 6 | data: [number, number][]; 7 | tension?: number; 8 | } & Omit; 9 | 10 | export default function({ data, tension = 0, ...props }: Props) { 11 | const d = line().curve(curveCardinalOpen.tension(tension))(data) || ''; 12 | return ; 13 | } 14 | -------------------------------------------------------------------------------- /src/cardinal.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { line, curveCardinal } from 'd3-shape'; 3 | import { Curve, CurveProps } from './curve'; 4 | 5 | type Props = { 6 | data: [number, number][]; 7 | tension?: number; 8 | } & Omit; 9 | 10 | export default function({ data, tension = 0, ...props }: Props) { 11 | const d = line().curve(curveCardinal.tension(tension))(data) || ''; 12 | return ; 13 | } 14 | -------------------------------------------------------------------------------- /src/catmull-rom-closed.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { line, curveCatmullRomClosed } from 'd3-shape'; 3 | import { Curve, CurveProps } from './curve'; 4 | 5 | type Props = { 6 | data: [number, number][]; 7 | alpha?: number; 8 | } & Omit; 9 | 10 | export default function({ data, alpha = 0.5, ...props }: Props) { 11 | const d = line().curve(curveCatmullRomClosed.alpha(alpha))(data) || ''; 12 | return ; 13 | } 14 | -------------------------------------------------------------------------------- /src/catmull-rom-open.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { line, curveCatmullRomOpen } from 'd3-shape'; 3 | import { Curve, CurveProps } from './curve'; 4 | 5 | type Props = { 6 | data: [number, number][]; 7 | alpha?: number; 8 | } & Omit; 9 | 10 | export default function({ data, alpha = 0.5, ...props }: Props) { 11 | const d = line().curve(curveCatmullRomOpen.alpha(alpha))(data) || ''; 12 | return ; 13 | } 14 | -------------------------------------------------------------------------------- /src/catmull-rom.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { line, curveCatmullRom } from 'd3-shape'; 3 | import { Curve, CurveProps } from './curve'; 4 | 5 | type Props = { 6 | data: [number, number][]; 7 | alpha?: number; 8 | } & Omit; 9 | 10 | export default function({ data, alpha = 0.5, ...props }: Props) { 11 | const d = line().curve(curveCatmullRom.alpha(alpha))(data) || ''; 12 | return ; 13 | } 14 | -------------------------------------------------------------------------------- /src/curve.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | 3 | export type CurveProps = { 4 | data: [number, number][]; 5 | path: string; 6 | showPoints?: boolean; 7 | pointElement?: PointElement; 8 | } & React.SVGProps; 9 | 10 | export function Curve({ 11 | path, 12 | data, 13 | pointElement = defaultPointElement, 14 | showPoints = true, 15 | ...props 16 | }: CurveProps) { 17 | return ( 18 | <> 19 | 20 | {showPoints && data.map(pointElement)} 21 | 22 | ); 23 | } 24 | 25 | type PointElement = ( 26 | center: [number, number], 27 | i: number, 28 | points: [number, number][] 29 | ) => React.ReactNode; 30 | 31 | function defaultPointElement( 32 | center: [number, number], 33 | i: number 34 | ): React.ReactNode { 35 | return ( 36 | 45 | ); 46 | } 47 | -------------------------------------------------------------------------------- /src/index.tsx: -------------------------------------------------------------------------------- 1 | export { default as Line } from './line'; 2 | export { default as BasisCurve } from './basis'; 3 | export { default as BasisClosedCurve } from './basis-closed'; 4 | export { default as BasisOpenCurve } from './basis-open'; 5 | export { default as BundleCurve } from './bundle'; 6 | export { default as CardinalCurve } from './cardinal'; 7 | export { default as CardinalClosedCurve } from './cardinal-closed'; 8 | export { default as CardinalOpenCurve } from './cardinal-open'; 9 | export { default as CatmullRomCurve } from './catmull-rom'; 10 | export { default as CatmullRomClosedCurve } from './catmull-rom-closed'; 11 | export { default as CatmullRomOpenCurve } from './catmull-rom-open'; 12 | export { default as ClosedLine } from './line-closed'; 13 | export { default as MonotoneXCurve } from './monotone-x'; 14 | export { default as MonotoneYCurve } from './monotone-y'; 15 | export { default as NaturalCurve } from './natural'; 16 | export { default as StepCurve } from './step'; 17 | export { default as StepAfterCurve } from './step-after'; 18 | export { default as StepBeforeCurve } from './step-before'; 19 | -------------------------------------------------------------------------------- /src/line-closed.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { line, curveLinearClosed } from 'd3-shape'; 3 | import { Curve, CurveProps } from './curve'; 4 | 5 | type Props = { 6 | data: [number, number][]; 7 | } & Omit; 8 | 9 | export default function({ data, ...props }: Props) { 10 | const d = line().curve(curveLinearClosed)(data) || ''; 11 | return ; 12 | } 13 | -------------------------------------------------------------------------------- /src/line.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { line } from 'd3-shape'; 3 | import { Curve, CurveProps } from './curve'; 4 | 5 | type Props = { 6 | data: [number, number][]; 7 | } & Omit; 8 | 9 | export default function({ data, ...props }: Props) { 10 | const d = line()(data) || ''; 11 | return ; 12 | } 13 | -------------------------------------------------------------------------------- /src/monotone-x.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { line, curveMonotoneX } from 'd3-shape'; 3 | import { Curve, CurveProps } from './curve'; 4 | 5 | type Props = { 6 | data: [number, number][]; 7 | } & Omit; 8 | 9 | export default function({ data, ...props }: Props) { 10 | const d = line().curve(curveMonotoneX)(data) || ''; 11 | return ; 12 | } 13 | -------------------------------------------------------------------------------- /src/monotone-y.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { line, curveMonotoneY } from 'd3-shape'; 3 | import { Curve, CurveProps } from './curve'; 4 | 5 | type Props = { 6 | data: [number, number][]; 7 | } & Omit; 8 | 9 | export default function({ data, ...props }: Props) { 10 | const d = line().curve(curveMonotoneY)(data) || ''; 11 | return ; 12 | } 13 | -------------------------------------------------------------------------------- /src/natural.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { line, curveNatural } from 'd3-shape'; 3 | import { Curve, CurveProps } from './curve'; 4 | 5 | type Props = { 6 | data: [number, number][]; 7 | } & Omit; 8 | 9 | export default function({ data, ...props }: Props) { 10 | const d = line().curve(curveNatural)(data) || ''; 11 | return ; 12 | } 13 | -------------------------------------------------------------------------------- /src/step-after.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { line, curveStepAfter } from 'd3-shape'; 3 | import { Curve, CurveProps } from './curve'; 4 | 5 | type Props = { 6 | data: [number, number][]; 7 | } & Omit; 8 | 9 | export default function({ data, ...props }: Props) { 10 | const d = line().curve(curveStepAfter)(data) || ''; 11 | return ; 12 | } 13 | -------------------------------------------------------------------------------- /src/step-before.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { line, curveStepBefore } from 'd3-shape'; 3 | import { Curve, CurveProps } from './curve'; 4 | 5 | type Props = { 6 | data: [number, number][]; 7 | } & Omit; 8 | 9 | export default function({ data, ...props }: Props) { 10 | const d = line().curve(curveStepBefore)(data) || ''; 11 | return ; 12 | } 13 | -------------------------------------------------------------------------------- /src/step.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { line, curveStep } from 'd3-shape'; 3 | import { Curve, CurveProps } from './curve'; 4 | 5 | type Props = { 6 | data: [number, number][]; 7 | } & Omit; 8 | 9 | export default function({ data, ...props }: Props) { 10 | const d = line().curve(curveStep)(data) || ''; 11 | return ; 12 | } 13 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": ["src", "types"], 3 | "compilerOptions": { 4 | "module": "esnext", 5 | "lib": ["dom", "esnext"], 6 | "importHelpers": true, 7 | "declaration": true, 8 | "sourceMap": true, 9 | "rootDir": "./src", 10 | "strict": true, 11 | "noUnusedLocals": true, 12 | "noUnusedParameters": true, 13 | "noImplicitReturns": true, 14 | "noFallthroughCasesInSwitch": true, 15 | "moduleResolution": "node", 16 | "baseUrl": "./", 17 | "paths": { 18 | "*": ["src/*", "node_modules/*"] 19 | }, 20 | "jsx": "react", 21 | "esModuleInterop": true 22 | } 23 | } 24 | --------------------------------------------------------------------------------