├── .eslintignore ├── .eslintrc.js ├── .github ├── dependabot.yml └── workflows │ └── node.js.yml ├── .gitignore ├── .npmrc ├── .prettierignore ├── .travis.yml ├── CHANGELOG.md ├── CODEOWNERS ├── LICENSE ├── NOTICE ├── README.md ├── babel.config.js ├── docs ├── assets │ ├── MyFirstLineChart.png │ └── favicon.png ├── build │ ├── assets │ │ ├── MyFirstLineChart.png │ │ └── favicon.png │ ├── bundle.6ab8ef2cbcf9e159df8e.js │ ├── bundle.6ab8ef2cbcf9e159df8e.js.LICENSE.txt │ ├── bundle.6ab8ef2cbcf9e159df8e.js.map │ └── index.html ├── index.html ├── src │ ├── App.js │ ├── ComponentDocs.js │ ├── ExampleSection.js │ ├── Lesson.js │ ├── data │ │ └── util.js │ ├── docs │ │ ├── AreaBarChart │ │ │ ├── AreaBarChartDocs.js │ │ │ ├── examples │ │ │ │ ├── AreaBarChart.js.example │ │ │ │ └── RatesByAge.js.example │ │ │ └── propDocs.json │ │ ├── AreaChart │ │ │ ├── AreaChartDocs.js │ │ │ ├── examples │ │ │ │ ├── Area2Datasets.js.example │ │ │ │ ├── AreaChart.js.example │ │ │ │ └── AreaDifference.js.example │ │ │ └── propDocs.json │ │ ├── AreaHeatmap │ │ │ ├── AreaHeatmapDocs.js │ │ │ ├── examples │ │ │ │ └── AreaHeatmap.js.example │ │ │ └── propDocs.json │ │ ├── AriaLabelContainer │ │ │ ├── AriaLabelContainerDocs.js │ │ │ ├── examples │ │ │ │ ├── OneDataset.js.example │ │ │ │ ├── TwoDatasets.js.example │ │ │ │ └── WithActions.js.example │ │ │ └── propDocs.json │ │ ├── Bar │ │ │ ├── BarDocs.js │ │ │ ├── examples │ │ │ │ └── Bar.js.example │ │ │ └── propDocs.json │ │ ├── BarChart │ │ │ ├── BarChartDocs.js │ │ │ ├── examples │ │ │ │ ├── BarChart.js.example │ │ │ │ └── BarChartLinearGradient.js.example │ │ │ └── propDocs.json │ │ ├── ColorHeatmap │ │ │ ├── ColorHeatmapDocs.js │ │ │ ├── examples │ │ │ │ ├── CategoricalColorHeatmap.js.example │ │ │ │ └── ColorHeatmap.js.example │ │ │ └── propDocs.json │ │ ├── FunnelChart │ │ │ ├── FunnelChartDocs.js │ │ │ ├── examples │ │ │ │ └── FunnelChart.js.example │ │ │ └── propDocs.json │ │ ├── Histogram │ │ │ ├── HistogramDocs.js │ │ │ ├── examples │ │ │ │ └── Histogram.js.example │ │ │ └── propDocs.json │ │ ├── KernelDensityEstimation │ │ │ ├── KernelDensityEstimationDocs.js │ │ │ ├── examples │ │ │ │ └── KernelDensityEstimation.js.example │ │ │ └── propDocs.json │ │ ├── LineChart │ │ │ ├── LineChartDocs.js │ │ │ ├── examples │ │ │ │ ├── InteractiveLineChart.js.example │ │ │ │ └── LineChart.js.example │ │ │ └── propDocs.json │ │ ├── MarkerLineChart │ │ │ ├── MarkerLineChartDocs.js │ │ │ ├── examples │ │ │ │ ├── MarkerLineChart.js.example │ │ │ │ └── MarkerLineWithBarChart.js.example │ │ │ └── propDocs.json │ │ ├── MeasuredValueLabel │ │ │ ├── MeasuredValueLabelDocs.js │ │ │ ├── examples │ │ │ │ └── MeasuredValueLabel.js.example │ │ │ └── propDocs.json │ │ ├── PieChart │ │ │ ├── PieChartDocs.js │ │ │ ├── examples │ │ │ │ └── PieChart.js.example │ │ │ └── propDocs.json │ │ ├── RangeBarChart │ │ │ ├── RangeBarChartDocs.js │ │ │ ├── examples │ │ │ │ └── RangeBarChart.js.example │ │ │ └── propDocs.json │ │ ├── RangeRect │ │ │ ├── RangeRectDocs.js │ │ │ ├── examples │ │ │ │ └── RangeRect.js.example │ │ │ └── propDocs.json │ │ ├── SankeyDiagram │ │ │ ├── SankeyDiagramDocs.js │ │ │ ├── examples │ │ │ │ ├── SankeyDiagram.js.example │ │ │ │ └── SankeyInteractive.js.example │ │ │ └── propDocs.json │ │ ├── ScatterPlot │ │ │ ├── ScatterPlotDocs.js │ │ │ ├── examples │ │ │ │ └── ScatterPlot.js.example │ │ │ └── propDocs.json │ │ ├── TreeMap │ │ │ ├── TreeMapDocs.js │ │ │ ├── examples │ │ │ │ ├── AnimatedTreeMap.js.example │ │ │ │ └── TreeMap.js.example │ │ │ └── propDocs.json │ │ ├── TreeMapNode │ │ │ ├── TreeMapNodeDocs.js │ │ │ ├── examples │ │ │ │ └── TreeMapNode.js.example │ │ │ └── propDocs.json │ │ ├── TreeMapNodeLabel │ │ │ ├── TreeMapNodeLabelDocs.js │ │ │ ├── examples │ │ │ │ └── TreeMapNodeLabel.js.example │ │ │ └── propDocs.json │ │ ├── XAxis │ │ │ ├── XAxisDocs.js │ │ │ ├── examples │ │ │ │ ├── XAxis.js.example │ │ │ │ └── XAxisCustomTicks.js.example │ │ │ └── propDocs.json │ │ ├── XAxisLabels │ │ │ ├── XAxisLabelsDocs.js │ │ │ ├── examples │ │ │ │ └── XAxisLabels.js.example │ │ │ └── propDocs.json │ │ ├── XAxisTitle │ │ │ ├── XAxisTitleDocs.js │ │ │ ├── examples │ │ │ │ ├── XAxisTitle.js.example │ │ │ │ └── XAxisTitleAll.js.example │ │ │ └── propDocs.json │ │ ├── XGrid │ │ │ ├── XGridDocs.js │ │ │ ├── examples │ │ │ │ └── XGrid.js.example │ │ │ └── propDocs.json │ │ ├── XLine │ │ │ ├── XLineDocs.js │ │ │ ├── examples │ │ │ │ └── XLine.js.example │ │ │ └── propDocs.json │ │ ├── XTicks │ │ │ ├── XTicksDocs.js │ │ │ ├── examples │ │ │ │ └── XTicks.js.example │ │ │ └── propDocs.json │ │ ├── XYPlot │ │ │ ├── XYPlotDocs.js │ │ │ ├── examples │ │ │ │ ├── CustomSpacing.js.example │ │ │ │ └── XYPlot.js.example │ │ │ └── propDocs.json │ │ ├── YAxis │ │ │ ├── YAxisDocs.js │ │ │ ├── examples │ │ │ │ ├── YAxis.js.example │ │ │ │ └── YAxisCustomTicks.js.example │ │ │ └── propDocs.json │ │ ├── YAxisLabels │ │ │ ├── YAxisLabelsDocs.js │ │ │ ├── examples │ │ │ │ └── YAxisLabels.js.example │ │ │ └── propDocs.json │ │ ├── YAxisTitle │ │ │ ├── YAxisTitleDocs.js │ │ │ ├── examples │ │ │ │ ├── YAxisTitle.js.example │ │ │ │ └── YAxisTitleAll.js.example │ │ │ └── propDocs.json │ │ ├── YGrid │ │ │ ├── YGridDocs.js │ │ │ ├── examples │ │ │ │ └── YGrid.js.example │ │ │ └── propDocs.json │ │ ├── YLine │ │ │ ├── YLineDocs.js │ │ │ ├── examples │ │ │ │ └── YLine.js.example │ │ │ └── propDocs.json │ │ ├── YTicks │ │ │ ├── YTicksDocs.js │ │ │ ├── examples │ │ │ │ └── YTicks.js.example │ │ │ └── propDocs.json │ │ ├── ZoomContainer │ │ │ ├── ZoomContainerDocs.js │ │ │ ├── examples │ │ │ │ ├── ZoomContainer.js.example │ │ │ │ └── ZoomContainerControlled.js.example │ │ │ └── propDocs.json │ │ └── index.js │ ├── index_html.ejs │ ├── lessons │ │ ├── GettersAndAccessors │ │ │ ├── GettersAndAccessorsLesson.js │ │ │ └── examples │ │ │ │ ├── GettersAndAccessors.js.example │ │ │ │ └── GraphingCalculator.js.example │ │ ├── Interaction │ │ │ ├── InteractionLesson.js │ │ │ └── examples │ │ │ │ └── Interaction.js.example │ │ ├── QuickStart │ │ │ ├── QuickStartLesson.js │ │ │ └── examples │ │ │ │ └── QuickStart.js.example │ │ ├── XYPlots │ │ │ ├── XYPlotsLesson.js │ │ │ └── examples │ │ │ │ ├── LineChart.js.example │ │ │ │ ├── LineChartWithAxis.js.example │ │ │ │ └── MultiChart.js.example │ │ └── index.js │ ├── main.js │ └── templates │ │ ├── ComponentDocsPage.js.template │ │ ├── ComponentExample.js.template │ │ └── Lesson.js.template └── styles │ └── main.less ├── index.html ├── jest.config.js ├── package-lock.json ├── package.json ├── prettier.config.js ├── scripts ├── clean.js ├── makeDocs.js ├── makeLesson.js └── utils.js ├── src ├── AreaBarChart.js ├── AreaChart.js ├── AreaHeatmap.js ├── AriaLabelContainer.js ├── Bar.js ├── BarChart.js ├── ColorHeatmap.js ├── FunnelChart.js ├── Histogram.js ├── KernelDensityEstimation.js ├── LineChart.js ├── MarkerLineChart.js ├── MeasuredValueLabel.js ├── PieChart.js ├── RangeBarChart.js ├── RangeRect.js ├── SankeyDiagram.js ├── ScatterPlot.js ├── TreeMap.js ├── TreeMapNode.js ├── TreeMapNodeLabel.js ├── XAxis.js ├── XAxisLabels.js ├── XAxisTitle.js ├── XGrid.js ├── XLine.js ├── XTicks.js ├── XYPlot.js ├── YAxis.js ├── YAxisLabels.js ├── YAxisTitle.js ├── YGrid.js ├── YLine.js ├── YTicks.js ├── ZoomContainer.js ├── index.js ├── util.js └── utils │ ├── Axis.js │ ├── CustomPropTypes.js │ ├── Data.js │ ├── Label.js │ ├── Margin.js │ ├── Scale.js │ ├── depthEqual.js │ ├── measureText.js │ ├── resolveXYScales.js │ ├── shallowEqual.js │ └── xyPropsEqual.js ├── styles └── charts.less ├── tests ├── browser │ ├── index.js │ ├── index_html.ejs │ ├── spec │ │ ├── XAxis.spec.js │ │ ├── XAxisLabels.spec.js │ │ ├── XAxisTitle.spec.js │ │ ├── YAxis.spec.js │ │ ├── YAxisLabels.spec.js │ │ └── YAxisTitle.spec.js │ └── webpack.config.test.js └── jsdom │ ├── setup.js │ ├── spec │ ├── AreaBarChart.spec.js │ ├── AreaChart.spec.js │ ├── AreaHeatmap.spec.js │ ├── AriaLabelContainer.spec.js │ ├── Bar.spec.js │ ├── BarChart.spec.js │ ├── ColorHeatmap.spec.js │ ├── FunnelChart.spec.js │ ├── Histogram.spec.js │ ├── LineChart.spec.js │ ├── MarkerLineChart.spec.js │ ├── PieChart.spec.js │ ├── RangeBarChart.spec.js │ ├── RangeRect.spec.js │ ├── SankeyDiagram.spec.js │ ├── ScatterPlot.spec.js │ ├── TreeMap.spec.js │ ├── XGrid.spec.js │ ├── XLine.spec.js │ ├── XTicks.spec.js │ ├── XYPlot.spec.js │ ├── YGrid.spec.js │ ├── YLine.spec.js │ ├── YTicks.spec.js │ ├── ZoomContainer.spec.js │ ├── resolveXYScales.spec.js │ ├── utils.Axis.spec.js │ ├── utils.Data.spec.js │ ├── utils.Label.spec.js │ ├── utils.Margin.spec.js │ ├── utils.Scale.spec.js │ └── utils.measureText.spec.js │ └── utils.js ├── webpack.config.base.js └── webpack.config.build.js /.eslintignore: -------------------------------------------------------------------------------- 1 | # Ignore charts that are still experimental 2 | /src/AreaHeatmap.js 3 | /src/KernelDensityEstimation.js 4 | 5 | # Ignore shallowEqual 6 | /src/utils/shallowEqual.js 7 | 8 | # Ignore lessons 9 | /docs/src/lessons 10 | 11 | # Ignore docs build 12 | /docs/build/* 13 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | settings: { 3 | react: { 4 | version: 'detect', 5 | }, 6 | }, 7 | parser: '@babel/eslint-parser', 8 | extends: [ 9 | '@spotify/eslint-config-react', 10 | '@spotify/eslint-config-base', 11 | 'prettier', 12 | 'plugin:chai-friendly/recommended', 13 | ], 14 | env: { jest: true }, 15 | plugins: ['jest', 'chai-friendly'], 16 | rules: { 17 | 'consistent-return': 'off', 18 | 'no-nested-ternary': 'off', 19 | 'no-console': ['error', { allow: ['warn', 'error'] }], 20 | 'jsx-a11y/click-events-have-key-events': 'off', 21 | 'jsx-a11y/no-noninteractive-element-interactions': 'off', 22 | 'no-restricted-imports': ['error', 'd3'], 23 | }, 24 | }; 25 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | # To get started with Dependabot version updates, you'll need to specify which 2 | # package ecosystems to update and where the package manifests are located. 3 | # Please see the documentation for all configuration options: 4 | # https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates 5 | 6 | version: 2 7 | updates: 8 | - package-ecosystem: "npm" 9 | directory: "/" # Location of package manifests 10 | open-pull-requests-limit: 10 11 | schedule: 12 | interval: "daily" 13 | -------------------------------------------------------------------------------- /.github/workflows/node.js.yml: -------------------------------------------------------------------------------- 1 | # This workflow will do a clean install of node dependencies, cache/restore them, build the source code and run tests across different versions of node 2 | # For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions 3 | 4 | name: Node.js CI 5 | 6 | on: 7 | push: 8 | branches: [master] 9 | pull_request: 10 | branches: [master] 11 | 12 | jobs: 13 | build: 14 | runs-on: ubuntu-latest 15 | 16 | strategy: 17 | matrix: 18 | node-version: [12.x, 14.x, 16.x] 19 | # See supported Node.js release schedule at https://nodejs.org/en/about/releases/ 20 | 21 | steps: 22 | - uses: actions/checkout@v2 23 | - name: Use Node.js ${{ matrix.node-version }} 24 | uses: actions/setup-node@v2 25 | with: 26 | node-version: ${{ matrix.node-version }} 27 | cache: 'npm' 28 | - run: npm ci 29 | - run: npm run build --if-present 30 | - run: npm test 31 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .idea/ 3 | *.sublime-* 4 | .DS_Store 5 | Thumbs.db 6 | npm-debug.log 7 | /coverage 8 | -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | registry= https://registry.npmjs.org/ -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | # node modules 2 | /node_modules/ 3 | 4 | # docs build 5 | /docs/build/* 6 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - '12' 4 | - '14' 5 | env: 6 | - CXX=g++-4.8 7 | addons: 8 | apt: 9 | sources: 10 | - ubuntu-toolchain-r-test 11 | packages: 12 | - g++-4.8 13 | cache: 14 | npm: false 15 | before_install: 16 | - npm i -g npm@latest 17 | install: 18 | - npm ci 19 | -------------------------------------------------------------------------------- /CODEOWNERS: -------------------------------------------------------------------------------- 1 | # This is a comment. 2 | # Each line is a file pattern followed by one or more owners. 3 | 4 | # These owners will be the default owners for everything in 5 | # the repo. Unless a later match takes precedence, 6 | # These users will be requested for review when someone opens a pull request. 7 | * @mawa-kake @ekh64 8 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2015-2016 Spotify AB. All rights reserved. 2 | 3 | The contents of this file are licensed under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. You may obtain a copy of the 5 | License at http://www.apache.org/licenses/LICENSE-2.0 6 | 7 | Unless required by applicable law or agreed to in writing, software distributed under the 8 | License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 9 | either express or implied. See the License for the specific language governing permissions 10 | and limitations under the License. -------------------------------------------------------------------------------- /NOTICE: -------------------------------------------------------------------------------- 1 | Reactochart 2 | Copyright 2018 Spotify AB 3 | -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [ 3 | [ 4 | '@babel/preset-env', 5 | { 6 | targets: { 7 | browsers: '> 3%', 8 | }, 9 | }, 10 | ], 11 | '@babel/preset-react', 12 | '@babel/preset-flow', 13 | ], 14 | plugins: [ 15 | '@babel/plugin-proposal-class-properties', 16 | '@babel/plugin-proposal-object-rest-spread', 17 | ], 18 | env: { 19 | production: { 20 | plugins: ['lodash'], 21 | }, 22 | test: { 23 | plugins: ['babel-plugin-rewire'], 24 | }, 25 | }, 26 | }; 27 | -------------------------------------------------------------------------------- /docs/assets/MyFirstLineChart.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spotify/reactochart/cd783035fabdd36953ff8e3e60702efedc86545a/docs/assets/MyFirstLineChart.png -------------------------------------------------------------------------------- /docs/assets/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spotify/reactochart/cd783035fabdd36953ff8e3e60702efedc86545a/docs/assets/favicon.png -------------------------------------------------------------------------------- /docs/build/assets/MyFirstLineChart.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spotify/reactochart/cd783035fabdd36953ff8e3e60702efedc86545a/docs/build/assets/MyFirstLineChart.png -------------------------------------------------------------------------------- /docs/build/assets/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spotify/reactochart/cd783035fabdd36953ff8e3e60702efedc86545a/docs/build/assets/favicon.png -------------------------------------------------------------------------------- /docs/build/bundle.6ab8ef2cbcf9e159df8e.js.LICENSE.txt: -------------------------------------------------------------------------------- 1 | /* 2 | object-assign 3 | (c) Sindre Sorhus 4 | @license MIT 5 | */ 6 | 7 | /*! 8 | * RegJSGen 9 | * Copyright 2014 Benjamin Tan 10 | * Available under MIT license 11 | */ 12 | 13 | /*! 14 | * The buffer module from node.js, for the browser. 15 | * 16 | * @author Feross Aboukhadijeh 17 | * @license MIT 18 | */ 19 | 20 | /*! 21 | * Determine if an object is a Buffer 22 | * 23 | * @author Feross Aboukhadijeh 24 | * @license MIT 25 | */ 26 | 27 | /*! Based on https://mths.be/fromcodepoint v0.2.0 by @mathias */ 28 | 29 | /*! https://mths.be/fromcodepoint v0.2.1 by @mathias */ 30 | 31 | /*! https://mths.be/jsesc v1.3.0 by @mathias */ 32 | 33 | /*! https://mths.be/regenerate v1.3.2 by @mathias | MIT license */ 34 | 35 | /** 36 | * @license 37 | * Lodash 38 | * Copyright OpenJS Foundation and other contributors 39 | * Released under MIT license 40 | * Based on Underscore.js 1.8.3 41 | * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors 42 | */ 43 | 44 | /** @license React v0.19.1 45 | * scheduler.production.min.js 46 | * 47 | * Copyright (c) Facebook, Inc. and its affiliates. 48 | * 49 | * This source code is licensed under the MIT license found in the 50 | * LICENSE file in the root directory of this source tree. 51 | */ 52 | 53 | /** @license React v16.13.1 54 | * react-is.production.min.js 55 | * 56 | * Copyright (c) Facebook, Inc. and its affiliates. 57 | * 58 | * This source code is licensed under the MIT license found in the 59 | * LICENSE file in the root directory of this source tree. 60 | */ 61 | 62 | /** @license React v16.14.0 63 | * react-dom-server.browser.production.min.js 64 | * 65 | * Copyright (c) Facebook, Inc. and its affiliates. 66 | * 67 | * This source code is licensed under the MIT license found in the 68 | * LICENSE file in the root directory of this source tree. 69 | */ 70 | 71 | /** @license React v16.14.0 72 | * react-dom.production.min.js 73 | * 74 | * Copyright (c) Facebook, Inc. and its affiliates. 75 | * 76 | * This source code is licensed under the MIT license found in the 77 | * LICENSE file in the root directory of this source tree. 78 | */ 79 | 80 | /** @license React v16.14.0 81 | * react.production.min.js 82 | * 83 | * Copyright (c) Facebook, Inc. and its affiliates. 84 | * 85 | * This source code is licensed under the MIT license found in the 86 | * LICENSE file in the root directory of this source tree. 87 | */ 88 | -------------------------------------------------------------------------------- /docs/build/index.html: -------------------------------------------------------------------------------- 1 | Reactochart Docs
Loading...
-------------------------------------------------------------------------------- /docs/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Redirect 4 | 5 | 6 | 7 | Redirecting to docs... 8 | 9 | 10 | -------------------------------------------------------------------------------- /docs/src/ExampleSection.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import PropTypes from 'prop-types'; 4 | import _ from 'lodash'; 5 | import * as d3 from 'd3'; // eslint-disable-line no-restricted-imports 6 | import Playground from 'component-playground'; 7 | 8 | // import *all* reactochart components/utils - usually you'd import one at a time 9 | import * as Reactochart from '../../src'; 10 | 11 | import { 12 | randomWalk, 13 | randomWalkSeries, 14 | randomWalkTimeSeries, 15 | } from './data/util'; 16 | window.Reactochart = Reactochart; 17 | 18 | export default class ExampleSection extends React.Component { 19 | static propTypes = { 20 | codeText: PropTypes.string, 21 | scope: PropTypes.object, 22 | isExpanded: PropTypes.bool, 23 | label: PropTypes.node, 24 | id: PropTypes.string, 25 | description: PropTypes.node, 26 | onClick: PropTypes.func, 27 | }; 28 | static defaultProps = { 29 | codeText: '', 30 | scope: {}, 31 | isExpanded: true, 32 | label: 'Example', 33 | id: '', 34 | }; 35 | 36 | onClick = e => { 37 | if (this.props.onClick) { 38 | this.props.onClick(e, this.props.id); 39 | } 40 | }; 41 | 42 | render() { 43 | const { codeText, isExpanded, label, id, description } = this.props; 44 | const scope = { 45 | React, 46 | ReactDOM, 47 | d3, 48 | _, 49 | randomWalk, 50 | randomWalkSeries, 51 | randomWalkTimeSeries, 52 | // include all Reactochart components in scope 53 | ...Reactochart, 54 | ...this.props.scope, 55 | }; 56 | 57 | return ( 58 |
63 |
64 |

