Skip to content

Commit

Permalink
feat(calendar): add support for legends on Calendar component
Browse files Browse the repository at this point in the history
  • Loading branch information
Raphaël Benitte authored and Raphaël Benitte committed Dec 7, 2017
1 parent 4063428 commit 6ef9dc2
Show file tree
Hide file tree
Showing 33 changed files with 894 additions and 218 deletions.
9 changes: 9 additions & 0 deletions Makefile
Expand Up @@ -118,6 +118,15 @@ package-build-watch-%: ##@packages build package (es flavor) on change, eg. `pac
@echo "${YELLOW}Running build watcher for package ${WHITE}${*}${RESET}"
@cd packages/nivo-${*} && yarn build:es:watch

package-build-%: ##@packages build package (all flavors), eg. `package-build-bar`
@echo "${YELLOW}Build package ${WHITE}${*}${RESET}"
@cd packages/nivo-${*} && yarn build

package-dev-%: ##@packages setup package for development, link to website, run watcher
@echo "${YELLOW}Preparing package ${WHITE}${*}${YELLOW} for development${RESET}"
@cd packages/nivo-${*} && yarn link
@cd website && yarn link @nivo/${*}
@make package-build-watch-${*}

########################################################################################################################
#
Expand Down
3 changes: 1 addition & 2 deletions README.md
Expand Up @@ -117,10 +117,9 @@ Join the [nivo discord community](https://discord.gg/n7Ft74f).

## Repositories

* [nivo](https://github.com/plouc/nivo) - the nivo library
* [nivo](https://github.com/plouc/nivo) - nivo packages, website, storybook and examples
* [nivo-api](https://github.com/plouc/nivo-api) - the nivo http api
* [nivo-api-docker](https://github.com/plouc/nivo-api-docker) - a Docker image for the nivo http api
* [nivo-generators](https://github.com/plouc/nivo-generators) - the data generators used for nivo-website and http API samples

## Credits

Expand Down
1 change: 0 additions & 1 deletion packages/nivo-bar/package.json
Expand Up @@ -7,7 +7,6 @@
"jsnext:main": "es/index.js",
"dependencies": {
"@nivo/core": "0.32.0",
"@nivo/legend": "0.32.0",
"d3-scale": "^1.0.6",
"d3-shape": "^1.2.0",
"react-motion": "^0.5.2",
Expand Down
115 changes: 0 additions & 115 deletions packages/nivo-bar/src/Bar.js
Expand Up @@ -14,7 +14,6 @@ import setDisplayName from 'recompose/setDisplayName'
import enhance from './enhance'
import { BarPropTypes } from './props'
import { Container, SvgWrapper } from '@nivo/core'
import { BoxLegendSvg } from '@nivo/legends'
import { Grid, Axes } from '@nivo/core'
import { CartesianMarkers } from '@nivo/core'

Expand Down Expand Up @@ -255,120 +254,6 @@ const Bar = ({
yScale={result.yScale}
theme={theme}
/>
<g transform={`translate(${-margin.left},${-margin.top})`}>
<BoxLegendSvg
containerWidth={outerWidth}
containerHeight={outerHeight}
itemWidth={100}
itemHeight={24}
direction="row"
anchor="top"
height={36}
data={keys}
/>
<BoxLegendSvg
containerWidth={outerWidth}
containerHeight={outerHeight}
itemWidth={100}
itemHeight={24}
direction="column"
anchor="top-right"
height={36}
data={keys}
/>
<BoxLegendSvg
containerWidth={outerWidth}
containerHeight={outerHeight}
itemWidth={100}
itemHeight={24}
direction="column"
anchor="right"
justify={true}
height={36}
data={keys}
/>
<BoxLegendSvg
containerWidth={outerWidth}
containerHeight={outerHeight}
itemWidth={64}
itemHeight={42}
direction="row"
anchor="bottom"
height={36}
data={keys}
itemDirection="top-to-bottom"
/>
<BoxLegendSvg
containerWidth={outerWidth}
containerHeight={outerHeight}
itemWidth={100}
itemHeight={36}
direction="column"
anchor="bottom-right"
itemDirection="bottom-to-top"
height={36}
data={keys}
/>
<BoxLegendSvg
containerWidth={outerWidth}
containerHeight={outerHeight}
itemWidth={100}
itemHeight={24}
margin={margin}
direction="column"
anchor="left"
itemDirection="right-to-left"
height={36}
data={keys}
/>
<BoxLegendSvg
containerWidth={outerWidth}
containerHeight={outerHeight}
itemWidth={100}
itemHeight={24}
direction="column"
anchor="bottom-left"
itemDirection="right-to-left"
justify={true}
height={36}
data={keys}
/>
<BoxLegendSvg
containerWidth={outerWidth}
containerHeight={outerHeight}
itemWidth={100}
itemHeight={36}
direction="column"
anchor="top-left"
itemDirection="top-to-bottom"
height={36}
data={keys}
/>
<BoxLegendSvg
containerWidth={outerWidth}
containerHeight={outerHeight}
itemWidth={100}
itemHeight={42}
direction="column"
anchor="top"
itemDirection="top-to-bottom"
justify={true}
height={36}
data={keys}
/>
<BoxLegendSvg
containerWidth={outerWidth}
containerHeight={outerHeight}
itemWidth={100}
itemHeight={42}
direction="column"
anchor="bottom"
itemDirection="bottom-to-top"
justify={true}
height={36}
data={keys}
/>
</g>
</SvgWrapper>
)
}}
Expand Down
1 change: 1 addition & 0 deletions packages/nivo-calendar/package.json
Expand Up @@ -7,6 +7,7 @@
"jsnext:main": "es/index.js",
"dependencies": {
"@nivo/core": "0.32.0",
"@nivo/legends": "0.32.0",
"d3-scale": "^1.0.6",
"d3-time": "^1.0.7",
"d3-time-format": "^2.0.5",
Expand Down
21 changes: 20 additions & 1 deletion packages/nivo-calendar/src/Calendar.js
Expand Up @@ -7,9 +7,10 @@
* file that was distributed with this source code.
*/
import React from 'react'
import { timeFormat } from 'd3-time-format'
import { BoxLegendSvg } from '@nivo/legends'
import computeCalendar from './computeCalendar'
import { CalendarPropTypes } from './props'
import { timeFormat } from 'd3-time-format'
import { DIRECTION_HORIZONTAL } from './constants'
import CalendarDay from './CalendarDay'
import CalendarMonthPath from './CalendarMonthPath'
Expand Down Expand Up @@ -49,6 +50,8 @@ const Calendar = ({
isInteractive,
tooltipFormat,
onClick,

legends,
}) => {
const { years, months, days } = computeCalendar({
width,
Expand Down Expand Up @@ -135,6 +138,22 @@ const Calendar = ({
</text>
)
})}
{legends.map((legend, i) => {
const legendData = colorScale.ticks(legend.itemCount).map(value => ({
label: value,
fill: colorScale(value),
}))

return (
<BoxLegendSvg
key={i}
{...legend}
containerWidth={width}
containerHeight={height}
data={legendData}
/>
)
})}
</SvgWrapper>
)}
</Container>
Expand Down
10 changes: 10 additions & 0 deletions packages/nivo-calendar/src/props.js
Expand Up @@ -8,6 +8,7 @@
*/
import PropTypes from 'prop-types'
import { noop } from '@nivo/core'
import { LegendPropShape } from '@nivo/legends'
import { DIRECTION_HORIZONTAL, DIRECTION_VERTICAL } from './constants'

/**
Expand Down Expand Up @@ -52,6 +53,13 @@ export const CalendarPropTypes = {
isInteractive: PropTypes.bool,
onClick: PropTypes.func.isRequired,
tooltipFormat: PropTypes.oneOfType([PropTypes.func, PropTypes.string]),

legends: PropTypes.arrayOf(
PropTypes.shape({
...LegendPropShape,
itemCount: PropTypes.number,
})
).isRequired,
}

/**
Expand Down Expand Up @@ -84,4 +92,6 @@ export const CalendarDefaultProps = {
// interactivity
isInteractive: true,
onClick: noop,

legends: [],
}
20 changes: 17 additions & 3 deletions packages/nivo-heatmap/src/HeatMap.js
Expand Up @@ -10,15 +10,18 @@ import React, { Component } from 'react'
import { partial } from 'lodash'
import { TransitionMotion } from 'react-motion'
import { colorMotionSpring, getInterpolatedColor } from '@nivo/core'
import { Container, SvgWrapper } from '@nivo/core'
import { Grid, Axes } from '@nivo/core'
import setDisplayName from 'recompose/setDisplayName'
import { HeatMapPropTypes } from './props'
import computeNodes from './computeNodes'
import enhance from './enhance'
import { Container, SvgWrapper } from '@nivo/core'
import { Grid, Axes } from '@nivo/core'
import HeatMapCellRect from './HeatMapCellRect'
import HeatMapCellCircle from './HeatMapCellCircle'
import HeatMapCellTooltip from './HeatMapCellTooltip'

import { scaleLinear } from 'd3-scale'

class HeatMap extends Component {
static propTypes = HeatMapPropTypes

Expand All @@ -39,6 +42,8 @@ class HeatMap extends Component {
yScale,
offsetX,
offsetY,
minValue,
maxValue,

margin,
width,
Expand All @@ -65,6 +70,7 @@ class HeatMap extends Component {

// theming
theme,
colorScale,

// motion
animate,
Expand Down Expand Up @@ -93,6 +99,14 @@ class HeatMap extends Component {
motionStiffness,
}

const legendItems = scaleLinear()
.domain([minValue, maxValue])
.ticks(4)
.map(i => ({
label: i,
fill: colorScale(i),
}))

return (
<Container isInteractive={isInteractive} theme={theme}>
{({ showTooltip, hideTooltip }) => {
Expand Down Expand Up @@ -210,4 +224,4 @@ class HeatMap extends Component {
}
}

export default enhance(HeatMap)
export default setDisplayName('HeatMap')(enhance(HeatMap))
1 change: 1 addition & 0 deletions packages/nivo-legends/package.json
@@ -1,5 +1,6 @@
{
"name": "@nivo/legends",
"description": "legend components for nivo dataviz library",
"version": "0.32.0",
"license": "MIT",
"main": "./lib/index.js",
Expand Down
56 changes: 56 additions & 0 deletions packages/nivo-legends/src/compute.js
@@ -0,0 +1,56 @@
/*
* This file is part of the nivo project.
*
* Copyright 2016-present, Raphaël Benitte.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
import { isNumber, isPlainObject } from 'lodash'
import { DIRECTION_COLUMN, DIRECTION_ROW } from './constants'

const zeroPadding = {
top: 0,
right: 0,
bottom: 0,
left: 0,
}

export const computeDimensions = ({
itemCount,
itemWidth,
itemHeight,
direction,
itemsSpacing,
padding: _padding,
}) => {
let padding
if (isNumber(_padding)) {
padding = {
top: _padding,
right: _padding,
bottom: _padding,
left: _padding,
}
} else if (isPlainObject(_padding)) {
padding = {
...zeroPadding,
..._padding,
}
} else {
throw new TypeError(`Invalid property padding, must be one of: number, object`)
}

const horizontalPadding = padding.left + padding.right
const verticalPadding = padding.top + padding.bottom
let width = itemWidth + horizontalPadding
let height = itemHeight + verticalPadding
let spacing = (itemCount - 1) * itemsSpacing
if (direction === DIRECTION_ROW) {
width = itemWidth * itemCount + spacing + horizontalPadding
} else if (direction === DIRECTION_COLUMN) {
height = itemHeight * itemCount + spacing + verticalPadding
}

return { width, height, padding }
}
1 change: 1 addition & 0 deletions packages/nivo-legends/src/constants.js
Expand Up @@ -17,6 +17,7 @@ export const ANCHOR_BOTTOM = 'bottom'
export const ANCHOR_BOTTOM_LEFT = 'bottom-left'
export const ANCHOR_LEFT = 'left'
export const ANCHOR_TOP_LEFT = 'top-left'
export const ANCHOR_CENTER = 'center'

export const DIRECTION_LEFT_TO_RIGHT = 'left-to-right'
export const DIRECTION_RIGHT_TO_LEFT = 'right-to-left'
Expand Down
2 changes: 2 additions & 0 deletions packages/nivo-legends/src/index.js
Expand Up @@ -7,3 +7,5 @@
* file that was distributed with this source code.
*/
export * from './svg'
export * from './constants'
export * from './props'

0 comments on commit 6ef9dc2

Please sign in to comment.