Skip to content

Commit

Permalink
feat(scatterplot): improve scatterplot
Browse files Browse the repository at this point in the history
  • Loading branch information
Raphaël Benitte authored and Raphaël Benitte committed Oct 18, 2018
1 parent 36cd9c7 commit 4ae6591
Show file tree
Hide file tree
Showing 41 changed files with 4,076 additions and 3,430 deletions.
5 changes: 5 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,9 @@ max_line_length = 100
[*.ts]
indent_style = space
indent_size = 4
max_line_length = 100

[*.tsx]
indent_style = space
indent_size = 4
max_line_length = 100
3 changes: 2 additions & 1 deletion .storybook/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,8 @@ function loadStories() {
require('../packages/pie/stories/pie.stories')
require('../packages/radar/stories/radar.stories')
require('../packages/sankey/stories/sankey.stories')
require('../packages/scatterplot/stories/scatterplot.stories')
require('../packages/scatterplot/stories/ScatterPlot.stories')
require('../packages/scatterplot/stories/ScatterPlotCanvas.stories')
require('../packages/stream/stories/stream.stories')
require('../packages/sunburst/stories/sunburst.stories')
require('../packages/treemap/stories/treemap.stories')
Expand Down
13 changes: 10 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,8 @@ init: ##@0 global cleanup/install/bootstrap

fmt: ##@0 global format code using prettier (js, css, md)
@./node_modules/.bin/prettier --color --write \
"packages/*/{src,stories,tests}/**/*.js" \
"packages/*/{src,stories,tests}/**/*.{js,ts}" \
"packages/*/index.d.ts" \
"packages/*/README.md" \
"website/src/**/*.{js,css}" \
"examples/*/src/**/*.{js,ts,tsx,css}" \
Expand All @@ -63,10 +64,10 @@ fmt: ##@0 global format code using prettier (js, css, md)
fmt-check: ##@0 global check if files were all formatted using prettier
@echo "${YELLOW}Checking formatting${RESET}"
@./node_modules/.bin/prettier --color --list-different \
"packages/*/{src,stories,tests}/**/*.js" \
"packages/*/{src,stories,tests}/**/*.{js,ts}" \
"packages/*/index.d.ts" \
"packages/*/README.md" \
"website/src/**/*.{js,css}" \
"storybook/stories/**/*.{js,css}" \
"examples/*/src/**/*.{js,ts,tsx,css}" \
"README.md"

Expand Down Expand Up @@ -120,11 +121,17 @@ package-tslint-%: ##@1 packages run tslint on package
packages-tslint: ##@1 packages run tslint on all packages
@echo "${YELLOW}Running tslint on all packages${RESET}"
@./node_modules/.bin/tslint \
./packages/axes/index.d.ts \
./packages/bar/index.d.ts \
./packages/calendar/index.d.ts \
./packages/core/index.d.ts \
./packages/heatmap/index.d.ts \
./packages/legends/index.d.ts \
./packages/line/index.d.ts \
./packages/pie/index.d.ts \
./packages/sankey/index.d.ts \
./packages/scales/index.d.ts \
./packages/scatterplot/index.d.ts \
./packages/waffle/index.d.ts

package-test-%: ##@1 packages run tests for a package
Expand Down
3 changes: 2 additions & 1 deletion examples/typescript/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
"version": "0.1.0",
"private": true,
"dependencies": {
"@nivo/line": "^0.50.0",
"@nivo/line": "0.50.0",
"@nivo/scatterplot": "0.50.0",
"react": "^16.5.2",
"react-dom": "^16.5.2",
"react-scripts-ts": "3.1.0"
Expand Down
2 changes: 2 additions & 0 deletions examples/typescript/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import * as React from 'react'
import Line from './components/Line'
import ScatterPlot from './components/ScatterPlot'
import './App.css'

export default class App extends React.Component {
Expand All @@ -9,6 +10,7 @@ export default class App extends React.Component {
<header className="App-header">
<h1 className="App-title">nivo typescript example</h1>
</header>
<ScatterPlot />
<Line />
</div>
)
Expand Down
1 change: 1 addition & 0 deletions examples/typescript/src/components/Line.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ export default class Line extends React.Component {
legend: 'whatever for x',
legendOffset: -40,
legendPosition: 'middle',
format: (v: number) => `${v}`,
}}
enableGridX={true}
enableGridY={true}
Expand Down
118 changes: 118 additions & 0 deletions examples/typescript/src/components/ScatterPlot.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
import * as React from 'react'
import { ResponsiveScatterPlot, ScatterPlotDatum } from '@nivo/scatterplot'

export default class ScatterPlot extends React.Component {
public render() {
return (
<div
style={{
height: 400,
}}
>
<ResponsiveScatterPlot
data={[
{
id: 'group A',
data: [{ x: 0, y: 0 }, { x: 2, y: 7 }, { x: 7, y: 23 }],
},
{
id: 'group B',
data: [{ x: 3, y: 13 }, { x: 5, y: 7 }, { x: 6, y: 19 }],
},
]}
xScale={{
type: 'linear',
min: 0,
max: 'auto',
}}
yScale={{
type: 'linear',
min: 0,
max: 30,
}}
theme={{
grid: {
line: {
stroke: '#fdd',
strokeDasharray: '8 4 1 4',
},
},
}}
margin={{
top: 60,
right: 100,
bottom: 60,
left: 100,
}}
enableGridX={true}
enableGridY={true}
symbolSize={12}
symbolShape="circle"
axisLeft={{
tickSize: 5,
tickPadding: 5,
tickRotation: 0,
legend: 'size',
legendPosition: 'middle',
legendOffset: -60,
format: (v: number) => `${v}x`,
}}
legends={[
{
anchor: 'bottom-right',
direction: 'column',
translateX: -20,
translateY: -20,
itemWidth: 80,
itemHeight: 24,
itemsSpacing: 5,
itemBackground: '#fff',
itemTextColor: '#999',
symbolSize: 12,
symbolShape: 'circle',
effects: [
{
on: 'hover',
style: {
itemTextColor: '#000',
},
},
],
},
]}
markers={[
{
axis: 'x',
value: 4,
legend: 'X marker a 4',
lineStyle: {
stroke: 'blue',
},
textStyle: {
fill: 'blue',
},
},
{
axis: 'y',
value: 20,
legend: 'Y marker at 20',
lineStyle: {
stroke: 'red',
},
textStyle: {
fill: 'red',
},
},
]}
isInteractive={true}
animate={false}
motionStiffness={150}
motionDamping={15}
onClick={(data: ScatterPlotDatum) => {
console.log(data)
}}
/>
</div>
)
}
}
14 changes: 13 additions & 1 deletion examples/typescript/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@
lodash "^4.17.4"
recompose "^0.26.0"

"@nivo/line@^0.50.0":
"@nivo/[email protected]":
version "0.50.0"
resolved "https://registry.yarnpkg.com/@nivo/line/-/line-0.50.0.tgz#61d4bfa2d840acc60c1e82e33bbd148817c19731"
dependencies:
Expand All @@ -74,6 +74,18 @@
d3-time-format "^2.1.3"
lodash "^4.17.4"

"@nivo/[email protected]":
version "0.50.0"
resolved "https://registry.yarnpkg.com/@nivo/scatterplot/-/scatterplot-0.50.0.tgz#f77201c4733b0c5068c163233be82c75ded14d2c"
dependencies:
"@nivo/core" "0.50.0"
"@nivo/legends" "0.50.0"
d3-scale "^2.1.2"
d3-shape "^1.2.2"
lodash "^4.17.4"
react-motion "^0.5.2"
recompose "^0.26.0"

"@types/jest@^23.3.5":
version "23.3.5"
resolved "https://registry.yarnpkg.com/@types/jest/-/jest-23.3.5.tgz#870a1434208b60603745bfd214fc3fc675142364"
Expand Down
2 changes: 1 addition & 1 deletion packages/axes/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ declare module '@nivo/axes' {
tickSize?: number
tickPadding?: number
tickRotation?: number
tickFormat?: any // PropTypes.oneOfType([PropTypes.func, PropTypes.string])
format?: any // PropTypes.oneOfType([PropTypes.func, PropTypes.string])
renderTick?: (data: any) => React.ReactNode
legend?: React.ReactNode
legendPosition?: 'start' | 'middle' | 'end'
Expand Down
11 changes: 7 additions & 4 deletions packages/axes/src/canvas.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
* file that was distributed with this source code.
*/
import { degreesToRadians } from './utils'
import { computeCartesianTicks } from './compute'
import { computeCartesianTicks, getFormatter } from './compute'

export const renderAxisToCanvas = (
ctx,
Expand All @@ -23,7 +23,7 @@ export const renderAxisToCanvas = (
tickSize = 5,
tickPadding = 5,
tickRotation = 0,
tickValueFormat,
format,

// @todo implement legend support
// legend,
Expand Down Expand Up @@ -68,7 +68,7 @@ export const renderAxisToCanvas = (
ctx.lineTo(tick.x + tick.lineX, tick.y + tick.lineY)
ctx.stroke()

const value = tickValueFormat !== undefined ? tickValueFormat(tick.value) : tick.value
const value = format !== undefined ? format(tick.value) : tick.value

ctx.save()
ctx.translate(tick.x + tick.textX, tick.y + tick.textY)
Expand Down Expand Up @@ -108,13 +108,16 @@ export const renderAxesToCanvas = (

const isXAxis = position === 'top' || position === 'bottom'
const ticksPosition = position === 'top' || position === 'left' ? 'before' : 'after'
const scale = isXAxis ? xScale : yScale
const format = getFormatter(axis.format, scale)

renderAxisToCanvas(ctx, {
...axis,
axis: isXAxis ? 'x' : 'y',
x: position === 'right' ? width : 0,
y: position === 'bottom' ? height : 0,
scale: isXAxis ? xScale : yScale,
scale,
format,
length: isXAxis ? width : height,
ticksPosition,
theme,
Expand Down
24 changes: 7 additions & 17 deletions packages/axes/src/components/Axis.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,13 @@
*/
import React, { Component, Fragment } from 'react'
import PropTypes from 'prop-types'
import isFunction from 'lodash/isFunction'
import { format as d3Format } from 'd3-format'
import { timeFormat } from 'd3-time-format'
import compose from 'recompose/compose'
import withPropsOnChange from 'recompose/withPropsOnChange'
import pure from 'recompose/pure'
import setDisplayName from 'recompose/setDisplayName'
import { Motion, TransitionMotion, spring } from 'react-motion'
import { computeCartesianTicks } from '../compute'
import { withMotion, motionPropTypes, axisThemePropType } from '@nivo/core'
import { computeCartesianTicks, getFormatter } from '../compute'
import AxisTick from './AxisTick'

const willEnter = () => ({
Expand Down Expand Up @@ -91,7 +88,7 @@ class Axis extends Component {
tickSize,
tickPadding,
tickRotation,
tickValueFormat,
format,
renderTick,
legend,
legendPosition,
Expand Down Expand Up @@ -165,7 +162,7 @@ class Axis extends Component {
{ticks.map((tick, tickIndex) =>
renderTick({
tickIndex,
format: tickValueFormat,
format,
rotate: tickRotation,
textBaseline,
textAnchor: textAlign,
Expand Down Expand Up @@ -214,7 +211,7 @@ class Axis extends Component {
{interpolatedStyles.map(({ style, data: tick }, tickIndex) =>
renderTick({
tickIndex,
format: tickValueFormat,
format,
textBaseline,
textAnchor: textAlign,
theme,
Expand Down Expand Up @@ -246,16 +243,9 @@ class Axis extends Component {

const enhance = compose(
withMotion(),
withPropsOnChange(['format', 'scale'], ({ format, scale }) => {
if (!format || isFunction(format)) {
return { format }
} else if (scale.type === 'time') {
const f = timeFormat(format)
return { format: d => f(new Date(d)) }
} else {
return { format: d3Format(format) }
}
}),
withPropsOnChange(['format', 'scale'], ({ format, scale }) => ({
format: getFormatter(format, scale),
})),
pure
)

Expand Down
14 changes: 14 additions & 0 deletions packages/axes/src/compute.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@
*/
import isNumber from 'lodash/isNumber'
import isArray from 'lodash/isArray'
import isFunction from 'lodash/isFunction'
import { timeFormat } from 'd3-time-format'
import { format as d3Format } from 'd3-format'
import { textPropsByEngine } from '@nivo/core'

export const centerScale = scale => {
Expand Down Expand Up @@ -107,3 +110,14 @@ export const computeCartesianTicks = ({
textBaseline,
}
}

export const getFormatter = (format, scale) => {
if (!format || isFunction(format)) return format

if (scale.type === 'time') {
const f = timeFormat(format)
return d => f(new Date(d))
}

return d3Format(format)
}
2 changes: 1 addition & 1 deletion packages/axes/src/props.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export const axisPropTypes = {
tickSize: PropTypes.number,
tickPadding: PropTypes.number,
tickRotation: PropTypes.number,
tickFormat: PropTypes.oneOfType([PropTypes.func, PropTypes.string]),
format: PropTypes.oneOfType([PropTypes.func, PropTypes.string]),
renderTick: PropTypes.func,
legend: PropTypes.node,
legendPosition: PropTypes.oneOf(['start', 'middle', 'end']),
Expand Down
Loading

0 comments on commit 4ae6591

Please sign in to comment.