65 | {label || id} {isExpanded ? '▼' : '►'} 66 |

67 | 68 | {isExpanded ? ( 69 |
70 | {description ? ( 71 |
{description}
72 | ) : null} 73 | 74 |
75 | ) : null} 76 |
77 |
78 | ); 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /docs/src/Lesson.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | 4 | export default class Lesson extends React.Component { 5 | static propTypes = { 6 | name: PropTypes.string, 7 | children: PropTypes.any, 8 | }; 9 | 10 | render() { 11 | const { name, children } = this.props; 12 | 13 | return ( 14 |
15 |

{name}

16 | 17 | {children} 18 |
19 | ); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /docs/src/data/util.js: -------------------------------------------------------------------------------- 1 | import _ from 'lodash'; 2 | 3 | export function randomWalk(length = 100, start = 0, variance = 10) { 4 | return _.reduce( 5 | _.range(length - 1), 6 | sequence => { 7 | return sequence.concat(_.last(sequence) + _.random(-variance, variance)); 8 | }, 9 | [start], 10 | ); 11 | } 12 | 13 | export function randomWalkSeries(length = 100, start = 0, variance = 10) { 14 | return randomWalk(length, start, variance).map((n, i) => [i, n]); 15 | } 16 | 17 | export function randomWalkTimeSeries( 18 | length = 100, 19 | start = 0, 20 | variance = 10, 21 | startDate = new Date(2015, 0, 1), 22 | ) { 23 | let date = startDate; 24 | return randomWalk(length, start, variance).map(n => { 25 | date = new Date(date.getTime() + 24 * 60 * 60 * 1000); 26 | return [date, n]; 27 | }); 28 | } 29 | 30 | export function removeRandomData(data, removeCount = 5) { 31 | const gapData = data.slice(); 32 | _.times(removeCount, () => { 33 | if (!gapData.length) return; 34 | const gapIndex = _.random(gapData.length - 1); 35 | gapData.splice(gapIndex, 1); 36 | }); 37 | return gapData; 38 | } 39 | -------------------------------------------------------------------------------- /docs/src/docs/AreaBarChart/AreaBarChartDocs.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ComponentDocs from '../../ComponentDocs'; 3 | import ExampleSection from '../../ExampleSection'; 4 | // autogenerated docs data containing descriptions of this component's props 5 | import propDocs from './propDocs.json'; 6 | 7 | const examples = [ 8 | { 9 | id: 'rates-by-age', 10 | label: 'Smoking Rates by Age', 11 | codeText: require('./examples/RatesByAge.js.example').default, 12 | }, 13 | { 14 | id: 'basic', 15 | label: 'Basic AreaBarChart', 16 | codeText: require('./examples/AreaBarChart.js.example').default, 17 | }, 18 | ]; 19 | 20 | export default class AreaBarChartExamples extends React.Component { 21 | render() { 22 | return ( 23 | 24 | {/* documentation goes here. intersperse docs with examples or leave examples loop below */} 25 | 26 | {examples.map(example => { 27 | return ; 28 | })} 29 | 30 | ); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /docs/src/docs/AreaBarChart/examples/AreaBarChart.js.example: -------------------------------------------------------------------------------- 1 | const AreaBarChartExample = (props) => { 2 | return
3 | 4 | 5 | Math.sin(d / 10) * 10} 8 | xEnd={d => Math.sin((d + 1) / 10) * 10} 9 | y={d => Math.cos(d / (Math.PI))} 10 | /> 11 | 12 | 13 | 14 | Math.cos(d / (Math.PI))} 18 | y={d => Math.sin(d / 10) * 10} 19 | yEnd={d => Math.sin((d + 1) / 10) * 10} 20 | /> 21 | 22 |
23 | }; 24 | 25 | ReactDOM.render(, mountNode); 26 | -------------------------------------------------------------------------------- /docs/src/docs/AreaBarChart/examples/RatesByAge.js.example: -------------------------------------------------------------------------------- 1 | const RatesByAge = (props) => { 2 | return
3 |

US Smoking Rates by Age Group

4 | 5 | 6 | 7 | d.ageMin} 15 | xEnd={d => d.ageMax} 16 | y={d => d.rate} 17 | /> 18 | 19 |
20 | }; 21 | 22 | ReactDOM.render(, mountNode); 23 | -------------------------------------------------------------------------------- /docs/src/docs/AreaChart/AreaChartDocs.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ComponentDocs from '../../ComponentDocs'; 3 | import ExampleSection from '../../ExampleSection'; 4 | // autogenerated docs data containing descriptions of this component's props 5 | import propDocs from './propDocs.json'; 6 | 7 | const examples = [ 8 | { 9 | id: 'basic', 10 | label: 'Basic AreaChart', 11 | codeText: require('./examples/AreaChart.js.example').default, 12 | }, 13 | { 14 | id: 'twoDatasets', 15 | label: 'Area Chart with Two Datasets', 16 | codeText: require('./examples/Area2Datasets.js.example').default, 17 | }, 18 | { 19 | id: 'difference', 20 | label: 'Difference Area Chart', 21 | codeText: require('./examples/AreaDifference.js.example').default, 22 | }, 23 | ]; 24 | 25 | export default class AreaChartExamples extends React.Component { 26 | render() { 27 | return ( 28 | 29 | {/* documentation goes here. intersperse docs with examples or leave examples loop below */} 30 | 31 | {examples.map(example => { 32 | return ; 33 | })} 34 | 35 | ); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /docs/src/docs/AreaChart/examples/Area2Datasets.js.example: -------------------------------------------------------------------------------- 1 | class Area2DatasetsExample extends React.Component { 2 | render() { 3 | const data1 = randomWalkTimeSeries(115).map(([x,y]) => ({x, y})); 4 | const data2 = randomWalkTimeSeries(115).map(([x,y]) => ({x, y})); 5 | 6 | // we have two datasets, but AreaChart takes one combined dataset 7 | // so combine the two datasets into one using the combineDatasets utility function 8 | // (import from 'Reactochart/utils') 9 | // original datasets are of the shape [{x: ..., y: 20}] 10 | // combined is of the shape [{x: ..., y0: 20, y1: 30}] 11 | const combined = utils.Data.combineDatasets([ 12 | {data: data1, combineKey: 'x', dataKeys: {y: 'y0'}}, 13 | {data: data2, combineKey: 'x', dataKeys: {y: 'y1'}} 14 | ], 'x'); 15 | 16 | return
17 | 18 | 19 | d.x} 22 | y={d => d.y0} 23 | yEnd={d => d.y1} 24 | /> 25 | 26 |
27 | } 28 | } 29 | 30 | ReactDOM.render(, mountNode); 31 | -------------------------------------------------------------------------------- /docs/src/docs/AreaChart/examples/AreaChart.js.example: -------------------------------------------------------------------------------- 1 | const AreaChartExample = (props) => { 2 | return
3 | 4 | 5 | 6 | d} 9 | y={d => Math.sin(d / 10) * 10} 10 | yEnd={d => Math.cos((d + 1) / 10) * 10} 11 | /> 12 | 13 |
14 | } 15 | 16 | ReactDOM.render(, mountNode); 17 | -------------------------------------------------------------------------------- /docs/src/docs/AreaChart/examples/AreaDifference.js.example: -------------------------------------------------------------------------------- 1 | class AreaDifferenceExample extends React.Component { 2 | render() { 3 | const data1 = randomWalkTimeSeries(115).map(([x, y]) => ({x, y})); 4 | const data2 = randomWalkTimeSeries(115).map(([x, y]) => ({x, y})); 5 | 6 | // we have two datasets, but AreaChart takes one combined dataset 7 | // so combine the two datasets into one using the combineDatasets utility function 8 | // (from 'reactochart/utils/Data') 9 | const combined = utils.Data.combineDatasets([ 10 | {data: data1, combineKey: 'x', dataKeys: {y: 'y0'}}, 11 | {data: data2, combineKey: 'x', dataKeys: {y: 'y1'}} 12 | ], 'x'); 13 | 14 | return
15 | 16 | 17 | 18 | d.x} 24 | y={d => d.y0} 25 | yEnd={d => d.y1} 26 | /> 27 | d.x} y={d => d.y} 30 | lineStyle={{strokeWidth: 3}} 31 | /> 32 | d.x} y={d => d.y} 35 | /> 36 | 37 |
38 | } 39 | } 40 | ReactDOM.render(, mountNode); 41 | -------------------------------------------------------------------------------- /docs/src/docs/AreaHeatmap/AreaHeatmapDocs.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ComponentDocs from '../../ComponentDocs'; 3 | import ExampleSection from '../../ExampleSection'; 4 | // autogenerated docs data containing descriptions of this component's props 5 | import propDocs from './propDocs.json'; 6 | 7 | const examples = [ 8 | { 9 | id: 'basic', 10 | label: 'Basic AreaHeatmap', 11 | codeText: require('./examples/AreaHeatmap.js.example').default, 12 | }, 13 | ]; 14 | 15 | export default class AreaHeatmapExamples extends React.Component { 16 | render() { 17 | return ( 18 | 19 | {/* documentation goes here. intersperse docs with examples or leave examples loop below */} 20 | 21 | {examples.map(example => { 22 | return ; 23 | })} 24 | 25 | ); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /docs/src/docs/AreaHeatmap/examples/AreaHeatmap.js.example: -------------------------------------------------------------------------------- 1 | const AreaHeatmapExample = (props) => { 2 | const gridData = _.range(30).map(m => { 3 | return _.range(30).map(n => { 4 | return { 5 | x: n, 6 | xEnd: n + 1, 7 | y: m, 8 | yEnd: m + 1, 9 | value: Math.sin(m * n * 0.01) 10 | }; 11 | }); 12 | }); 13 | 14 | const data = _.flatten(gridData); 15 | 16 | return
17 | 18 | 19 | 20 | d.value} 23 | x={d => d.x} 24 | xEnd={d => d.xEnd} 25 | y={d => d.y} 26 | yEnd={d => d.yEnd} 27 | rectStyle={{fill: 'rebeccapurple'}} 28 | /> 29 | 30 | 31 | 32 | 33 | 34 | d.value} 37 | x={d => d.x} 38 | xEnd={d => d.xEnd} 39 | y={d => d.y} 40 | yEnd={d => d.yEnd} 41 | rectStyle={{fill: '#41ab5d'}} 42 | /> 43 | d.value * -1} 46 | x={d => d.x} 47 | xEnd={d => d.xEnd} 48 | y={d => d.y} 49 | yEnd={d => d.yEnd} 50 | rectStyle={{fill: '#fc4e2a'}} 51 | /> 52 | 53 |
; 54 | }; 55 | 56 | ReactDOM.render(, mountNode); 57 | -------------------------------------------------------------------------------- /docs/src/docs/AriaLabelContainer/AriaLabelContainerDocs.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ComponentDocs from '../../ComponentDocs'; 3 | import ExampleSection from '../../ExampleSection'; 4 | // autogenerated docs data containing descriptions of this component's props 5 | import propDocs from './propDocs.json'; 6 | 7 | const examples = [ 8 | { 9 | id: 'one-dataset', 10 | label: 'With One Dataset', 11 | codeText: require('./examples/OneDataset.js.example').default, 12 | }, 13 | { 14 | id: 'two-dataset', 15 | label: 'With Two Datasets', 16 | codeText: require('./examples/TwoDatasets.js.example').default, 17 | }, 18 | { 19 | id: 'action', 20 | label: 'With Interactions', 21 | codeText: require('./examples/WithActions.js.example').default, 22 | }, 23 | ]; 24 | 25 | export default class AriaLabelContainerExamples extends React.Component { 26 | render() { 27 | return ( 28 | 29 | {/* documentation goes here. intersperse docs with examples or leave examples loop below */} 30 | 31 | {examples.map(example => { 32 | return ; 33 | })} 34 | 35 | ); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /docs/src/docs/AriaLabelContainer/examples/OneDataset.js.example: -------------------------------------------------------------------------------- 1 | const AriaLabelContainerExample = (props) => { 2 | const data = _.range(10).map(d => ({ 3 | x: d, 4 | y: Math.round(d * Math.random() * 10) 5 | })) 6 | return 7 | 8 | 9 | d.x} 12 | y={d => d.y} 13 | lineStyle={{stroke: '#ff7f0e', strokeWidth: 3}} 14 | /> 15 | { 17 | const { 0: dataPoint } = datasets; 18 | if(xValue){ 19 | return `xValue, ${dataPoint.x}; yValue, ${dataPoint.y}` 20 | } 21 | }} 22 | datasetWithAccessor={ 23 | [{ 24 | data: data, 25 | accessor: d => d.x 26 | }] 27 | } 28 | /> 29 | ; 30 | }; 31 | 32 | ReactDOM.render(, mountNode); 33 | -------------------------------------------------------------------------------- /docs/src/docs/AriaLabelContainer/examples/TwoDatasets.js.example: -------------------------------------------------------------------------------- 1 | const AriaLabelContainerExample = (props) => { 2 | const data0 = _.range(10).map(d => ({ 3 | x: d, 4 | y: Math.round(d * Math.random() * 10) 5 | })) 6 | const data1 = _.range(7).map(d => ({ 7 | x: d, 8 | y: Math.round(d * Math.random() * 10) 9 | })) 10 | 11 | const ariaLabelGenerator = (xValue, datasets) => { 12 | const { 0: data0Point, 1: data1Point } = datasets; 13 | let ariaLabelString = `x Value, ${xValue}`; 14 | if(data0Point) { 15 | ariaLabelString += `, data0 y Value ${data0Point.y}`; 16 | } 17 | if(data1Point) { 18 | ariaLabelString += `, data1 y Value ${data1Point.y}`; 19 | } 20 | return ariaLabelString; 21 | } 22 | 23 | 24 | return 25 | 26 | 27 | d.x} 30 | y={d => d.y} 31 | lineStyle={{stroke: '#ff7f0e', strokeWidth: 3}} 32 | /> 33 | d.x} 36 | y={d => d.y} 37 | lineStyle={{stroke: '#2ca02c', strokeWidth: 3}} 38 | /> 39 | d.x, 45 | }, 46 | { 47 | data: data1, 48 | accessor: d => d.x, 49 | } 50 | ]} 51 | /> 52 | ; 53 | }; 54 | 55 | ReactDOM.render(, mountNode); 56 | -------------------------------------------------------------------------------- /docs/src/docs/AriaLabelContainer/examples/WithActions.js.example: -------------------------------------------------------------------------------- 1 | const AriaLabelContainerExample = (props) => { 2 | const [selectedValue, setSelectedValue] = React.useState(); 3 | 4 | const data = _.range(10).map(d => ({ 5 | x: d, 6 | y: d * 50, 7 | })) 8 | 9 | const onMouseMove = ({xValue, yValue}) => { 10 | setSelectedValue({ x: xValue, y: yValue }); 11 | } 12 | 13 | const onMouseLeave = () => setSelectedValue(); 14 | 15 | const onKeyDown = (event, xValue, datasets) => { 16 | const dataPoint = datasets[0]; 17 | switch (event.keyCode) { 18 | // enter key code 19 | case 13: 20 | setSelectedValue(dataPoint); 21 | break; 22 | default: 23 | break; 24 | } 25 | } 26 | 27 | 28 | return (
29 | 35 | 36 | 37 | d.x} 40 | y={d => d.y} 41 | lineStyle={{stroke: '#ff7f0e', strokeWidth: 3}} 42 | /> 43 | { 45 | const dataPoint = datasets[0]; 46 | if(dataPoint) { 47 | return `x Value, ${dataPoint.x}; y Value: ${dataPoint.y}` 48 | } 49 | }} 50 | onKeyDown={onKeyDown} 51 | datasetWithAccessor={[ 52 | { 53 | data, 54 | accessor: d => d.x 55 | } 56 | ]} 57 | /> 58 | 59 | {selectedValue &&

{`(${selectedValue.x}, ${selectedValue.y})`}

} 60 |
); 61 | }; 62 | 63 | ReactDOM.render(, mountNode); 64 | -------------------------------------------------------------------------------- /docs/src/docs/Bar/BarDocs.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ComponentDocs from '../../ComponentDocs'; 3 | import ExampleSection from '../../ExampleSection'; 4 | // autogenerated docs data containing descriptions of this component's props 5 | import propDocs from './propDocs.json'; 6 | 7 | const examples = [ 8 | { 9 | id: 'basic', 10 | label: 'Basic Bar', 11 | codeText: require('./examples/Bar.js.example').default, 12 | }, 13 | ]; 14 | 15 | export default class BarExamples extends React.Component { 16 | render() { 17 | return ( 18 | 19 | {/* documentation goes here. intersperse docs with examples or leave examples loop below */} 20 | 21 | {examples.map(example => { 22 | return ; 23 | })} 24 | 25 | ); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /docs/src/docs/Bar/examples/Bar.js.example: -------------------------------------------------------------------------------- 1 | const BarExample = (props) => { 2 | return
3 | 7 | 8 | 13 | 19 | 20 |
; 21 | }; 22 | 23 | ReactDOM.render(, mountNode); 24 | -------------------------------------------------------------------------------- /docs/src/docs/BarChart/BarChartDocs.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ComponentDocs from '../../ComponentDocs'; 3 | import ExampleSection from '../../ExampleSection'; 4 | // autogenerated docs data containing descriptions of this component's props 5 | import propDocs from './propDocs.json'; 6 | 7 | const examples = [ 8 | { 9 | id: 'basic', 10 | label: 'Basic BarChart', 11 | codeText: require('./examples/BarChart.js.example').default, 12 | }, 13 | { 14 | id: 'gradient', 15 | label: 'BarChart with Linear Gradient', 16 | codeText: require('./examples/BarChartLinearGradient.js.example').default, 17 | }, 18 | ]; 19 | 20 | export default class BarChartExamples extends React.Component { 21 | render() { 22 | return ( 23 | 24 | {/* documentation goes here. intersperse docs with examples or leave examples loop below */} 25 | 26 | {examples.map(example => { 27 | return ; 28 | })} 29 | 30 | ); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /docs/src/docs/BarChart/examples/BarChart.js.example: -------------------------------------------------------------------------------- 1 | const BarChartExample = (props) => { 2 | const count = 30; 3 | const startDate = new Date(1992, 0, 1); 4 | 5 | const numbers = _.range(count); 6 | const letters = _.times(count, n => String.fromCharCode(97 + n)); 7 | const dates = _.times(count, n => new Date(+(startDate) + (n * 1000 * 60 * 60 * 24 * 100))); 8 | 9 | const getNumberValue = (d) => 1.97 + Math.cos(d / 10); 10 | const getDateValue = (d) => getNumberValue(d.getFullYear() + (d.getMonth() / 12)); 11 | const getLetterValue = (d) => getNumberValue(d.charCodeAt(0)); 12 | 13 | const chartDefs = _.zip([numbers, letters, dates], [getNumberValue, getLetterValue, getDateValue]); 14 | 15 | return
16 | {([true, false]).map((horizontal, index) => { 17 | return
18 |

{horizontal ? "Horizontal" : "Vertical"}

19 | 20 | {chartDefs.map(([data, getValue], index2) => { 21 | return 22 | 23 | d} 27 | y={horizontal ? d => d : getValue} 28 | /> 29 | ; 30 | })} 31 |
; 32 | })} 33 |
34 | }; 35 | 36 | ReactDOM.render(, mountNode); 37 | -------------------------------------------------------------------------------- /docs/src/docs/BarChart/examples/BarChartLinearGradient.js.example: -------------------------------------------------------------------------------- 1 | const BarChartWithDefs = (props) => { 2 | const data = [ 3 | {x: 0, y: 80}, 4 | {x: 5, y: 60}, 5 | {x: 10, y: 90}, 6 | {x: 15, y: 30}, 7 | ]; 8 | return
9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | d.x} 25 | y={d => d.y} 26 | barThickness={40} 27 | /> 28 | 29 |
30 | }; 31 | 32 | ReactDOM.render(, mountNode); 33 | -------------------------------------------------------------------------------- /docs/src/docs/ColorHeatmap/ColorHeatmapDocs.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ComponentDocs from '../../ComponentDocs'; 3 | import ExampleSection from '../../ExampleSection'; 4 | // autogenerated docs data containing descriptions of this component's props 5 | import propDocs from './propDocs.json'; 6 | 7 | const examples = [ 8 | { 9 | id: 'basic', 10 | label: 'Basic ColorHeatmap', 11 | codeText: require('./examples/ColorHeatmap.js.example').default, 12 | }, 13 | { 14 | id: 'categorical', 15 | label: 'Categorical ColorHeatmap', 16 | codeText: require('./examples/CategoricalColorHeatmap.js.example').default, 17 | }, 18 | ]; 19 | 20 | export default class ColorHeatmapExamples extends React.Component { 21 | render() { 22 | return ( 23 | 24 | {/* documentation goes here. intersperse docs with examples or leave examples loop below */} 25 | 26 | {examples.map(example => { 27 | return ; 28 | })} 29 | 30 | ); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /docs/src/docs/ColorHeatmap/examples/CategoricalColorHeatmap.js.example: -------------------------------------------------------------------------------- 1 | const CategoricalColorHeatmapExample = (props) => { 2 | // sorry, kinda hacky currently! 3 | // working on a better solution... -d 4 | const playTypes = ['www', 'open', 'play', 'other']; 5 | const platforms = ['desktop', 'mobile', 'webplayer', 'other']; 6 | 7 | const gridData = playTypes.map(function(n, i) { 8 | return platforms.map(function(m, j) { 9 | return { 10 | x: i, 11 | xEnd: i + 1, 12 | y: j, 13 | yEnd: j+1, 14 | value: Math.sin(i * j * 0.1) 15 | }; 16 | }) 17 | }); 18 | const data = _.flatten(gridData); 19 | 20 | return
21 | 22 | d.value} 25 | x={d => d.x} 26 | xEnd={d => d.xEnd} 27 | y={d => d.y} 28 | yEnd={d => d.yEnd} 29 | colors={['rebeccapurple', 'goldenrod']} 30 | interpolator={'lab'} 31 | /> 32 | i + 0.5)} 35 | labelFormat={d => playTypes[Math.round(d - 0.5)]} 36 | /> 37 | i + 0.5)} 40 | labelFormat={d => platforms[Math.round(d - 0.5)]} 41 | /> 42 | 43 | 44 | 45 |
46 | }; 47 | 48 | ReactDOM.render(, mountNode); 49 | -------------------------------------------------------------------------------- /docs/src/docs/ColorHeatmap/examples/ColorHeatmap.js.example: -------------------------------------------------------------------------------- 1 | const ColorHeatMapExample = (props) => { 2 | const gridData = _.range(30).map(m => { 3 | return _.range(30).map(n => { 4 | return { 5 | x: n, 6 | xEnd: n + 1, 7 | y: m, 8 | yEnd: m + 1, 9 | value: Math.sin(m * n * 0.01) 10 | }; 11 | }); 12 | }); 13 | 14 | const data = _.flatten(gridData); 15 | 16 | return
17 | 18 | d.value} 21 | x={d => d.x} 22 | xEnd={d => d.xEnd} 23 | y={d => d.y} 24 | yEnd={d => d.yEnd} 25 | colors={['rebeccapurple', 'goldenrod']} 26 | interpolator={'lab'} 27 | /> 28 | 29 | 30 | 31 | 32 | 33 | d.value} 36 | x={d => d.x} 37 | xEnd={d => d.xEnd} 38 | y={d => d.y} 39 | yEnd={d => d.yEnd} 40 | valueDomain={[-1, 0, 1]} 41 | colors={['Crimson', '#eee', 'ForestGreen']} 42 | interpolator={'lab'} 43 | /> 44 | 45 | 46 | 47 |
; 48 | }; 49 | 50 | ReactDOM.render(, mountNode); 51 | -------------------------------------------------------------------------------- /docs/src/docs/FunnelChart/FunnelChartDocs.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ComponentDocs from '../../ComponentDocs'; 3 | import ExampleSection from '../../ExampleSection'; 4 | // autogenerated docs data containing descriptions of this component's props 5 | import propDocs from './propDocs.json'; 6 | 7 | const examples = [ 8 | { 9 | id: 'basic', 10 | label: 'Basic FunnelChart', 11 | codeText: require('./examples/FunnelChart.js.example').default, 12 | }, 13 | ]; 14 | 15 | export default class FunnelChartExamples extends React.Component { 16 | render() { 17 | return ( 18 | 19 | {/* documentation goes here. intersperse docs with examples or leave examples loop below */} 20 | 21 | {examples.map(example => { 22 | return ; 23 | })} 24 | 25 | ); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /docs/src/docs/FunnelChart/examples/FunnelChart.js.example: -------------------------------------------------------------------------------- 1 | const FunnelChartExample = (props) => { 2 | const funnelData = [ 3 | {observation: 1, value: 100}, 4 | {observation: 2, value: 85}, 5 | {observation: 3, value: 42}, 6 | {observation: 4, value: 37}, 7 | {observation: 5, value: 12} 8 | ]; 9 | 10 | return
11 | 12 | 13 | 14 | d.observation} 17 | y={d => d.value} 18 | /> 19 | 20 | 21 | 22 | 23 | 24 | d.value} 28 | y={d => d.observation} 29 | /> 30 | 31 |
32 | }; 33 | 34 | ReactDOM.render(, mountNode); 35 | -------------------------------------------------------------------------------- /docs/src/docs/Histogram/HistogramDocs.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ComponentDocs from '../../ComponentDocs'; 3 | import ExampleSection from '../../ExampleSection'; 4 | // autogenerated docs data containing descriptions of this component's props 5 | import propDocs from './propDocs.json'; 6 | 7 | const examples = [ 8 | { 9 | id: 'basic', 10 | label: 'Basic Histogram', 11 | codeText: require('./examples/Histogram.js.example').default, 12 | }, 13 | ]; 14 | 15 | export default class HistogramExamples extends React.Component { 16 | render() { 17 | return ( 18 | 19 | {/* documentation goes here. intersperse docs with examples or leave examples loop below */} 20 | 21 | {examples.map(example => { 22 | return ; 23 | })} 24 | 25 | ); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /docs/src/docs/Histogram/examples/Histogram.js.example: -------------------------------------------------------------------------------- 1 | const HistogramExample = (props) => { 2 | const randomNormalArr = _.times(1000, d3.randomNormal(0, 1)).concat(_.times(1000, d3.randomNormal(3, 0.5))); 3 | 4 | return
5 |
6 | 10 | 11 | d} 14 | /> 15 | 16 |
17 |
18 |

