Thanks for helping out! We couldn't build Victory without the support of our awesome community. Here's a guide for getting you started. If you have any questions, don't hesitate to reach out on Gitter.
We love issues!
If you find a bug 🐛 the first thing you should do is search for an existing issue describing your problem. It helps if you can add more detail or a reproduction case. See this list of repos, and scroll through or use the search feature.
If you can't find an existing issue, create a new issue. Please add a Fiddle demonstrating the issue. This is the number one most important thing you can do to help us fix the bug!
Feel like writing some code? The best way to get familiar with the code base is to fix a bug! Check out our Project Board to see issues across all repos.
Fork the repo from the repository front page of the component you want to work on.
When you've fixed the bug, it's time to write some tests to ensure important corner cases are covered, and that the bug doesn't get introduced again. See victory-pie.spec.jsx for an example test suite.
Submit a PR by clicking "New pull request" from your fork's main repo page. Before submitting a PR, please read the Developer's Guide below. It will help you stay consistent with the code style and get your PRs merged sooner!
We prefer that you fold all your commits into one for bug fixes. It's easy:
# 1. Create a separate copy of the branch just to be safe.
$ git checkout -b bug-fixWithOneCommit
# 2. "Soft reset" the precise number of commits you want to squash into one.
# Replace the `N` with the number of commits you've made! `git log --oneline` if you're unsure.
# This will result in a staged diff that's ready-to-commit.
$ git reset --soft HEAD~N
# 3. Commit the change. Include the issue #number in the commit message!
$ git commit
Make sure to mention the issue #number
in the commit message!
This is an overview. For a more in-depth guide, see DEVELOPMENT.md
.
Note: Victory requires npm v3
. To upgrade your global npm
installation, run npm install -g npm@3
.
We use builder to control our
development workflows. builder
is an npm dependency found in
node_modules/.bin/builder
. To use the shorthand builder
command without the
full path, please follow the steps in the builder
local install guide.
The "short, short version" of this on Mac/Linux is to add:
export PATH="${PATH}:./node_modules/.bin"
to your permanent shell configuration.
Run builder run dev
to run a webpack dev server with component examples. The dev server runs on localhost:3000
.
Each bug fix and feature should come with tests. New features should aim for 100% code coverage.
Run builder run server-test
to run a karma server with HTML reporting, then open http://localhost:3001/test/client/test.html in your browser. This is great for debugging tests.
Run builder run check
before committing to ensure lint and tests are passing.
We'd like to start using Enzyme for tests. If you feel up for it, please help by converting some existing tests to Enzyme.
We follow a consistent code style, but we don't have a style manual yet. The easiest way to get a feel for the style is to look at source code.
The JavaScript code style is enforced with eslint
following the defaults/configurations/walmart/es6-react
configuration from eslint-config-defaults
.
Victory is an ecosystem of modular components with similar language and methodologies. Because these components are designed to work together, a consistent set of patterns and conventions is necessary. Please read the following set of standards and examples if you are interested in writing a larger feature, or contributing a new victory component.
Victory is designed to be as flexible as possible. Code should be free of hard-coded values or one-off solutions. The following patterns also help keep the library flexible:
Seperating Rendered Components
Any component that renders an element (i.e. <line/>
, <text/>
and even <g/>
) should be written as a seperate component, and included via defaultProps
so that they can be overridden the users. This pattern also allows us to use the same code base to support a react native version of Victory.
These primitive rendered elements are kept in the victory-core
repo. Please check here first before writing a new rendered component. Rendered components should be stateless and as general as possible. Point
is a good example of a rendered component. Notice that Point
is written so that it can easily be extended to a react native compatible version. The appropriate versions of Point
can then be included as defaultProps
in standard version, and the native version of VictoryScatter
Support Data Accessor Props
Rather than requiring a rigid data structure, Victory components should provide accessor props for formatting whatever data the user provides into a format the component is expecting. Use this createAccessor
function to build an accessor from props and use it to format data. Notice how VictoryCandlestick
makes use of data accessor functions to support its unique data requirements.
Support themes
defaultProps
should not contain any layout related props because these values may be provided by themes. Necessary layout props should be provided via fallbackProps
and merged with props and themes as needed; for example, see how VictoryScatter
uses fallbackProps
.
All Victory components should render something even if no props are provided. This can be accomplished with default data and other defaultProps
. Victory components should also have sensible behavior even when the minimum of props are provided. For example, if only data
is provided, components that require a domain should calculate one from the data provided. All Victory components should also use the default grayscale
theme so that they have sensible styling even when no styles are provided by the user.
Similar props across Victory components should have the same names and operate similarly. For example, the style prop should almost always have the shape:
style={{
data: {
...
},
labels: {
...
}
}}
When writing a new component please reference other Victory components when deciding on a set of props. When writing a component for use with VictoryChart, the API should include the following props:
name
animate
categories
labels
data
- data accessors, usually
x
andy
domain
andscale
domainPadding
- rendered components, usually
dataComponent
,labelComponent
,groupComponent
, andcontainerComponent
events
andsharedEvents
- required layout props:
height
,width
, andpadding
style
andtheme
Victory Components animate via a flexible animation wrapper VictoryTransition
which handles load animations and entrance and exit transitions before interpolation between sets of props with VictoryAnimation
. All Victory components that render elements (not higher order components that are only responsible for coodinating other components) should return the component wrapped in VictoryTransition
as in this example. Components should also expose their set of transiton parameters via a static method. Most components will use standard transitions: either discrete as in VictoryScatter or continuous as in VictoryLine. It also possible to define custom default transitions where appropriate. For example VictoryBar defines custom transitions which cause the bars to rise from zero. These transitions and other animation properties can all be defined by users via the animate
prop.
Victory's event system is as general as possible, with no hard-coded events. To make a component work with Victory's event system, use the addEvents
wrapper provided by victory-core
. Components that use this wrapper should have a static method called getBaseProps
that calculates props for each primitive component (i.e. each Bar
and VictoryLabel
rendered by VictoryBar
). and a static array of expectedComponents
that may also have devault events. See VictoryBar
and its helper-methods for an example.