With nicing applied

19 | 23 | 24 | d} 27 | nice={true} 28 | thresholds={10} 29 | /> 30 | 31 |
32 |
33 |

With specified binDomain

34 | 38 | 39 | d} 42 | binDomain={[-6, 6]} 43 | /> 44 | 45 |
46 |
; 47 | }; 48 | 49 | ReactDOM.render(, mountNode); 50 | -------------------------------------------------------------------------------- /docs/src/docs/KernelDensityEstimation/KernelDensityEstimationDocs.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ComponentDocs from '../../ComponentDocs'; 3 | import ExampleSection from '../../ExampleSection'; 4 | // autogenerated docs data containing descriptions of this component's props 5 | import propDocs from './propDocs.json'; 6 | 7 | const examples = [ 8 | { 9 | id: 'basic', 10 | label: 'Basic KernelDensityEstimation', 11 | codeText: require('./examples/KernelDensityEstimation.js.example').default, 12 | }, 13 | ]; 14 | 15 | export default class KernelDensityEstimationExamples extends React.Component { 16 | render() { 17 | return ( 18 | 19 | {/* documentation goes here. intersperse docs with examples or leave examples loop below */} 20 | 21 | {examples.map(example => { 22 | return ; 23 | })} 24 | 25 | ); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /docs/src/docs/KernelDensityEstimation/examples/KernelDensityEstimation.js.example: -------------------------------------------------------------------------------- 1 | const KernelDensityEstimationExample = (props) => { 2 | const randomNormalArr = _.times(1000, d3.randomNormal(0, 1)).concat(_.times(1000, d3.randomNormal(3, 0.5))); 3 | 4 | return
5 |
6 | 7 | 8 | d} 10 | /> 11 | d} bandwidth={0.5} 13 | /> 14 | d} bandwidth={0.1} 16 | /> 17 | d} bandwidth={2} 19 | /> 20 | 21 |
22 | {/*
*/} 23 | {/**/} 30 | {/* Math.random()}*/} 34 | {/*pointRadius={1}*/} 35 | {/*/>*/} 36 | {/**/} 37 | {/*
*/} 38 |
; 39 | }; 40 | 41 | ReactDOM.render(, mountNode); 42 | -------------------------------------------------------------------------------- /docs/src/docs/LineChart/LineChartDocs.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ComponentDocs from '../../ComponentDocs'; 3 | import ExampleSection from '../../ExampleSection'; 4 | // autogenerated docs data containing descriptions of this component's props 5 | import propDocs from './propDocs.json'; 6 | 7 | const examples = [ 8 | { 9 | id: 'basic', 10 | label: 'Basic LineChart', 11 | codeText: require('./examples/LineChart.js.example').default, 12 | }, 13 | { 14 | id: 'interactive', 15 | label: 'Interactive LineChart', 16 | codeText: require('./examples/InteractiveLineChart.js.example').default, 17 | }, 18 | ]; 19 | 20 | export default class LineChartExamples extends React.Component { 21 | render() { 22 | return ( 23 | 24 | {/* documentation goes here. intersperse docs with examples or leave examples loop below */} 25 | 26 | {examples.map(example => { 27 | return ; 28 | })} 29 | 30 | ); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /docs/src/docs/LineChart/examples/InteractiveLineChart.js.example: -------------------------------------------------------------------------------- 1 | const line1 = d => Math.sin(d*.1); 2 | const line2 = d => Math.cos(d*.1); 3 | const line3 = d => Math.sin(d*.2) * 1.5; 4 | 5 | const dPlusOne = d => d + 1; 6 | 7 | const gridData = _.range(30).map(m => { 8 | return _.range(30).map(n => { 9 | return { 10 | x: n, 11 | xEnd: n + 1, 12 | y: m, 13 | yEnd: m + 1, 14 | value: Math.sin(m * n * 0.01) 15 | }; 16 | }); 17 | }); 18 | 19 | const randomNormalArr = _.times(1000, d3.randomNormal(0, 1)).concat(_.times(1000, d3.randomNormal(3, 0.5))); 20 | 21 | class InteractiveLineChartExample extends React.Component { 22 | state = { 23 | activeX: null 24 | }; 25 | 26 | _onMouseMove = ({xValue, yValue}) => { 27 | this.setState({activeX: xValue}); 28 | }; 29 | 30 | render() { 31 | const {activeX} = this.state; 32 | const colors = d3.scaleOrdinal(d3.schemeCategory10); 33 | 34 | return
35 | 36 | 37 | 38 | 39 | {/**/} 45 | 51 | 57 | 63 | 64 | 70 | 71 | {activeX ? 72 | : 73 | null 74 | } 75 | 76 | {/*{activeX ?*/} 77 | {/* [activeX, lineFunc(activeX)])}*/} 79 | {/*getX={0}*/} 80 | {/*getY={1}*/} 81 | {/*pointRadius={5}*/} 82 | {/*/> :*/} 83 | {/*null*/} 84 | {/*}*/} 85 | 86 | 87 | {activeX ? 88 |

{this.state.activeX.toFixed(3)}

: 89 | null 90 | } 91 |
92 | } 93 | } 94 | 95 | ReactDOM.render(, mountNode); 96 | -------------------------------------------------------------------------------- /docs/src/docs/LineChart/examples/LineChart.js.example: -------------------------------------------------------------------------------- 1 | const LineChartExample = (props) => { 2 | return
3 | 4 | 5 | 6 | d} 9 | y={d => Math.sin(d*.1)} 10 | lineStyle={{stroke: '#ff7f0e', strokeWidth: 3}} 11 | /> 12 | d} 15 | y={d => Math.cos(d*.1)} 16 | lineStyle={{stroke: '#1f77b4', strokeWidth: 2}} 17 | /> 18 | d} 21 | y={d => Math.sin(d*.2) * 1.5} 22 | lineStyle={{stroke: '#2ca02c', strokeWidth: 1}} 23 | /> 24 | 25 |
26 | }; 27 | 28 | ReactDOM.render(, mountNode); 29 | -------------------------------------------------------------------------------- /docs/src/docs/LineChart/propDocs.json: -------------------------------------------------------------------------------- 1 | { 2 | "description": "`LineChart` displays a series of points connected by straight line segments.\nEach `LineChart` renders one line.", 3 | "displayName": "LineChart", 4 | "methods": [ 5 | { 6 | "name": "getBisectorState", 7 | "docblock": null, 8 | "modifiers": ["static"], 9 | "params": [ 10 | { 11 | "name": "props", 12 | "type": null 13 | } 14 | ], 15 | "returns": null 16 | }, 17 | { 18 | "name": "getHovered", 19 | "docblock": null, 20 | "modifiers": [], 21 | "params": [ 22 | { 23 | "name": "x", 24 | "type": null 25 | } 26 | ], 27 | "returns": null 28 | } 29 | ], 30 | "props": { 31 | "data": { 32 | "type": { 33 | "name": "array" 34 | }, 35 | "required": true, 36 | "description": "Array of data objects" 37 | }, 38 | "x": { 39 | "type": { 40 | "name": "custom", 41 | "raw": "CustomPropTypes.valueOrAccessor" 42 | }, 43 | "required": false, 44 | "description": "Accessor function for line X values, called once per datum, or a single value to be used for the entire line." 45 | }, 46 | "y": { 47 | "type": { 48 | "name": "custom", 49 | "raw": "CustomPropTypes.valueOrAccessor" 50 | }, 51 | "required": false, 52 | "description": "Accessor function for line Y values, called once per datum, or a single value to be used for the entire line." 53 | }, 54 | "lineStyle": { 55 | "type": { 56 | "name": "object" 57 | }, 58 | "required": false, 59 | "description": "Inline style object to be applied to the line path.", 60 | "defaultValue": { 61 | "value": "{}", 62 | "computed": false 63 | } 64 | }, 65 | "lineClassName": { 66 | "type": { 67 | "name": "string" 68 | }, 69 | "required": false, 70 | "description": "Class attribute to be applied to the line path.", 71 | "defaultValue": { 72 | "value": "''", 73 | "computed": false 74 | } 75 | }, 76 | "xScale": { 77 | "type": { 78 | "name": "func" 79 | }, 80 | "required": false, 81 | "description": "D3 scale for X axis - provided by XYPlot." 82 | }, 83 | "yScale": { 84 | "type": { 85 | "name": "func" 86 | }, 87 | "required": false, 88 | "description": "D3 scale for Y axis - provided by XYPlot." 89 | }, 90 | "curve": { 91 | "type": { 92 | "name": "func" 93 | }, 94 | "required": false, 95 | "description": "D3 curve for path generation", 96 | "defaultValue": { 97 | "value": "curveLinear", 98 | "computed": true 99 | } 100 | } 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /docs/src/docs/MarkerLineChart/MarkerLineChartDocs.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ComponentDocs from '../../ComponentDocs'; 3 | import ExampleSection from '../../ExampleSection'; 4 | // autogenerated docs data containing descriptions of this component's props 5 | import propDocs from './propDocs.json'; 6 | 7 | const examples = [ 8 | { 9 | id: 'basic', 10 | label: 'Basic MarkerLineChart', 11 | codeText: require('./examples/MarkerLineChart.js.example').default, 12 | }, 13 | { 14 | id: 'withBar', 15 | label: 'MarkerLineChart with BarChart', 16 | codeText: require('./examples/MarkerLineWithBarChart.js.example').default, 17 | }, 18 | ]; 19 | 20 | export default class MarkerLineChartExamples extends React.Component { 21 | render() { 22 | return ( 23 | 24 | {/* documentation goes here. intersperse docs with examples or leave examples loop below */} 25 | 26 | {examples.map(example => { 27 | return ; 28 | })} 29 | 30 | ); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /docs/src/docs/MarkerLineChart/examples/MarkerLineChart.js.example: -------------------------------------------------------------------------------- 1 | const MarkerLineChartExample = (props) => { 2 | return
3 |
4 | 5 | 6 | 7 | d} 10 | y={d => Math.sin(d / (Math.PI))} 11 | /> 12 | 13 | 14 | 15 | 16 | 17 | d} 21 | y={d => Math.sin(d / (Math.PI))} 22 | /> 23 | 24 |
25 | 26 |
27 | 28 | 29 | 30 | Math.sin(d / 10) * 10} 33 | xEnd={d => Math.sin((d + 1) / 10) * 10} 34 | y={d => Math.sin(d / (Math.PI))} 35 | /> 36 | 37 | 38 | 39 | 40 | 41 | Math.sin(d / (Math.PI))} 45 | y={d => Math.sin(d / 10) * 10} 46 | yEnd={d => Math.sin((d + 1) / 10) * 10} 47 | /> 48 | 49 |
50 |
; 51 | }; 52 | 53 | ReactDOM.render(, mountNode); 54 | -------------------------------------------------------------------------------- /docs/src/docs/MarkerLineChart/examples/MarkerLineWithBarChart.js.example: -------------------------------------------------------------------------------- 1 | const MarkerLineWithBarChartExample = (props) => { 2 | const data1 = [[1, 12], [2, 23], [3, 14], [4, 17], [5, 29], [6, 21]]; 3 | const data2 = [[1, 14], [2, 21], [3, 19], [4, 11], [5, 27], [6, 11]]; 4 | 5 | return
6 | 7 | 8 | 9 | d[0]} 12 | y={d => d[1]} 13 | /> 14 | d[0]} 17 | y={d => d[1]} 18 | lineLength={15} 19 | /> 20 | 21 |
; 22 | }; 23 | 24 | ReactDOM.render(, mountNode); 25 | -------------------------------------------------------------------------------- /docs/src/docs/MeasuredValueLabel/MeasuredValueLabelDocs.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ComponentDocs from '../../ComponentDocs'; 3 | import ExampleSection from '../../ExampleSection'; 4 | // autogenerated docs data containing descriptions of this component's props 5 | import propDocs from './propDocs.json'; 6 | 7 | const examples = [ 8 | { 9 | id: 'basic', 10 | label: 'Basic MeasuredValueLabel', 11 | codeText: require('./examples/MeasuredValueLabel.js.example').default, 12 | }, 13 | ]; 14 | 15 | export default class MeasuredValueLabelExamples extends React.Component { 16 | render() { 17 | return ( 18 | 19 | {/* documentation goes here. intersperse docs with examples or leave examples loop below */} 20 | 21 | {examples.map(example => { 22 | return ; 23 | })} 24 | 25 | ); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /docs/src/docs/MeasuredValueLabel/examples/MeasuredValueLabel.js.example: -------------------------------------------------------------------------------- 1 | const MeasuredValueLabelExample = (props) => { 2 | return
insert example here
; 3 | }; 4 | 5 | ReactDOM.render(, mountNode); 6 | -------------------------------------------------------------------------------- /docs/src/docs/MeasuredValueLabel/propDocs.json: -------------------------------------------------------------------------------- 1 | { 2 | "description": "", 3 | "displayName": "MeasuredValueLabel", 4 | "methods": [ 5 | { 6 | "name": "getLabel", 7 | "docblock": null, 8 | "modifiers": ["static"], 9 | "params": [ 10 | { 11 | "name": "props", 12 | "type": null 13 | } 14 | ], 15 | "returns": null 16 | } 17 | ], 18 | "props": { 19 | "value": { 20 | "type": { 21 | "name": "any" 22 | }, 23 | "required": false, 24 | "description": "" 25 | }, 26 | "format": { 27 | "type": { 28 | "name": "func" 29 | }, 30 | "required": false, 31 | "description": "", 32 | "defaultValue": { 33 | "value": "identity", 34 | "computed": true 35 | } 36 | }, 37 | "children": { 38 | "type": { 39 | "name": "any" 40 | }, 41 | "required": false, 42 | "description": "" 43 | }, 44 | "style": { 45 | "defaultValue": { 46 | "value": "{\n fontFamily: 'Helvetica, sans-serif',\n fontSize: '20px',\n lineHeight: 1,\n textAnchor: 'middle',\n}", 47 | "computed": false 48 | }, 49 | "required": false 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /docs/src/docs/PieChart/PieChartDocs.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ComponentDocs from '../../ComponentDocs'; 3 | import ExampleSection from '../../ExampleSection'; 4 | // autogenerated docs data containing descriptions of this component's props 5 | import propDocs from './propDocs.json'; 6 | 7 | const examples = [ 8 | { 9 | id: 'basic', 10 | label: 'Basic PieChart', 11 | codeText: require('./examples/PieChart.js.example').default, 12 | }, 13 | ]; 14 | 15 | export default class PieChartExamples extends React.Component { 16 | render() { 17 | return ( 18 | 19 | {/* documentation goes here. intersperse docs with examples or leave examples loop below */} 20 | 21 | {examples.map(example => { 22 | return ; 23 | })} 24 | 25 | ); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /docs/src/docs/PieChart/examples/PieChart.js.example: -------------------------------------------------------------------------------- 1 | class PieChartExample extends React.Component { 2 | state = { sinVal: 0 }; 3 | 4 | _animateValue = () => { 5 | const sinVal = Math.min( 6 | Math.abs( 7 | Math.cos(new Date() * 0.001) * Math.sin(new Date() * 0.0011) + 1, 8 | ), 9 | 2, 10 | ); 11 | this.setState({ sinVal }); 12 | }; 13 | 14 | componentDidMount() { 15 | this._interval = setInterval(this._animateValue, 20); 16 | } 17 | componentWillUnmount() { 18 | clearInterval(this._interval); 19 | } 20 | 21 | getPieSliceFill = datum => { 22 | const color = d3.interpolateSinebow(datum / 100); 23 | return { 24 | fill: color, 25 | }; 26 | }; 27 | 28 | render() { 29 | const slice = d => d; 30 | return ( 31 |
32 | 37 | 45 | 53 | 61 | `${val}%`} 65 | pieSliceLabelDistance={20} 66 | holeRadius={75} 67 | radius={100} 68 | marginTop={50} 69 | marginBottom={50} 70 | marginLeft={50} 71 | marginRight={50} 72 | /> 73 |
74 | ); 75 | } 76 | } 77 | 78 | ReactDOM.render(, mountNode); 79 | -------------------------------------------------------------------------------- /docs/src/docs/RangeBarChart/RangeBarChartDocs.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ComponentDocs from '../../ComponentDocs'; 3 | import ExampleSection from '../../ExampleSection'; 4 | // autogenerated docs data containing descriptions of this component's props 5 | import propDocs from './propDocs.json'; 6 | 7 | const examples = [ 8 | { 9 | id: 'basic', 10 | label: 'Basic RangeBarChart', 11 | codeText: require('./examples/RangeBarChart.js.example').default, 12 | }, 13 | ]; 14 | 15 | export default class RangeBarChartExamples extends React.Component { 16 | render() { 17 | return ( 18 | 19 | {/* documentation goes here. intersperse docs with examples or leave examples loop below */} 20 | 21 | {examples.map(example => { 22 | return ; 23 | })} 24 | 25 | ); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /docs/src/docs/RangeRect/RangeRectDocs.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ComponentDocs from '../../ComponentDocs'; 3 | import ExampleSection from '../../ExampleSection'; 4 | // autogenerated docs data containing descriptions of this component's props 5 | import propDocs from './propDocs.json'; 6 | 7 | const examples = [ 8 | { 9 | id: 'basic', 10 | label: 'Basic RangeRect', 11 | codeText: require('./examples/RangeRect.js.example').default, 12 | }, 13 | ]; 14 | 15 | export default class RangeRectExamples extends React.Component { 16 | render() { 17 | return ( 18 | 19 | {/* documentation goes here. intersperse docs with examples or leave examples loop below */} 20 | 21 | {examples.map(example => { 22 | return ; 23 | })} 24 | 25 | ); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /docs/src/docs/RangeRect/examples/RangeRect.js.example: -------------------------------------------------------------------------------- 1 | const RangeRectExample = (props) => { 2 | return
3 | 7 | 8 | 13 | 18 | 19 |
; 20 | }; 21 | 22 | ReactDOM.render(, mountNode); 23 | -------------------------------------------------------------------------------- /docs/src/docs/SankeyDiagram/SankeyDiagramDocs.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ComponentDocs from '../../ComponentDocs'; 3 | import ExampleSection from '../../ExampleSection'; 4 | // autogenerated docs data containing descriptions of this component's props 5 | import propDocs from './propDocs.json'; 6 | 7 | const examples = [ 8 | { 9 | id: 'basic', 10 | label: 'Basic SankeyDiagram', 11 | codeText: require('./examples/SankeyDiagram.js.example').default, 12 | }, 13 | { 14 | id: 'interactive', 15 | label: 'Interactive Sankey Diagram', 16 | codeText: require('./examples/SankeyInteractive.js.example').default, 17 | }, 18 | ]; 19 | 20 | export default class SankeyDiagramExamples extends React.Component { 21 | render() { 22 | return ( 23 | 24 | {/* documentation goes here. intersperse docs with examples or leave examples loop below */} 25 | 26 | {examples.map(example => { 27 | return ; 28 | })} 29 | 30 | ); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /docs/src/docs/ScatterPlot/ScatterPlotDocs.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ComponentDocs from '../../ComponentDocs'; 3 | import ExampleSection from '../../ExampleSection'; 4 | // autogenerated docs data containing descriptions of this component's props 5 | import propDocs from './propDocs.json'; 6 | 7 | const examples = [ 8 | { 9 | id: 'basic', 10 | label: 'Basic ScatterPlot', 11 | codeText: require('./examples/ScatterPlot.js.example').default, 12 | }, 13 | ]; 14 | 15 | export default class ScatterPlotExamples extends React.Component { 16 | render() { 17 | return ( 18 | 19 | {/* documentation goes here. intersperse docs with examples or leave examples loop below */} 20 | 21 | {examples.map(example => { 22 | return ; 23 | })} 24 | 25 | ); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /docs/src/docs/ScatterPlot/examples/ScatterPlot.js.example: -------------------------------------------------------------------------------- 1 | const randomScatter = [ 2 | _.zip(randomWalk(20, 100), randomWalk(20, 100)), 3 | _.zip(randomWalk(3000, 10000), randomWalk(3000, 10000)), 4 | _.zip(randomWalk(50, 100), randomWalk(50, 100)), 5 | _.zip(randomWalk(100, 100), randomWalk(100, 100)), 6 | _.zip(randomWalk(200, 100), randomWalk(200, 100)) 7 | ]; 8 | 9 | const emojis = ["😀", "😁", "😂", "😅", "😆", "😇", "😈", "👿", "😉", "😊", "😐", "😑", "😒", "😓", "😔", "😕", "😖", "😗", "😘", "😙", "😚", "😛", "😜", "😝", "👻", "👹", "👺", "💩", "💀", "👽", "👾", "🙇", "💁", "🙅", "🙆", "🙋", "🙎", "🙍", "💆", "💇"]; 10 | 11 | const ScatterPlotExample = () => { 12 | const rectangleSymbol = ; 13 | const triangleSymbol = ; 14 | const randomEmoji = (d, i) => _.sample(emojis); 15 | 16 | return
17 | 18 | 19 | 20 | 21 | d[0]} 24 | y={d => d[1]} 25 | pointSymbol={rectangleSymbol} 26 | /> 27 | d[0]} 30 | y={d => d[1]} 31 | pointSymbol={randomEmoji} 32 | pointOffset={[0, 2]} 33 | /> 34 | 35 | d[0]} 38 | y={d => d[1]} 39 | pointSymbol={(d, i) => i} 40 | /> 41 | d[0]} 44 | y={d => d[1]} 45 | pointSymbol={triangleSymbol} 46 | pointOffset={[-4, -3]} 47 | /> 48 | 49 |
50 | }; 51 | 52 | ReactDOM.render(, mountNode); 53 | -------------------------------------------------------------------------------- /docs/src/docs/TreeMap/TreeMapDocs.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ComponentDocs from '../../ComponentDocs'; 3 | import ExampleSection from '../../ExampleSection'; 4 | // autogenerated docs data containing descriptions of this component's props 5 | import propDocs from './propDocs.json'; 6 | 7 | const examples = [ 8 | { 9 | id: 'basic', 10 | label: 'Basic TreeMap', 11 | codeText: require('./examples/TreeMap.js.example').default, 12 | }, 13 | { 14 | id: 'animated', 15 | label: 'Animated TreeMap', 16 | codeText: require('./examples/AnimatedTreeMap.js.example').default, 17 | }, 18 | ]; 19 | 20 | export default class TreeMapExamples extends React.Component { 21 | render() { 22 | return ( 23 | 24 | {/* documentation goes here. intersperse docs with examples or leave examples loop below */} 25 | 26 | {examples.map(example => { 27 | return ; 28 | })} 29 | 30 | ); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /docs/src/docs/TreeMap/examples/AnimatedTreeMap.js.example: -------------------------------------------------------------------------------- 1 | class AnimatedTreeMapExample extends React.Component { 2 | constructor(props) { 3 | super(props); 4 | 5 | const data = { 6 | children: _.range(1, 5).map(n => ({ 7 | children: _.times(n * n, m => ({ 8 | size: (n +1) * (m + 1) + (100 * Math.random()), 9 | size2: (n +1) * (m + 1) + (100 * Math.random()) 10 | })) 11 | })) 12 | }; 13 | 14 | this.state = { getValue: "size", data }; 15 | } 16 | 17 | _animateValue = () => { 18 | if(this.state.getValue === "size") 19 | this.setState({getValue: "size2"}); 20 | else 21 | this.setState({getValue: "size"}); 22 | }; 23 | 24 | componentDidMount() { 25 | this._interval = setInterval(this._animateValue, 1000); 26 | } 27 | 28 | componentWillUnmount() { 29 | clearInterval(this._interval); 30 | } 31 | 32 | render() { 33 | const {getValue, data} = this.state; 34 | 35 | const colorScale = d3.scaleLinear() 36 | .domain([0, 65]) 37 | .range(['#6b6ecf', '#8ca252']) 38 | .interpolate(d3.interpolateHcl); 39 | 40 | return
41 | ({ 46 | backgroundColor: colorScale(parseInt(node.data.size)), 47 | border: '1px solid #333' 48 | })} 49 | sticky 50 | width={400} 51 | height={500} 52 | /> 53 |
54 | } 55 | } 56 | 57 | ReactDOM.render(, mountNode); 58 | -------------------------------------------------------------------------------- /docs/src/docs/TreeMap/examples/TreeMap.js.example: -------------------------------------------------------------------------------- 1 | const TreeMapExample = props => { 2 | const data = { 3 | children: _.range(1, 5).map(n => ({ 4 | children: _.times(n * n, m => ({ 5 | size: n * (m + 1) 6 | })) 7 | })) 8 | }; 9 | 10 | const colorScale = d3 11 | .scaleLinear() 12 | .domain([0, 65]) 13 | .range(["#6b6ecf", "#8ca252"]) 14 | .interpolate(d3.interpolateHcl); 15 | 16 | return ( 17 |
18 | d.size} 21 | getLabel={d => d.value} 22 | nodeStyle={node => ({ 23 | backgroundColor: colorScale(parseInt(node.data.size)), 24 | border: "1px solid #333" 25 | })} 26 | width={400} 27 | height={500} 28 | /> 29 |
30 | ); 31 | }; 32 | 33 | ReactDOM.render(, mountNode); 34 | -------------------------------------------------------------------------------- /docs/src/docs/TreeMapNode/TreeMapNodeDocs.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ComponentDocs from '../../ComponentDocs'; 3 | import ExampleSection from '../../ExampleSection'; 4 | // autogenerated docs data containing descriptions of this component's props 5 | import propDocs from './propDocs.json'; 6 | 7 | const examples = [ 8 | { 9 | id: 'basic', 10 | label: 'Basic TreeMapNode', 11 | codeText: require('./examples/TreeMapNode.js.example').default, 12 | }, 13 | ]; 14 | 15 | export default class TreeMapNodeExamples extends React.Component { 16 | render() { 17 | return ( 18 | 19 | {/* documentation goes here. intersperse docs with examples or leave examples loop below */} 20 | 21 | {examples.map(example => { 22 | return ; 23 | })} 24 | 25 | ); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /docs/src/docs/TreeMapNode/examples/TreeMapNode.js.example: -------------------------------------------------------------------------------- 1 | const TreeMapNodeExample = (props) => { 2 | return
insert example here
; 3 | }; 4 | 5 | ReactDOM.render(, mountNode); 6 | -------------------------------------------------------------------------------- /docs/src/docs/TreeMapNode/propDocs.json: -------------------------------------------------------------------------------- 1 | { 2 | "description": "", 3 | "methods": [], 4 | "props": { 5 | "node": { 6 | "type": { 7 | "name": "shape", 8 | "value": { 9 | "parent": { 10 | "name": "object", 11 | "required": false 12 | }, 13 | "children": { 14 | "name": "array", 15 | "required": false 16 | }, 17 | "value": { 18 | "name": "number", 19 | "required": false 20 | }, 21 | "depth": { 22 | "name": "number", 23 | "required": false 24 | }, 25 | "x": { 26 | "name": "number", 27 | "required": false 28 | }, 29 | "y": { 30 | "name": "number", 31 | "required": false 32 | }, 33 | "dx": { 34 | "name": "number", 35 | "required": false 36 | }, 37 | "dy": { 38 | "name": "number", 39 | "required": false 40 | } 41 | } 42 | }, 43 | "required": false, 44 | "description": "" 45 | }, 46 | "nodeStyle": { 47 | "type": { 48 | "name": "union", 49 | "value": [ 50 | { 51 | "name": "func" 52 | }, 53 | { 54 | "name": "object" 55 | } 56 | ] 57 | }, 58 | "required": false, 59 | "description": "" 60 | }, 61 | "minLabelWidth": { 62 | "type": { 63 | "name": "number" 64 | }, 65 | "required": false, 66 | "description": "", 67 | "defaultValue": { 68 | "value": "0", 69 | "computed": false 70 | } 71 | }, 72 | "minLabelHeight": { 73 | "type": { 74 | "name": "number" 75 | }, 76 | "required": false, 77 | "description": "", 78 | "defaultValue": { 79 | "value": "0", 80 | "computed": false 81 | } 82 | }, 83 | "getLabel": { 84 | "type": { 85 | "name": "custom", 86 | "raw": "CustomPropTypes.getter" 87 | }, 88 | "required": false, 89 | "description": "" 90 | }, 91 | "labelStyle": { 92 | "type": { 93 | "name": "union", 94 | "value": [ 95 | { 96 | "name": "func" 97 | }, 98 | { 99 | "name": "object" 100 | } 101 | ] 102 | }, 103 | "required": false, 104 | "description": "" 105 | }, 106 | "NodeLabelComponent": { 107 | "type": { 108 | "name": "func" 109 | }, 110 | "required": false, 111 | "description": "" 112 | } 113 | } 114 | } -------------------------------------------------------------------------------- /docs/src/docs/TreeMapNodeLabel/TreeMapNodeLabelDocs.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ComponentDocs from '../../ComponentDocs'; 3 | import ExampleSection from '../../ExampleSection'; 4 | // autogenerated docs data containing descriptions of this component's props 5 | import propDocs from './propDocs.json'; 6 | 7 | const examples = [ 8 | { 9 | id: 'basic', 10 | label: 'Basic TreeMapNodeLabel', 11 | codeText: require('./examples/TreeMapNodeLabel.js.example').default, 12 | }, 13 | ]; 14 | 15 | export default class TreeMapNodeLabelExamples extends React.Component { 16 | render() { 17 | return ( 18 | 19 | {/* documentation goes here. intersperse docs with examples or leave examples loop below */} 20 | 21 | {examples.map(example => { 22 | return ; 23 | })} 24 | 25 | ); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /docs/src/docs/TreeMapNodeLabel/examples/TreeMapNodeLabel.js.example: -------------------------------------------------------------------------------- 1 | const TreeMapNodeLabelExample = (props) => { 2 | return
insert example here
; 3 | }; 4 | 5 | ReactDOM.render(, mountNode); 6 | -------------------------------------------------------------------------------- /docs/src/docs/TreeMapNodeLabel/propDocs.json: -------------------------------------------------------------------------------- 1 | { 2 | "description": "", 3 | "methods": [], 4 | "props": { 5 | "node": { 6 | "type": { 7 | "name": "object" 8 | }, 9 | "required": false, 10 | "description": "" 11 | }, 12 | "getLabel": { 13 | "type": { 14 | "name": "custom", 15 | "raw": "CustomPropTypes.getter" 16 | }, 17 | "required": false, 18 | "description": "" 19 | }, 20 | "labelStyle": { 21 | "type": { 22 | "name": "union", 23 | "value": [ 24 | { 25 | "name": "func" 26 | }, 27 | { 28 | "name": "object" 29 | } 30 | ] 31 | }, 32 | "required": false, 33 | "description": "" 34 | }, 35 | "minLabelWidth": { 36 | "type": { 37 | "name": "number" 38 | }, 39 | "required": false, 40 | "description": "" 41 | }, 42 | "minLabelHeight": { 43 | "type": { 44 | "name": "number" 45 | }, 46 | "required": false, 47 | "description": "" 48 | } 49 | } 50 | } -------------------------------------------------------------------------------- /docs/src/docs/XAxis/XAxisDocs.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ComponentDocs from '../../ComponentDocs'; 3 | import ExampleSection from '../../ExampleSection'; 4 | // autogenerated docs data containing descriptions of this component's props 5 | import propDocs from './propDocs.json'; 6 | 7 | const examples = [ 8 | { 9 | id: 'basic', 10 | label: 'Basic XAxis', 11 | codeText: require('./examples/XAxis.js.example').default, 12 | }, 13 | { 14 | id: 'customTicks', 15 | label: 'XAxis with custom ticks', 16 | codeText: require('./examples/XAxisCustomTicks.js.example').default, 17 | }, 18 | ]; 19 | 20 | export default class XAxisExamples extends React.Component { 21 | render() { 22 | return ( 23 | 24 | {/* documentation goes here. intersperse docs with examples or leave examples loop below */} 25 | 26 | {examples.map(example => { 27 | return ; 28 | })} 29 | 30 | ); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /docs/src/docs/XAxis/examples/XAxis.js.example: -------------------------------------------------------------------------------- 1 | const XAxisExample = (props) => { 2 | const dateDomain = [new Date(2008, 0, 1), new Date(2017, 0, 1)]; 3 | const numberDomain = [-20, 20]; 4 | const categoricalDomain = ['puppies', 'kitties', 'ponies']; 5 | const smallSize = {width: 300, height: 100}; 6 | 7 | return
8 |
9 | 10 | 11 | 12 |
13 |
14 | 15 | 16 | 17 |
18 |
19 | 20 | 21 | 22 |
23 |
24 | }; 25 | 26 | ReactDOM.render(, mountNode); 27 | -------------------------------------------------------------------------------- /docs/src/docs/XAxis/examples/XAxisCustomTicks.js.example: -------------------------------------------------------------------------------- 1 | const XAxisExample = (props) => { 2 | const size = {width: 350, height: 100}; 3 | 4 | return
5 | 6 | 7 | 8 |
9 | }; 10 | 11 | ReactDOM.render(, mountNode); 12 | -------------------------------------------------------------------------------- /docs/src/docs/XAxisLabels/XAxisLabelsDocs.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ComponentDocs from '../../ComponentDocs'; 3 | import ExampleSection from '../../ExampleSection'; 4 | // autogenerated docs data containing descriptions of this component's props 5 | import propDocs from './propDocs.json'; 6 | 7 | const examples = [ 8 | { 9 | id: 'basic', 10 | label: 'Basic XAxisLabels', 11 | codeText: require('./examples/XAxisLabels.js.example').default, 12 | }, 13 | ]; 14 | 15 | export default class XAxisLabelsExamples extends React.Component { 16 | render() { 17 | return ( 18 | 19 | {/* documentation goes here. intersperse docs with examples or leave examples loop below */} 20 | 21 | {examples.map(example => { 22 | return ; 23 | })} 24 | 25 | ); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /docs/src/docs/XAxisLabels/examples/XAxisLabels.js.example: -------------------------------------------------------------------------------- 1 | const XAxisLabelsExample = (props) => { 2 | const chartStyle = {marginBottom: '10px'}; 3 | 4 | return
5 |
6 | 10 | 13 | label + "%"} 15 | position="top" 16 | distance={2} 17 | tickCount={5} 18 | labelStyle={(label) => { 19 | return { 20 | fontSize: '10px', 21 | fill: label.text === "20%" ? "red" : "black" 22 | }; 23 | } 24 | } /> 25 | 26 |
27 |
28 | }; 29 | 30 | ReactDOM.render(, mountNode); 31 | -------------------------------------------------------------------------------- /docs/src/docs/XAxisTitle/XAxisTitleDocs.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ComponentDocs from '../../ComponentDocs'; 3 | import ExampleSection from '../../ExampleSection'; 4 | // autogenerated docs data containing descriptions of this component's props 5 | import propDocs from './propDocs.json'; 6 | 7 | const examples = [ 8 | { 9 | id: 'basic', 10 | label: 'Basic XAxisTitle', 11 | codeText: require('./examples/XAxisTitle.js.example').default, 12 | }, 13 | { 14 | id: 'all', 15 | label: 'All XAxisTitle Options', 16 | codeText: require('./examples/XAxisTitleAll.js.example').default, 17 | }, 18 | ]; 19 | 20 | export default class XAxisTitleExamples extends React.Component { 21 | render() { 22 | return ( 23 | 24 | {/* documentation goes here. intersperse docs with examples or leave examples loop below */} 25 | 26 | {examples.map(example => { 27 | return ; 28 | })} 29 | 30 | ); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /docs/src/docs/XAxisTitle/examples/XAxisTitle.js.example: -------------------------------------------------------------------------------- 1 | const XAxisTitleExample = (props) => { 2 | const xyProps = { 3 | width: 500, height: 200, 4 | xDomain: [0, 100], yDomain: [0, 100] 5 | }; 6 | 7 | return 8 | 9 | ; 10 | }; 11 | 12 | ReactDOM.render(, mountNode); 13 | -------------------------------------------------------------------------------- /docs/src/docs/XAxisTitle/examples/XAxisTitleAll.js.example: -------------------------------------------------------------------------------- 1 | const XAxisTitleExample = (props) => { 2 | const xyProps = { 3 | width: 500, height: 360, 4 | xDomain: [0, 100], yDomain: [0, 100] 5 | }; 6 | 7 | return 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | ; 43 | }; 44 | 45 | ReactDOM.render(, mountNode); 46 | -------------------------------------------------------------------------------- /docs/src/docs/XGrid/XGridDocs.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ComponentDocs from '../../ComponentDocs'; 3 | import ExampleSection from '../../ExampleSection'; 4 | // autogenerated docs data containing descriptions of this component's props 5 | import propDocs from './propDocs.json'; 6 | 7 | const examples = [ 8 | { 9 | id: 'basic', 10 | label: 'Basic XGrid', 11 | codeText: require('./examples/XGrid.js.example').default, 12 | }, 13 | ]; 14 | 15 | export default class XGridExamples extends React.Component { 16 | render() { 17 | return ( 18 | 19 | {/* documentation goes here. intersperse docs with examples or leave examples loop below */} 20 | 21 | {examples.map(example => { 22 | return ; 23 | })} 24 | 25 | ); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /docs/src/docs/XGrid/examples/XGrid.js.example: -------------------------------------------------------------------------------- 1 | const XGridExample = (props) => { 2 | const size = {width: 400, height: 300}; 3 | 4 | return
5 | 6 | 7 | 8 | 9 |
10 | }; 11 | 12 | ReactDOM.render(, mountNode); 13 | -------------------------------------------------------------------------------- /docs/src/docs/XGrid/propDocs.json: -------------------------------------------------------------------------------- 1 | { 2 | "description": "", 3 | "displayName": "XGrid", 4 | "methods": [ 5 | { 6 | "name": "getTickDomain", 7 | "docblock": null, 8 | "modifiers": ["static"], 9 | "params": [ 10 | { 11 | "name": "props", 12 | "type": null 13 | } 14 | ], 15 | "returns": null 16 | } 17 | ], 18 | "props": { 19 | "width": { 20 | "type": { 21 | "name": "number" 22 | }, 23 | "required": false, 24 | "description": "" 25 | }, 26 | "height": { 27 | "type": { 28 | "name": "number" 29 | }, 30 | "required": false, 31 | "description": "" 32 | }, 33 | "xScale": { 34 | "type": { 35 | "name": "func" 36 | }, 37 | "required": false, 38 | "description": "" 39 | }, 40 | "spacingTop": { 41 | "type": { 42 | "name": "number" 43 | }, 44 | "required": false, 45 | "description": "" 46 | }, 47 | "spacingBottom": { 48 | "type": { 49 | "name": "number" 50 | }, 51 | "required": false, 52 | "description": "" 53 | }, 54 | "spacingLeft": { 55 | "type": { 56 | "name": "number" 57 | }, 58 | "required": false, 59 | "description": "" 60 | }, 61 | "spacingRight": { 62 | "type": { 63 | "name": "number" 64 | }, 65 | "required": false, 66 | "description": "" 67 | }, 68 | "nice": { 69 | "type": { 70 | "name": "bool" 71 | }, 72 | "required": false, 73 | "description": "", 74 | "defaultValue": { 75 | "value": "true", 76 | "computed": false 77 | } 78 | }, 79 | "ticks": { 80 | "type": { 81 | "name": "array" 82 | }, 83 | "required": false, 84 | "description": "" 85 | }, 86 | "tickCount": { 87 | "type": { 88 | "name": "number" 89 | }, 90 | "required": false, 91 | "description": "" 92 | }, 93 | "lineClassName": { 94 | "type": { 95 | "name": "string" 96 | }, 97 | "required": false, 98 | "description": "" 99 | }, 100 | "lineStyle": { 101 | "type": { 102 | "name": "object" 103 | }, 104 | "required": false, 105 | "description": "", 106 | "defaultValue": { 107 | "value": "{}", 108 | "computed": false 109 | } 110 | } 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /docs/src/docs/XLine/XLineDocs.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ComponentDocs from '../../ComponentDocs'; 3 | import ExampleSection from '../../ExampleSection'; 4 | // autogenerated docs data containing descriptions of this component's props 5 | import propDocs from './propDocs.json'; 6 | 7 | const examples = [ 8 | { 9 | id: 'basic', 10 | label: 'Basic XLine', 11 | codeText: require('./examples/XLine.js.example').default, 12 | }, 13 | ]; 14 | 15 | export default class XLineExamples extends React.Component { 16 | render() { 17 | return ( 18 | 19 | {/* documentation goes here. intersperse docs with examples or leave examples loop below */} 20 | 21 | {examples.map(example => { 22 | return ; 23 | })} 24 | 25 | ); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /docs/src/docs/XLine/examples/XLine.js.example: -------------------------------------------------------------------------------- 1 | const XLineExample = (props) => { 2 | return
3 | 4 | 5 | 6 | 7 | 8 |
9 | }; 10 | 11 | ReactDOM.render(, mountNode); 12 | -------------------------------------------------------------------------------- /docs/src/docs/XLine/propDocs.json: -------------------------------------------------------------------------------- 1 | { 2 | "description": "`XLine` is a vertical line rendered on the x axis", 3 | "displayName": "XLine", 4 | "methods": [], 5 | "props": { 6 | "height": { 7 | "type": { 8 | "name": "number" 9 | }, 10 | "required": false, 11 | "description": "Height of chart - provided by XYPlot" 12 | }, 13 | "xScale": { 14 | "type": { 15 | "name": "func" 16 | }, 17 | "required": false, 18 | "description": "D3 scale for X axis - provided by XYPlot" 19 | }, 20 | "value": { 21 | "type": { 22 | "name": "union", 23 | "value": [ 24 | { 25 | "name": "number" 26 | }, 27 | { 28 | "name": "string" 29 | }, 30 | { 31 | "name": "instanceOf", 32 | "value": "Date" 33 | } 34 | ] 35 | }, 36 | "required": true, 37 | "description": "" 38 | }, 39 | "yScale": { 40 | "type": { 41 | "name": "func" 42 | }, 43 | "required": false, 44 | "description": "D3 scale for Y axis - provided by XYPlot" 45 | }, 46 | "yLimit": { 47 | "type": { 48 | "name": "union", 49 | "value": [ 50 | { 51 | "name": "number" 52 | }, 53 | { 54 | "name": "string" 55 | }, 56 | { 57 | "name": "instanceOf", 58 | "value": "Date" 59 | } 60 | ] 61 | }, 62 | "required": false, 63 | "description": "" 64 | }, 65 | "yDomain": { 66 | "type": { 67 | "name": "array" 68 | }, 69 | "required": false, 70 | "description": "The Y domain of the data as an array - provided by XYPlot" 71 | }, 72 | "spacingTop": { 73 | "type": { 74 | "name": "number" 75 | }, 76 | "required": false, 77 | "description": "Spacing top - provided by XYPlot", 78 | "defaultValue": { 79 | "value": "0", 80 | "computed": false 81 | } 82 | }, 83 | "spacingBottom": { 84 | "type": { 85 | "name": "number" 86 | }, 87 | "required": false, 88 | "description": "Spacing bottom - provided by XYPlot", 89 | "defaultValue": { 90 | "value": "0", 91 | "computed": false 92 | } 93 | }, 94 | "style": { 95 | "type": { 96 | "name": "object" 97 | }, 98 | "required": false, 99 | "description": "Inline style object to be applied to the line", 100 | "defaultValue": { 101 | "value": "{}", 102 | "computed": false 103 | } 104 | }, 105 | "className": { 106 | "type": { 107 | "name": "string" 108 | }, 109 | "required": false, 110 | "description": "Class attribute to be applied to the line", 111 | "defaultValue": { 112 | "value": "''", 113 | "computed": false 114 | } 115 | } 116 | } 117 | } 118 | -------------------------------------------------------------------------------- /docs/src/docs/XTicks/XTicksDocs.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ComponentDocs from '../../ComponentDocs'; 3 | import ExampleSection from '../../ExampleSection'; 4 | // autogenerated docs data containing descriptions of this component's props 5 | import propDocs from './propDocs.json'; 6 | 7 | const examples = [ 8 | { 9 | id: 'basic', 10 | label: 'Basic XTicks', 11 | codeText: require('./examples/XTicks.js.example').default, 12 | }, 13 | ]; 14 | 15 | export default class XTicksExamples extends React.Component { 16 | render() { 17 | return ( 18 | 19 | {/* documentation goes here. intersperse docs with examples or leave examples loop below */} 20 | 21 | {examples.map(example => { 22 | return ; 23 | })} 24 | 25 | ); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /docs/src/docs/XTicks/examples/XTicks.js.example: -------------------------------------------------------------------------------- 1 | const XTicksExample = (props) => { 2 | const size = {width: 300, height: 100}; 3 | const chartStyle = {marginBottom: '10px'}; 4 | 5 | return
6 |
7 | Default:
8 | 9 | 10 | 11 |
12 |
13 | Multiple sets of ticks, with options:
14 | 15 | 16 | 17 | 18 | 19 |
20 |
21 | }; 22 | 23 | 24 | ReactDOM.render(, mountNode); 25 | -------------------------------------------------------------------------------- /docs/src/docs/XYPlot/XYPlotDocs.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ComponentDocs from '../../ComponentDocs'; 3 | import ExampleSection from '../../ExampleSection'; 4 | // autogenerated docs data containing descriptions of this component's props 5 | import propDocs from './propDocs.json'; 6 | 7 | const examples = [ 8 | { 9 | id: 'basic', 10 | label: 'Basic XYPlot', 11 | codeText: require('./examples/XYPlot.js.example').default, 12 | }, 13 | { 14 | id: 'spacing', 15 | label: 'Custom Spacing', 16 | codeText: require('./examples/CustomSpacing.js.example').default, 17 | }, 18 | ]; 19 | 20 | export default class XYPlotExamples extends React.Component { 21 | render() { 22 | return ( 23 | 24 | {/* documentation goes here. intersperse docs with examples or leave examples loop below */} 25 | 26 | {examples.map(example => { 27 | return ; 28 | })} 29 | 30 | ); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /docs/src/docs/XYPlot/examples/CustomSpacing.js.example: -------------------------------------------------------------------------------- 1 | const SpacingExample = (props) => { 2 | const spacing = {spacingLeft: 10, spacingTop: 53, spacingRight: 16, spacingBottom: 9}; 3 | 4 | return
5 | 6 | 7 | 8 | d} 11 | y={d => Math.sin(d*.1)} 12 | /> 13 | 14 |
15 | }; 16 | 17 | ReactDOM.render(, mountNode); 18 | -------------------------------------------------------------------------------- /docs/src/docs/XYPlot/examples/XYPlot.js.example: -------------------------------------------------------------------------------- 1 | const MultipleXYExample = (props) => { 2 | return
3 | 4 | 5 | 6 | 7 | d} 10 | y={d => (Math.sin(d*3) * .7) + 1.2} 11 | yEnd={d => (Math.sin(d*3) * Math.cos(d*3) * .7) + 1.2} 12 | barThickness={2} 13 | barStyle={{fill: '#3690c0'}} 14 | /> 15 | 16 | d} 19 | y={d => Math.pow(Math.abs(Math.sin(d*5)), Math.abs(Math.sin(d*.25))) * 1.8} 20 | lineStyle={{stroke: '#02818a', strokeWidth: 3}} 21 | /> 22 | 23 | d} 26 | y={d => Math.pow(2, (d + 2) * 1.8) * 0.1} 27 | pointSymbol={} 28 | /> 29 | 30 | d} 33 | y={d => -Math.abs(Math.sin(d*4) * Math.cos(d*3))} 34 | barThickness={3} 35 | barStyle={{fill: '#67a9cf'}} 36 | /> 37 | 38 | d} 41 | y={d => Math.cos(d)} 42 | lineStyle={{stroke: '#ec7014', strokeWidth: 3}} 43 | /> 44 | 45 | _.range(-2, 0, .1).map(j => [i, j])))} 47 | value={([i, j]) => Math.sin(i * j * 5)} 48 | x={([i, j]) => i} 49 | xEnd={([i, j]) => i + .1} 50 | y={([i, j]) => j} 51 | yEnd={([i, j]) => j + .1} 52 | colors={['#d0d1e6', '#016450']} 53 | interpolator={'lab'} 54 | /> 55 | 56 | _.range(-2, -1, .1).map(j => [i, j])))} 58 | area={([i, j]) => -Math.sin(i * j * 5)} 59 | x={([i, j]) => i} 60 | xEnd={([i, j]) => i + .1} 61 | y={([i, j]) => j} 62 | yEnd={([i, j]) => j + .1} 63 | rectStyle={{fill: '#016450'}} 64 | /> 65 | 66 |
; 67 | }; 68 | 69 | ReactDOM.render(, mountNode); 70 | -------------------------------------------------------------------------------- /docs/src/docs/YAxis/YAxisDocs.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ComponentDocs from '../../ComponentDocs'; 3 | import ExampleSection from '../../ExampleSection'; 4 | // autogenerated docs data containing descriptions of this component's props 5 | import propDocs from './propDocs.json'; 6 | 7 | const examples = [ 8 | { 9 | id: 'basic', 10 | label: 'Basic YAxis', 11 | codeText: require('./examples/YAxis.js.example').default, 12 | }, 13 | { 14 | id: 'customTicks', 15 | label: 'YAxis with custom ticks', 16 | codeText: require('./examples/YAxisCustomTicks.js.example').default, 17 | }, 18 | ]; 19 | 20 | export default class YAxisExamples extends React.Component { 21 | render() { 22 | return ( 23 | 24 | {/* documentation goes here. intersperse docs with examples or leave examples loop below */} 25 | 26 | {examples.map(example => { 27 | return ; 28 | })} 29 | 30 | ); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /docs/src/docs/YAxis/examples/YAxis.js.example: -------------------------------------------------------------------------------- 1 | const YAxisExample = (props) => { 2 | const dateDomain = [new Date(2008, 0, 1), new Date(2017, 0, 1)]; 3 | const numberDomain = [-20, 20]; 4 | const categoricalDomain = ['puppies', 'kitties', 'ponies']; 5 | const size = {width: 100, height: 300}; 6 | const chartStyle = {display: 'inline-block', marginRight: '10px'}; 7 | 8 | return
9 |
10 | 11 | 12 | 13 |
14 |
15 | 16 | 17 | 18 |
19 |
20 | 21 | 22 | 23 |
24 |
25 | }; 26 | 27 | 28 | ReactDOM.render(, mountNode); 29 | -------------------------------------------------------------------------------- /docs/src/docs/YAxis/examples/YAxisCustomTicks.js.example: -------------------------------------------------------------------------------- 1 | const YAxisCustomTicksExample = (props) => { 2 | const size = {width: 150, height: 300}; 3 | 4 | return
5 | 6 | 7 | 8 |
9 | }; 10 | 11 | ReactDOM.render(, mountNode); 12 | -------------------------------------------------------------------------------- /docs/src/docs/YAxisLabels/YAxisLabelsDocs.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ComponentDocs from '../../ComponentDocs'; 3 | import ExampleSection from '../../ExampleSection'; 4 | // autogenerated docs data containing descriptions of this component's props 5 | import propDocs from './propDocs.json'; 6 | 7 | const examples = [ 8 | { 9 | id: 'basic', 10 | label: 'Basic YAxisLabels', 11 | codeText: require('./examples/YAxisLabels.js.example').default, 12 | }, 13 | ]; 14 | 15 | export default class YAxisLabelsExamples extends React.Component { 16 | render() { 17 | return ( 18 | 19 | {/* documentation goes here. intersperse docs with examples or leave examples loop below */} 20 | 21 | {examples.map(example => { 22 | return ; 23 | })} 24 | 25 | ); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /docs/src/docs/YAxisLabels/examples/YAxisLabels.js.example: -------------------------------------------------------------------------------- 1 | const YAxisLabelsExample = (props) => { 2 | const chartStyle = {marginBottom: '10px'}; 3 | 4 | return
5 |
6 | 10 | 13 | label + "%"} 15 | position="right" 16 | tickCount={5} 17 | labelStyle={(label) => { 18 | const is20 = Math.abs(label.value) === 20; 19 | return { 20 | fill: is20 ? "green" : "black", 21 | fontWeight: is20 ? 900 : 400 22 | }; 23 | }} 24 | /> 25 | 26 |
27 |
28 | }; 29 | 30 | ReactDOM.render(, mountNode); 31 | -------------------------------------------------------------------------------- /docs/src/docs/YAxisTitle/YAxisTitleDocs.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ComponentDocs from '../../ComponentDocs'; 3 | import ExampleSection from '../../ExampleSection'; 4 | // autogenerated docs data containing descriptions of this component's props 5 | import propDocs from './propDocs.json'; 6 | 7 | const examples = [ 8 | { 9 | id: 'basic', 10 | label: 'Basic YAxisTitle', 11 | codeText: require('./examples/YAxisTitle.js.example').default, 12 | }, 13 | { 14 | id: 'all', 15 | label: 'YAxisTitle Positions and Placements', 16 | codeText: require('./examples/YAxisTitleAll.js.example').default, 17 | }, 18 | ]; 19 | 20 | export default class YAxisTitleExamples extends React.Component { 21 | render() { 22 | return ( 23 | 24 | {/* documentation goes here. intersperse docs with examples or leave examples loop below */} 25 | 26 | {examples.map(example => { 27 | return ; 28 | })} 29 | 30 | ); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /docs/src/docs/YAxisTitle/examples/YAxisTitle.js.example: -------------------------------------------------------------------------------- 1 | const YAxisTitleExample = (props) => { 2 | const xyProps = { 3 | width: 400, height: 300, 4 | xDomain: [0, 100], yDomain: [0, 100] 5 | }; 6 | 7 | return 8 | 9 | ; 10 | }; 11 | 12 | ReactDOM.render(, mountNode); 13 | -------------------------------------------------------------------------------- /docs/src/docs/YAxisTitle/examples/YAxisTitleAll.js.example: -------------------------------------------------------------------------------- 1 | const YAxisTitleExample = (props) => { 2 | const xyProps = { 3 | width: 500, height: 360, 4 | xDomain: [0, 100], yDomain: [0, 100] 5 | }; 6 | 7 | return 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | ; 43 | }; 44 | 45 | ReactDOM.render(, mountNode); 46 | -------------------------------------------------------------------------------- /docs/src/docs/YGrid/YGridDocs.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ComponentDocs from '../../ComponentDocs'; 3 | import ExampleSection from '../../ExampleSection'; 4 | // autogenerated docs data containing descriptions of this component's props 5 | import propDocs from './propDocs.json'; 6 | 7 | const examples = [ 8 | { 9 | id: 'basic', 10 | label: 'Basic YGrid', 11 | codeText: require('./examples/YGrid.js.example').default, 12 | }, 13 | ]; 14 | 15 | export default class YGridExamples extends React.Component { 16 | render() { 17 | return ( 18 | 19 | {/* documentation goes here. intersperse docs with examples or leave examples loop below */} 20 | 21 | {examples.map(example => { 22 | return ; 23 | })} 24 | 25 | ); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /docs/src/docs/YGrid/examples/YGrid.js.example: -------------------------------------------------------------------------------- 1 | const YGridExample = (props) => { 2 | const size = {width: 400, height: 300}; 3 | 4 | return
5 | 6 | 7 | 8 | 9 |
10 | }; 11 | 12 | ReactDOM.render(, mountNode); 13 | -------------------------------------------------------------------------------- /docs/src/docs/YGrid/propDocs.json: -------------------------------------------------------------------------------- 1 | { 2 | "description": "", 3 | "displayName": "YGrid", 4 | "methods": [ 5 | { 6 | "name": "getTickDomain", 7 | "docblock": null, 8 | "modifiers": ["static"], 9 | "params": [ 10 | { 11 | "name": "props", 12 | "type": null 13 | } 14 | ], 15 | "returns": null 16 | } 17 | ], 18 | "props": { 19 | "width": { 20 | "type": { 21 | "name": "number" 22 | }, 23 | "required": false, 24 | "description": "" 25 | }, 26 | "height": { 27 | "type": { 28 | "name": "number" 29 | }, 30 | "required": false, 31 | "description": "" 32 | }, 33 | "yScale": { 34 | "type": { 35 | "name": "func" 36 | }, 37 | "required": false, 38 | "description": "" 39 | }, 40 | "spacingTop": { 41 | "type": { 42 | "name": "number" 43 | }, 44 | "required": false, 45 | "description": "" 46 | }, 47 | "spacingBottom": { 48 | "type": { 49 | "name": "number" 50 | }, 51 | "required": false, 52 | "description": "" 53 | }, 54 | "spacingLeft": { 55 | "type": { 56 | "name": "number" 57 | }, 58 | "required": false, 59 | "description": "" 60 | }, 61 | "spacingRight": { 62 | "type": { 63 | "name": "number" 64 | }, 65 | "required": false, 66 | "description": "" 67 | }, 68 | "nice": { 69 | "type": { 70 | "name": "bool" 71 | }, 72 | "required": false, 73 | "description": "", 74 | "defaultValue": { 75 | "value": "true", 76 | "computed": false 77 | } 78 | }, 79 | "ticks": { 80 | "type": { 81 | "name": "array" 82 | }, 83 | "required": false, 84 | "description": "" 85 | }, 86 | "tickCount": { 87 | "type": { 88 | "name": "number" 89 | }, 90 | "required": false, 91 | "description": "" 92 | }, 93 | "lineClassName": { 94 | "type": { 95 | "name": "string" 96 | }, 97 | "required": false, 98 | "description": "" 99 | }, 100 | "lineStyle": { 101 | "type": { 102 | "name": "object" 103 | }, 104 | "required": false, 105 | "description": "", 106 | "defaultValue": { 107 | "value": "{}", 108 | "computed": false 109 | } 110 | } 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /docs/src/docs/YLine/YLineDocs.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ComponentDocs from '../../ComponentDocs'; 3 | import ExampleSection from '../../ExampleSection'; 4 | // autogenerated docs data containing descriptions of this component's props 5 | import propDocs from './propDocs.json'; 6 | 7 | const examples = [ 8 | { 9 | id: 'basic', 10 | label: 'Basic YLine', 11 | codeText: require('./examples/YLine.js.example').default, 12 | }, 13 | ]; 14 | 15 | export default class YLineExamples extends React.Component { 16 | render() { 17 | return ( 18 | 19 | {/* documentation goes here. intersperse docs with examples or leave examples loop below */} 20 | 21 | {examples.map(example => { 22 | return ; 23 | })} 24 | 25 | ); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /docs/src/docs/YLine/examples/YLine.js.example: -------------------------------------------------------------------------------- 1 | const YLineExample = (props) => { 2 | return
3 | 4 | 5 | 6 | 7 | 8 |
9 | }; 10 | 11 | ReactDOM.render(, mountNode); 12 | -------------------------------------------------------------------------------- /docs/src/docs/YLine/propDocs.json: -------------------------------------------------------------------------------- 1 | { 2 | "description": "`YLine` is a horizontal line rendered on the y axis", 3 | "displayName": "YLine", 4 | "methods": [], 5 | "props": { 6 | "yScale": { 7 | "type": { 8 | "name": "func" 9 | }, 10 | "required": false, 11 | "description": "D3 scale for Y axis - provided by XYPlot" 12 | }, 13 | "width": { 14 | "type": { 15 | "name": "number" 16 | }, 17 | "required": false, 18 | "description": "Width of chart - provided by XYPlot." 19 | }, 20 | "value": { 21 | "type": { 22 | "name": "union", 23 | "value": [ 24 | { 25 | "name": "number" 26 | }, 27 | { 28 | "name": "string" 29 | }, 30 | { 31 | "name": "instanceOf", 32 | "value": "Date" 33 | } 34 | ] 35 | }, 36 | "required": true, 37 | "description": "" 38 | }, 39 | "xScale": { 40 | "type": { 41 | "name": "func" 42 | }, 43 | "required": false, 44 | "description": "D3 scale for X axis - provided by XYPlot" 45 | }, 46 | "xLimit": { 47 | "type": { 48 | "name": "union", 49 | "value": [ 50 | { 51 | "name": "number" 52 | }, 53 | { 54 | "name": "string" 55 | }, 56 | { 57 | "name": "instanceOf", 58 | "value": "Date" 59 | } 60 | ] 61 | }, 62 | "required": false, 63 | "description": "" 64 | }, 65 | "spacingLeft": { 66 | "type": { 67 | "name": "number" 68 | }, 69 | "required": false, 70 | "description": "Spacing left - provided by XYPlot", 71 | "defaultValue": { 72 | "value": "0", 73 | "computed": false 74 | } 75 | }, 76 | "spacingRight": { 77 | "type": { 78 | "name": "number" 79 | }, 80 | "required": false, 81 | "description": "Spacing right - provided by XYPlot", 82 | "defaultValue": { 83 | "value": "0", 84 | "computed": false 85 | } 86 | }, 87 | "style": { 88 | "type": { 89 | "name": "object" 90 | }, 91 | "required": false, 92 | "description": "Inline style object to be applied to the line", 93 | "defaultValue": { 94 | "value": "{}", 95 | "computed": false 96 | } 97 | }, 98 | "className": { 99 | "type": { 100 | "name": "string" 101 | }, 102 | "required": false, 103 | "description": "Class attribute to be applied to the line", 104 | "defaultValue": { 105 | "value": "''", 106 | "computed": false 107 | } 108 | } 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /docs/src/docs/YTicks/YTicksDocs.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ComponentDocs from '../../ComponentDocs'; 3 | import ExampleSection from '../../ExampleSection'; 4 | // autogenerated docs data containing descriptions of this component's props 5 | import propDocs from './propDocs.json'; 6 | 7 | const examples = [ 8 | { 9 | id: 'basic', 10 | label: 'Basic YTicks', 11 | codeText: require('./examples/YTicks.js.example').default, 12 | }, 13 | ]; 14 | 15 | export default class YTicksExamples extends React.Component { 16 | render() { 17 | return ( 18 | 19 | {/* documentation goes here. intersperse docs with examples or leave examples loop below */} 20 | 21 | {examples.map(example => { 22 | return ; 23 | })} 24 | 25 | ); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /docs/src/docs/YTicks/examples/YTicks.js.example: -------------------------------------------------------------------------------- 1 | const YTicksExample = (props) => { 2 | const size = {width: 100, height: 300}; 3 | const chartStyle = {display: 'inline-block', marginRight: '10px'}; 4 | 5 | return
6 |
7 | Left: default params
8 | Right: Multiple sets of ticks, with options 9 |
10 |
11 | 12 | 13 | 14 |
15 |
16 | 17 | 18 | 19 | 20 | 21 |
22 |
23 | }; 24 | 25 | 26 | ReactDOM.render(, mountNode); 27 | -------------------------------------------------------------------------------- /docs/src/docs/ZoomContainer/ZoomContainerDocs.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ComponentDocs from '../../ComponentDocs'; 3 | import ExampleSection from '../../ExampleSection'; 4 | // autogenerated docs data containing descriptions of this component's props 5 | import propDocs from './propDocs.json'; 6 | 7 | const examples = [ 8 | { 9 | id: 'basic', 10 | label: 'Basic ZoomContainer', 11 | codeText: require('./examples/ZoomContainer.js.example').default, 12 | }, 13 | { 14 | id: 'controlled', 15 | label: 'Controlled ZoomContainer', 16 | codeText: require('./examples/ZoomContainerControlled.js.example').default, 17 | }, 18 | ]; 19 | 20 | export default class ZoomContainerExamples extends React.Component { 21 | render() { 22 | return ( 23 | 24 | {/* documentation goes here. intersperse docs with examples or leave examples loop below */} 25 | 26 | {examples.map(example => { 27 | return ; 28 | })} 29 | 30 | ); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /docs/src/docs/ZoomContainer/examples/ZoomContainer.js.example: -------------------------------------------------------------------------------- 1 | const ZoomContainerExample = (props) => { 2 | return
3 | 4 | 5 | 6 | 7 | d} 10 | y={d => Math.sin(d*.1)} 11 | /> 12 | 13 | 14 |
15 | }; 16 | 17 | ReactDOM.render(, mountNode); 18 | -------------------------------------------------------------------------------- /docs/src/docs/ZoomContainer/examples/ZoomContainerControlled.js.example: -------------------------------------------------------------------------------- 1 | const width = 600; 2 | const height = 350; 3 | 4 | function getNewZoomProps(newZoomScale, oldZoomScale, oldZoomX, oldZoomY, width, height) { 5 | // Some math is required here in order to ensure that whatever is in the center of the viewport 6 | // remains in the center of the viewport after zooming in/out. 7 | // It's possible to only update zoomScale (and not zoomX & zoomY), but doing so will zoom relative to the 8 | // top left corner of the chart, rather than viewport center. 9 | 10 | return { 11 | zoomX: width / 2 - newZoomScale / oldZoomScale * (width / 2 - oldZoomX), 12 | zoomY: height / 2 - newZoomScale / oldZoomScale * (height / 2 - oldZoomY), 13 | zoomScale: newZoomScale 14 | }; 15 | } 16 | 17 | class ZoomControlledExample extends React.Component { 18 | state = { 19 | zoomTransform: {k: 1, x: 0, y: 0}, 20 | zoomX: 0, 21 | zoomY: 0, 22 | zoomScale: 1 23 | }; 24 | 25 | handleZoom = nextZoomTransform => { 26 | // callback called when user has zoomed (or panned) 27 | // pass the new zoom transform from callback back down as props 28 | if (!nextZoomTransform) return; 29 | this.setState({ 30 | zoomX: nextZoomTransform.x, 31 | zoomY: nextZoomTransform.y, 32 | zoomScale: nextZoomTransform.k 33 | }); 34 | }; 35 | handleClickZoomIn = () => { 36 | const {zoomScale, zoomX, zoomY} = this.state; 37 | const newZoomScale = this.state.zoomScale * 1.25; 38 | this.setState(getNewZoomProps(newZoomScale, zoomScale, zoomX, zoomY, width, height)); 39 | }; 40 | handleClickZoomOut = () => { 41 | const {zoomScale, zoomX, zoomY} = this.state; 42 | const newZoomScale = this.state.zoomScale / 1.25; 43 | this.setState(getNewZoomProps(newZoomScale, zoomScale, zoomX, zoomY, width, height)); 44 | }; 45 | 46 | render() { 47 | return ( 48 |
49 | 59 | 60 | 61 | 62 | d} y={d => Math.sin(d * 0.1)} /> 63 | 64 | 65 |
66 | 67 | 68 |
69 |
70 | ); 71 | } 72 | } 73 | 74 | ReactDOM.render(, mountNode); 75 | -------------------------------------------------------------------------------- /docs/src/docs/index.js: -------------------------------------------------------------------------------- 1 | export { default as AreaBarChartDocs } from './AreaBarChart/AreaBarChartDocs'; 2 | export { default as AreaChartDocs } from './AreaChart/AreaChartDocs'; 3 | export { default as AreaHeatmapDocs } from './AreaHeatmap/AreaHeatmapDocs'; 4 | export { 5 | default as AriaLabelContainerDocs, 6 | } from './AriaLabelContainer/AriaLabelContainerDocs'; 7 | export { default as BarDocs } from './Bar/BarDocs'; 8 | export { default as BarChartDocs } from './BarChart/BarChartDocs'; 9 | export { default as ColorHeatmapDocs } from './ColorHeatmap/ColorHeatmapDocs'; 10 | export { default as FunnelChartDocs } from './FunnelChart/FunnelChartDocs'; 11 | export { default as HistogramDocs } from './Histogram/HistogramDocs'; 12 | export { 13 | default as KernelDensityEstimationDocs, 14 | } from './KernelDensityEstimation/KernelDensityEstimationDocs'; 15 | export { default as LineChartDocs } from './LineChart/LineChartDocs'; 16 | export { 17 | default as MarkerLineChartDocs, 18 | } from './MarkerLineChart/MarkerLineChartDocs'; 19 | export { 20 | default as MeasuredValueLabelDocs, 21 | } from './MeasuredValueLabel/MeasuredValueLabelDocs'; 22 | export { default as PieChartDocs } from './PieChart/PieChartDocs'; 23 | export { 24 | default as RangeBarChartDocs, 25 | } from './RangeBarChart/RangeBarChartDocs'; 26 | export { default as RangeRectDocs } from './RangeRect/RangeRectDocs'; 27 | export { 28 | default as SankeyDiagramDocs, 29 | } from './SankeyDiagram/SankeyDiagramDocs'; 30 | export { default as ScatterPlotDocs } from './ScatterPlot/ScatterPlotDocs'; 31 | export { default as TreeMapDocs } from './TreeMap/TreeMapDocs'; 32 | export { default as XAxisDocs } from './XAxis/XAxisDocs'; 33 | export { default as XAxisLabelsDocs } from './XAxisLabels/XAxisLabelsDocs'; 34 | export { default as XAxisTitleDocs } from './XAxisTitle/XAxisTitleDocs'; 35 | export { default as XGridDocs } from './XGrid/XGridDocs'; 36 | export { default as XLineDocs } from './XLine/XLineDocs'; 37 | export { default as XTicksDocs } from './XTicks/XTicksDocs'; 38 | export { default as XYPlotDocs } from './XYPlot/XYPlotDocs'; 39 | export { default as YAxisDocs } from './YAxis/YAxisDocs'; 40 | export { default as YAxisLabelsDocs } from './YAxisLabels/YAxisLabelsDocs'; 41 | export { default as YAxisTitleDocs } from './YAxisTitle/YAxisTitleDocs'; 42 | export { default as YGridDocs } from './YGrid/YGridDocs'; 43 | export { default as YLineDocs } from './YLine/YLineDocs'; 44 | export { default as YTicksDocs } from './YTicks/YTicksDocs'; 45 | export { 46 | default as ZoomContainerDocs, 47 | } from './ZoomContainer/ZoomContainerDocs'; 48 | -------------------------------------------------------------------------------- /docs/src/index_html.ejs: -------------------------------------------------------------------------------- 1 | 5 | 6 | 7 | 8 | 9 | <%= htmlWebpackPlugin.options.title %> 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 32 | 33 |
Loading...
34 | 35 | -------------------------------------------------------------------------------- /docs/src/lessons/GettersAndAccessors/examples/GettersAndAccessors.js.example: -------------------------------------------------------------------------------- 1 | const GettersAndAccessorsExample = (props) => { 2 | // sample data in a few different shapes 3 | const arrData = [ 4 | [0, 4], [5, 20], [10, 13], [15, 19] 5 | ]; 6 | const objData = [ 7 | {count: 4, friends: [{id: 'a', age: 24}, {id: 'b', age: 19}]}, 8 | {count: 7, friends: [{id: 'a', age: 28}, {id: 'b', age: 29}]}, 9 | {count: 19, friends: [{id: 'a', age: 22}, {id: 'b', age: 44}]}, 10 | {count: 22, friends: [{id: 'a', age: 41}, {id: 'b', age: 22}]}, 11 | ]; 12 | 13 | return 14 | 15 | 16 | {/* array getters: line X is d[0] and line Y is d[1] */} 17 | 22 | {/* use strings for deep object access */} 23 | 29 | {/* or use functions if you prefer */} 30 | d.count} 33 | getY={(d) => d.friends[1].age} 34 | lineStyle={{stroke: 'purple'}} 35 | /> 36 | 37 | }; 38 | 39 | 40 | ReactDOM.render(, mountNode); 41 | -------------------------------------------------------------------------------- /docs/src/lessons/GettersAndAccessors/examples/GraphingCalculator.js.example: -------------------------------------------------------------------------------- 1 | const GraphingCalculatorExample = (props) => { 2 | // generate an array of numbers using _.range 3 | // returns [0, 1, 2, 3, ..., 99] 4 | const data = _.range(100); 5 | 6 | return 7 | 8 | 9 | Math.sin(d*0.1)} 15 | /> 16 | 17 | }; 18 | 19 | 20 | ReactDOM.render(, mountNode); 21 | -------------------------------------------------------------------------------- /docs/src/lessons/Interaction/InteractionLesson.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import Lesson from '../../Lesson'; 3 | import ExampleSection from '../../ExampleSection'; 4 | 5 | const examples = [ 6 | { 7 | id: 'basic', 8 | label: 'Interaction Example', 9 | codeText: require('./examples/Interaction.js.example').default, 10 | }, 11 | ]; 12 | 13 | export default class InteractionLesson extends React.Component { 14 | render() { 15 | return ( 16 | 17 | {/* Interaction lesson goes here. intersperse with examples or leave examples loop below */} 18 | 19 | {examples.map(example => { 20 | return ; 21 | })} 22 | 23 | ); 24 | } 25 | } 26 | 27 | // todo: flesh out this lesson and re-do this example: 28 | 29 | const CustomSelectionRect = () => { 30 | const { scale, hoveredYVal } = this.props; 31 | return hoveredYVal ? ( 32 | 39 | ) : null; 40 | }; 41 | 42 | class CustomChildExample extends React.Component { 43 | state = { 44 | hoveredYVal: null, 45 | }; 46 | 47 | onMouseMoveChart = ({ yValue }) => { 48 | this.setState({ hoveredYVal: yValue }); 49 | }; 50 | 51 | render() { 52 | return ( 53 |
54 | 60 | 61 | 62 | 63 | 64 | 65 |
66 | ); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /docs/src/lessons/Interaction/examples/Interaction.js.example: -------------------------------------------------------------------------------- 1 | // const InteractionExample = React.createClass({ 2 | class InteractionExample extends React.Component { 3 | getInitialState() { 4 | return { 5 | activeValue: null 6 | } 7 | } 8 | onEnterBar(e, d) { 9 | this.setState({activeValue: d}); 10 | } 11 | onLeaveBar(e, d) { 12 | this.setState({activeValue: null}) 13 | } 14 | render() { 15 | const {activeValue} = this.state; 16 | 17 | return
18 | {_.isNumber(activeValue) ? 19 |
20 | {activeValue.toFixed(2)} 21 |
: 22 |
Hover over the chart to show values
23 | } 24 | 25 | 26 | Math.sin(d / 10) * 10} 29 | getXEnd={d => Math.sin((d + 1) / 10) * 10} 30 | getY={d => Math.cos(d / (Math.PI))} 31 | onMouseEnterBar={this.onEnterBar} 32 | onMouseLeaveBar={this.onLeaveBar} 33 | /> 34 | ; 35 |
36 | } 37 | } 38 | 39 | ReactDOM.render(, mountNode); 40 | -------------------------------------------------------------------------------- /docs/src/lessons/QuickStart/QuickStartLesson.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import Lesson from '../../Lesson'; 3 | import ExampleSection from '../../ExampleSection'; 4 | 5 | const examples = [ 6 | { 7 | id: 'basic', 8 | label: 'Quick Start Example', 9 | codeText: require('./examples/QuickStart.js.example').default, 10 | }, 11 | ]; 12 | 13 | export default class QuickStartLesson extends React.Component { 14 | render() { 15 | return ( 16 | 17 |

18 | To get started using Reactochart, first install it using{' '} 19 | npm: 20 |

21 |
npm install --save reactochart
22 |

23 | Then you can import individual Reactochart components: 24 |

25 |
import LineChart from 'reactochart/LineChart'
26 |

27 | The examples in this documentation will omit these imports to save 28 | space, so make sure you remember to include them in your code to get 29 | things working. For example, the example below requires importing the 30 | following components: 31 |

32 |
33 |           import XYPlot from 'reactochart/XYPlot';
34 |           
35 | import XAxis from 'reactochart/XAxis'; 36 |
37 | import YAxis from 'reactochart/YAxis'; 38 |
39 | import LineChart from 'reactochart/LineChart'; 40 |
41 |

42 | If you prefer, you can import all of Reactochart at once, though this 43 | may hinder some optimizations, such as webpack{' '} 44 | tree-shaking: 45 |

46 |
47 |           import {'{'}XYPlot, XAxis, YAxis, LineChart{'}'} from 'reactochart';
48 |           
49 | // or
50 | import * as Reactochart from 'reactochart'; 51 |
52 |

53 | And now, here's our first line chart showing the basic usage of these 54 | components. In this and all future examples, the code on the left side 55 | is editable and will update the preview on the right - so experiment 56 | and see for yourself how things work! 57 |

58 | 59 | {examples.map(example => { 60 | return ; 61 | })} 62 |
63 | ); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /docs/src/lessons/QuickStart/examples/QuickStart.js.example: -------------------------------------------------------------------------------- 1 | const QuickStartExample = (props) => { 2 | return 3 | 4 | 5 | d.x} 13 | y={d => d.y} 14 | /> 15 | 16 | }; 17 | 18 | ReactDOM.render(, mountNode); 19 | -------------------------------------------------------------------------------- /docs/src/lessons/XYPlots/examples/LineChart.js.example: -------------------------------------------------------------------------------- 1 | const XYLineChartExample = (props) => { 2 | const data = [ 3 | {x: 0, y: 20}, 4 | {x: 5, y: 30}, 5 | {x: 10, y: 35}, 6 | {x: 15, y: 30}, 7 | ]; 8 | return 9 | d.x} 12 | y={d => d.y} 13 | /> 14 | 15 | }; 16 | 17 | ReactDOM.render(, mountNode); 18 | -------------------------------------------------------------------------------- /docs/src/lessons/XYPlots/examples/LineChartWithAxis.js.example: -------------------------------------------------------------------------------- 1 | const XYLineChartExample = (props) => { 2 | const data = [ 3 | {x: 0, y: 2}, 4 | {x: 5, y: 22}, 5 | {x: 10, y: 32}, 6 | {x: 15, y: 36}, 7 | ]; 8 | return 9 | 10 | 11 | d.x} 14 | y={d => d.y} 15 | /> 16 | 17 | }; 18 | 19 | ReactDOM.render(, mountNode); 20 | -------------------------------------------------------------------------------- /docs/src/lessons/XYPlots/examples/MultiChart.js.example: -------------------------------------------------------------------------------- 1 | const MultiChartExample = (props) => { 2 | const data = [ 3 | {x: 0, y: 2, z: 3}, 4 | {x: 5, y: 22, z: 12}, 5 | {x: 10, y: 32, z: 15}, 6 | {x: 15, y: 36, z: 25}, 7 | ]; 8 | return 9 | 10 | 11 | d.x} 14 | y={d => d.y} 15 | barThickness={35} 16 | barStyle={{fill: '#888'}} 17 | /> 18 | d.x} 21 | y={d => d.y} 22 | lineStyle={{stroke: 'royalblue', strokeWidth: 5}} 23 | /> 24 | d.x} 27 | y={d => d.z} 28 | lineStyle={{stroke: 'coral', strokeWidth: 3}} 29 | /> 30 | 31 | }; 32 | 33 | ReactDOM.render(, mountNode); 34 | -------------------------------------------------------------------------------- /docs/src/lessons/index.js: -------------------------------------------------------------------------------- 1 | export { default as QuickStartLesson } from "./QuickStart/QuickStartLesson"; 2 | export { default as XYPlotsLesson } from "./XYPlots/XYPlotsLesson"; 3 | export { 4 | default as GettersAndAccessorsLesson 5 | } from "./GettersAndAccessors/GettersAndAccessorsLesson"; 6 | export { default as InteractionLesson } from "./Interaction/InteractionLesson"; 7 | -------------------------------------------------------------------------------- /docs/src/main.js: -------------------------------------------------------------------------------- 1 | import '../styles/main.less'; 2 | import React from 'react'; 3 | import ReactDOM from 'react-dom'; 4 | import { App } from './App'; 5 | 6 | ReactDOM.render(, document.getElementById('container')); 7 | -------------------------------------------------------------------------------- /docs/src/templates/ComponentDocsPage.js.template: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import ComponentDocs from '../../ComponentDocs'; 4 | import ExampleSection from '../../ExampleSection'; 5 | // autogenerated docs data containing descriptions of this component's props 6 | import propDocs from './propDocs.json'; 7 | 8 | const examples = [ 9 | { 10 | id: "basic", 11 | label: "Basic ${componentName}", 12 | codeText: require('./examples/${componentName}.js.example').default, 13 | }, 14 | ]; 15 | 16 | export default class ${componentName}Examples extends React.Component { 17 | render() { 18 | return 19 | 20 | {/* documentation goes here. intersperse docs with examples or leave examples loop below */} 21 | 22 | {examples.map(example => { 23 | return ; 24 | })} 25 | ; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /docs/src/templates/ComponentExample.js.template: -------------------------------------------------------------------------------- 1 | const ${componentName}Example = (props) => { 2 | return
insert example here
; 3 | }; 4 | 5 | ReactDOM.render(<${componentName}Example />, mountNode); 6 | -------------------------------------------------------------------------------- /docs/src/templates/Lesson.js.template: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import Lesson from '../../Lesson'; 4 | import ExampleSection from '../../ExampleSection'; 5 | 6 | const examples = [ 7 | { 8 | id: "basic", 9 | label: "${name} Example", 10 | codeText: require('./examples/${componentName}.js.example').default, 11 | }, 12 | ]; 13 | 14 | export default class ${componentName}Lesson extends React.Component { 15 | render() { 16 | return 17 | 18 | {/* ${name} lesson goes here. intersperse with examples or leave examples loop below */} 19 | 20 | {examples.map(example => { 21 | return ; 22 | })} 23 | ; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /docs/styles/main.less: -------------------------------------------------------------------------------- 1 | @import "../../styles/charts.less"; 2 | 3 | body { 4 | //font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; 5 | //margin: 0; 6 | //padding: 0; 7 | //background: #f0f0f0; 8 | //color: #0f0f0f; 9 | 10 | #container { 11 | //margin: 10px; 12 | } 13 | } 14 | 15 | .sidebar-nav { 16 | h1, 17 | h2, 18 | h3, 19 | h4, 20 | h5, 21 | h6 { 22 | color: #f8f8f8; 23 | text-transform: uppercase; 24 | } 25 | h3 { 26 | font-size: 16px; 27 | } 28 | h4 { 29 | font-size: 14px; 30 | } 31 | } 32 | 33 | .example { 34 | margin-bottom: 2em; 35 | } 36 | 37 | .component-docs { 38 | padding: 0 30px; 39 | } 40 | .prop-docs { 41 | background-color: #efefef; 42 | padding: 15px; 43 | 44 | .prop-description, 45 | .prop-default { 46 | display: block; 47 | margin-left: 2em; 48 | font-size: 0.85em; 49 | } 50 | } 51 | 52 | .example-section { 53 | display: inline-block; 54 | margin: 10px; 55 | 56 | &.example-section-visible { 57 | display: block; 58 | } 59 | 60 | .example-section-button { 61 | display: inline-block; 62 | //margin: 10px; 63 | padding: 10px 20px; 64 | font-size: 20pt; 65 | font-weight: bold; 66 | background: #cccccc; 67 | cursor: pointer; 68 | border-radius: 5px; 69 | 70 | .example-arrow { 71 | color: #888; 72 | } 73 | &.active { 74 | background-color: #4cba6f; 75 | .example-arrow { 76 | color: #0f0f0f; 77 | } 78 | } 79 | } 80 | 81 | .example-section-content { 82 | margin: 10px 20px; 83 | } 84 | } 85 | 86 | .playground { 87 | display: flex; 88 | flex-wrap: wrap; 89 | 90 | .playgroundCode, 91 | .playgroundPreview { 92 | border: 1px solid #efefef; 93 | border-radius: 3px; 94 | flex-basis: 150px; 95 | 96 | &:before { 97 | display: block; 98 | text-align: center; 99 | color: #616467; 100 | background-color: #f8f8f8; 101 | border-bottom: 1px solid #efefef; 102 | text-transform: uppercase; 103 | letter-spacing: 1px; 104 | font-size: 14px; 105 | line-height: 28px; 106 | } 107 | } 108 | 109 | .playgroundCode { 110 | margin-right: 8px; 111 | flex-grow: 0.6; 112 | 113 | &:before { 114 | content: "Editable Source"; 115 | } 116 | .CodeMirror { 117 | font-size: 10pt; 118 | font-family: Consolas, Monaco, "Andale Mono", "Ubuntu Mono", monospace; 119 | } 120 | } 121 | 122 | .playgroundPreview { 123 | margin-left: 8px; 124 | //text-align: center; 125 | flex-grow: 0.4; 126 | 127 | &:before { 128 | content: "Live Preview"; 129 | } 130 | .previewArea { 131 | padding: 8px 6px; 132 | } 133 | } 134 | } 135 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Redirect 4 | 5 | 6 | 7 | Redirecting to docs... 8 | 9 | 10 | -------------------------------------------------------------------------------- /jest.config.js: -------------------------------------------------------------------------------- 1 | const dontTranspiledThese = ['internmap', 'delaunator', 'robust-predicates']; 2 | const dontTranspile = dontTranspiledThese.join('|'); 3 | 4 | const config = { 5 | collectCoverage: true, 6 | collectCoverageFrom: ['src/**/*.js'], 7 | setupFiles: ['/tests/jsdom/setup.js'], 8 | setupFilesAfterEnv: ['./node_modules/jest-enzyme/lib/index.js'], 9 | transformIgnorePatterns: [ 10 | `[/\\\\]node_modules[/\\\\]((?!(?<=[/\\\\])(d3-?|${dontTranspile})).)+\\.(js|jsx|ts|tsx)$`, 11 | ], 12 | }; 13 | 14 | module.exports = config; 15 | -------------------------------------------------------------------------------- /prettier.config.js: -------------------------------------------------------------------------------- 1 | module.exports = require('@spotify/web-scripts/config/prettier.config'); 2 | -------------------------------------------------------------------------------- /scripts/clean.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs'); 2 | const sh = require('shelljs'); 3 | 4 | const { fileExists, dirExists } = require('./utils'); 5 | 6 | const srcContents = sh.ls('src'); 7 | 8 | // We don't want to commit built files, so it is useful to have a `clean` script which deletes them if they exist. 9 | // However, Reactochart is built in the root directory 10 | // (so that modules may be required with eg. `require('reactochart/LineChart')`). 11 | // This makes cleanup harder than simply deleting a `build` directory. 12 | // Instead this looks for any files in the root directory which match the name of a file in the `src` directory, 13 | // and deletes them if they exist. 14 | // Sounds dangerous, but any files in root which share a name with src would have been overwritten by the build anyway. 15 | 16 | srcContents.forEach(fileOrDir => { 17 | if (fileExists(`src/${fileOrDir}`) && fileExists(`./${fileOrDir}`)) { 18 | console.log(`deleting file ./${fileOrDir}`); 19 | sh.rm(`./${fileOrDir}`); 20 | } else if (dirExists(`src/${fileOrDir}`) && dirExists(fileOrDir)) { 21 | console.log(`deleting directory ./${fileOrDir}`); 22 | sh.rm('-rf', `./${fileOrDir}`); 23 | } 24 | // check for source maps too 25 | if (fileExists(`./${fileOrDir}.map`)) { 26 | console.log(`deleting file ./${fileOrDir}.map`); 27 | sh.rm(`./${fileOrDir}.map`); 28 | } 29 | }); 30 | 31 | // Clean compiled css file 32 | if (fileExists('./styles.css')) { 33 | sh.rm('./styles.css'); 34 | } 35 | -------------------------------------------------------------------------------- /scripts/makeLesson.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs'); 2 | const sh = require('shelljs'); 3 | const _ = require('lodash'); 4 | 5 | const { 6 | isUpperCase, 7 | fileExists, 8 | dirExists, 9 | ensureDir, 10 | fileNameFromPath, 11 | stripFileExtension, 12 | } = require('./utils'); 13 | 14 | const lessonsDirPath = `${__dirname}/../docs/src/lessons`; 15 | const lessonTemplatePath = `${__dirname}/../docs/src/templates/Lesson.js.template`; 16 | const exampleTemplatePath = `${__dirname}/../docs/src/templates/ComponentExample.js.template`; 17 | 18 | if (process.argv.length <= 2) { 19 | console.log(`Usage: ${__filename} LESSON_NAME`); 20 | process.exit(-1); 21 | } 22 | 23 | const lessonName = process.argv[2]; 24 | console.log(lessonName); 25 | 26 | const componentName = lessonName 27 | .split(' ') 28 | .map(_.capitalize) 29 | .join(''); 30 | console.log('componentName', componentName); 31 | const lessonDirPath = `${lessonsDirPath}/${componentName}`; 32 | const lessonComponentPath = `${lessonDirPath}/${componentName}Lesson.js`; 33 | 34 | ensureDir(lessonsDirPath); 35 | ensureDir(lessonDirPath); 36 | if (!fileExists(lessonComponentPath)) { 37 | // use template file to generate a stub example page for this component 38 | const lessonTemplate = _.template(sh.cat(lessonTemplatePath).toString()); 39 | const lessonStub = lessonTemplate({ name: lessonName, componentName }); 40 | fs.writeFile(lessonComponentPath, lessonStub, err => { 41 | if (err) throw err; 42 | console.log('created stub lesson component:', lessonComponentPath); 43 | }); 44 | 45 | const examplesDirPath = `${lessonDirPath}/examples`; 46 | const examplePath = `${examplesDirPath}/${componentName}.js.example`; 47 | 48 | // use template to generate stub example file, to be used for live preview (using component-playground) 49 | const exampleTemplate = _.template(sh.cat(exampleTemplatePath).toString()); 50 | const exampleStub = exampleTemplate({ componentName }); 51 | ensureDir(examplesDirPath); 52 | fs.writeFile(examplePath, exampleStub, err => { 53 | if (err) throw err; 54 | console.log('created stub example:', examplePath); 55 | }); 56 | } 57 | -------------------------------------------------------------------------------- /scripts/utils.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs'); 2 | const sh = require('shelljs'); 3 | const _ = require('lodash'); 4 | 5 | function isUpperCase(letter) { 6 | return letter.toUpperCase() === letter; 7 | } 8 | function fileExists(path) { 9 | return sh.test('-f', path); 10 | } 11 | function dirExists(path) { 12 | return sh.test('-d', path); 13 | } 14 | function ensureDir(path) { 15 | if (!dirExists(path)) sh.mkdir('-p', path); 16 | } 17 | function fileNameFromPath(path) { 18 | return _.last(path.split('/')); 19 | } 20 | function stripFileExtension(fileName) { 21 | return _.dropRight(fileName.split('.')).join('.'); 22 | } 23 | 24 | module.exports = { 25 | isUpperCase, 26 | fileExists, 27 | dirExists, 28 | ensureDir, 29 | fileNameFromPath, 30 | stripFileExtension, 31 | }; 32 | -------------------------------------------------------------------------------- /src/MeasuredValueLabel.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import defaults from 'lodash/defaults'; 3 | import omit from 'lodash/omit'; 4 | import identity from 'lodash/identity'; 5 | import measureText from './utils/measureText'; 6 | import PropTypes from 'prop-types'; 7 | 8 | export default class MeasuredValueLabel extends React.Component { 9 | static propTypes = { 10 | value: PropTypes.any, 11 | format: PropTypes.func, 12 | children: PropTypes.any, 13 | }; 14 | 15 | static defaultProps = { 16 | format: identity, 17 | style: { 18 | fontFamily: 'Helvetica, sans-serif', 19 | fontSize: '20px', 20 | lineHeight: 1, 21 | textAnchor: 'middle', 22 | }, 23 | }; 24 | 25 | static getLabel(props) { 26 | const { value, format } = props; 27 | const style = defaults(props.style, MeasuredValueLabel.defaultProps.style); 28 | const labelStr = format(value); 29 | const labelWithStyle = Object.assign({ text: labelStr }, style); 30 | const measured = measureText(labelWithStyle); 31 | 32 | return { 33 | value: props.value, 34 | text: measured.text, 35 | height: measured.height.value, 36 | width: measured.width.value, 37 | }; 38 | } 39 | 40 | render() { 41 | const { value, format } = this.props; 42 | const passedProps = omit(this.props, ['value', 'format']); 43 | 44 | return ( 45 | 46 | {React.Children.count(this.props.children) 47 | ? this.props.children 48 | : format(value)} 49 | 50 | ); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/TreeMapNode.js: -------------------------------------------------------------------------------- 1 | import get from 'lodash/get'; 2 | import kebabCase from 'lodash/kebabCase'; 3 | import isFunction from 'lodash/isFunction'; 4 | import isObject from 'lodash/isObject'; 5 | 6 | import PropTypes from 'prop-types'; 7 | import React from 'react'; 8 | import * as CustomPropTypes from './utils/CustomPropTypes'; 9 | 10 | const TreeMapNode = props => { 11 | const { 12 | node, 13 | getLabel, 14 | nodeStyle, 15 | labelStyle, 16 | minLabelWidth, 17 | minLabelHeight, 18 | NodeLabelComponent, 19 | parentNames, 20 | } = props; 21 | const { depth, parent, x0, y0, x1, y1 } = node; 22 | 23 | const parentName = get(parent, 'data.name'); 24 | const nodeGroupClass = parent 25 | ? `node-group-${kebabCase(parentName)} node-group-i-${parentNames.indexOf( 26 | parentName, 27 | )}` 28 | : ''; 29 | const className = `rct-tree-map-node node-depth-${depth} ${nodeGroupClass}`; 30 | 31 | const style = { 32 | position: 'absolute', 33 | width: x1 - x0, 34 | height: y1 - y0, 35 | top: y0, 36 | left: x0, 37 | transition: 'all .2s', 38 | }; 39 | const customStyle = isFunction(nodeStyle) 40 | ? nodeStyle(node) 41 | : isObject(nodeStyle) 42 | ? nodeStyle 43 | : {}; 44 | Object.assign(style, customStyle); 45 | 46 | const handlers = [ 47 | 'onClick', 48 | 'onMouseEnter', 49 | 'onMouseLeave', 50 | 'onMouseMove', 51 | ].reduce((acc, eventName) => { 52 | const handler = props[`${eventName}Node`]; 53 | if (handler) acc[eventName] = handler.bind(null, node); 54 | return acc; 55 | }, {}); 56 | 57 | return ( 58 |
59 | {x1 - x0 > minLabelWidth && y1 - y0 > minLabelHeight ? ( // show label if node is big enough 60 | 61 | ) : null} 62 |
63 | ); 64 | }; 65 | 66 | TreeMapNode.propTypes = { 67 | node: PropTypes.shape({ 68 | parent: PropTypes.object, 69 | children: PropTypes.array, 70 | value: PropTypes.number, 71 | depth: PropTypes.number, 72 | x: PropTypes.number, 73 | y: PropTypes.number, 74 | dx: PropTypes.number, 75 | dy: PropTypes.number, 76 | x0: PropTypes.number, 77 | y0: PropTypes.number, 78 | x1: PropTypes.number, 79 | y1: PropTypes.number, 80 | }), 81 | nodeStyle: PropTypes.oneOfType([PropTypes.func, PropTypes.object]), 82 | minLabelWidth: PropTypes.number, 83 | minLabelHeight: PropTypes.number, 84 | getLabel: CustomPropTypes.getter, 85 | labelStyle: PropTypes.oneOfType([PropTypes.func, PropTypes.object]), 86 | NodeLabelComponent: PropTypes.func, 87 | parentNames: PropTypes.arrayOf(PropTypes.string), 88 | }; 89 | 90 | TreeMapNode.defaultProps = { 91 | minLabelWidth: 0, 92 | minLabelHeight: 0, 93 | }; 94 | 95 | export default TreeMapNode; 96 | -------------------------------------------------------------------------------- /src/TreeMapNodeLabel.js: -------------------------------------------------------------------------------- 1 | import isFunction from 'lodash/isFunction'; 2 | import isObject from 'lodash/isObject'; 3 | import PropTypes from 'prop-types'; 4 | import React from 'react'; 5 | import * as CustomPropTypes from './utils/CustomPropTypes'; 6 | import { makeAccessor } from './utils/Data'; 7 | 8 | const TreeMapNodeLabel = props => { 9 | const { node, getLabel, labelStyle } = props; 10 | const { x1, x0 } = node; 11 | const style = { width: x1 - x0 }; 12 | const customStyle = isFunction(labelStyle) 13 | ? labelStyle(node) 14 | : isObject(labelStyle) 15 | ? labelStyle 16 | : {}; 17 | Object.assign(style, customStyle); 18 | 19 | return ( 20 |
21 | {makeAccessor(getLabel)(node)} 22 |
23 | ); 24 | }; 25 | 26 | TreeMapNodeLabel.propTypes = { 27 | node: PropTypes.object, 28 | getLabel: CustomPropTypes.getter, 29 | labelStyle: PropTypes.oneOfType([PropTypes.func, PropTypes.object]), 30 | minLabelWidth: PropTypes.number, 31 | minLabelHeight: PropTypes.number, 32 | }; 33 | 34 | export default TreeMapNodeLabel; 35 | -------------------------------------------------------------------------------- /src/XGrid.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import defaults from 'lodash/defaults'; 3 | import PropTypes from 'prop-types'; 4 | 5 | import { getScaleTicks, getTickDomain } from './utils/Scale'; 6 | import XLine from './XLine'; 7 | 8 | export default class XGrid extends React.Component { 9 | static propTypes = { 10 | width: PropTypes.number, 11 | height: PropTypes.number, 12 | xScale: PropTypes.func, 13 | spacingTop: PropTypes.number, 14 | spacingBottom: PropTypes.number, 15 | spacingLeft: PropTypes.number, 16 | spacingRight: PropTypes.number, 17 | nice: PropTypes.bool, 18 | ticks: PropTypes.array, 19 | tickCount: PropTypes.number, 20 | lineClassName: PropTypes.string, 21 | lineStyle: PropTypes.object, 22 | }; 23 | static defaultProps = { 24 | nice: true, 25 | lineStyle: {}, 26 | }; 27 | 28 | static getTickDomain(props) { 29 | if (!props.xScale) return; 30 | const propsWithDefaults = defaults({}, props, XGrid.defaultProps); 31 | return { 32 | xTickDomain: getTickDomain(propsWithDefaults.xScale, propsWithDefaults), 33 | }; 34 | } 35 | 36 | render() { 37 | const { 38 | height, 39 | xScale, 40 | tickCount, 41 | lineClassName, 42 | lineStyle, 43 | spacingTop, 44 | spacingBottom, 45 | spacingLeft, 46 | spacingRight, 47 | } = this.props; 48 | const ticks = this.props.ticks || getScaleTicks(xScale, null, tickCount); 49 | const className = `rct-chart-grid-line ${lineClassName || ''}`; 50 | 51 | return ( 52 | 72 | ); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/XLine.js: -------------------------------------------------------------------------------- 1 | import PropTypes from 'prop-types'; 2 | import React from 'react'; 3 | 4 | /** 5 | * `XLine` is a vertical line rendered on the x axis 6 | */ 7 | export default class XLine extends React.Component { 8 | static propTypes = { 9 | /** 10 | * Height of chart - provided by XYPlot 11 | */ 12 | height: PropTypes.number, 13 | /** 14 | * D3 scale for X axis - provided by XYPlot 15 | */ 16 | xScale: PropTypes.func, 17 | value: PropTypes.oneOfType([ 18 | PropTypes.number, 19 | PropTypes.string, 20 | PropTypes.instanceOf(Date), 21 | ]).isRequired, 22 | /** 23 | * D3 scale for Y axis - provided by XYPlot 24 | */ 25 | yScale: PropTypes.func, 26 | yLimit: PropTypes.oneOfType([ 27 | PropTypes.number, 28 | PropTypes.string, 29 | PropTypes.instanceOf(Date), 30 | ]), 31 | /** 32 | * The Y domain of the data as an array - provided by XYPlot 33 | */ 34 | yDomain: PropTypes.array, 35 | /** 36 | * Spacing top - provided by XYPlot 37 | */ 38 | spacingTop: PropTypes.number, 39 | /** 40 | * Spacing bottom - provided by XYPlot 41 | */ 42 | spacingBottom: PropTypes.number, 43 | /** 44 | * Inline style object to be applied to the line 45 | */ 46 | style: PropTypes.object, 47 | /** 48 | * Class attribute to be applied to the line 49 | */ 50 | className: PropTypes.string, 51 | }; 52 | static defaultProps = { 53 | style: {}, 54 | className: '', 55 | spacingTop: 0, 56 | spacingBottom: 0, 57 | }; 58 | 59 | render() { 60 | const { 61 | xScale, 62 | value, 63 | yScale, 64 | yLimit, 65 | yDomain, 66 | height, 67 | style, 68 | spacingTop, 69 | spacingBottom, 70 | } = this.props; 71 | const className = `rct-chart-line-x ${this.props.className}`; 72 | const lineX = xScale(value); 73 | 74 | let y1 = -spacingTop; 75 | let y2 = height + spacingBottom; 76 | 77 | if (typeof yLimit !== 'undefined') { 78 | y1 = yScale(yDomain[0]) + spacingBottom; 79 | y2 = yScale(yLimit); 80 | } 81 | 82 | return ( 83 |