diff --git a/src/components/charts/Container.js b/src/components/charts/Container.js
new file mode 100644
index 000000000..fcacfa181
--- /dev/null
+++ b/src/components/charts/Container.js
@@ -0,0 +1,74 @@
+import React, { Component } from 'react'
+import PropTypes from 'prop-types'
+
+const containerStyle = {
+ position: 'relative',
+}
+
+const tooltipStyle = {
+ position: 'absolute',
+ background: '#FFF',
+ zIndex: 10,
+ top: 0,
+ left: 0,
+ borderRadius: '3px',
+ boxShadow: '0 1px 2px rgba(0, 0, 0, 0.25)',
+ padding: '7px 12px',
+}
+
+const Tooltip = ({ x, y, children }) =>
+
+ {children}
+
+
+export default class Container extends Component {
+ static propTypes = {
+ children: PropTypes.func.isRequired,
+ }
+
+ state = {
+ isTooltipVisible: true,
+ tooltipContent: 'crap',
+ tooltipX: 0,
+ tooltipY: 0,
+ }
+
+ showTooltip = (content, event) => {
+ const { pageX, pageY } = event
+ const bounds = this.container.getBoundingClientRect()
+
+ this.setState({
+ isTooltipVisible: true,
+ tooltipContent: content,
+ tooltipX: pageX - bounds.left + 20,
+ tooltipY: pageY - bounds.top,
+ })
+ }
+
+ hideTooltip = () => {
+ this.setState({ isTooltipVisible: false, tooltipContent: null })
+ }
+
+ render() {
+ const { children } = this.props
+ const { isTooltipVisible, tooltipContent, tooltipX, tooltipY } = this.state
+
+ return (
+ {
+ this.container = container
+ }}
+ >
+ {children({
+ showTooltip: this.showTooltip,
+ hideTooltip: this.hideTooltip,
+ })}
+ {isTooltipVisible &&
+
+ {tooltipContent}
+ }
+
+ )
+ }
+}
diff --git a/src/components/charts/stream/Stream.js b/src/components/charts/stream/Stream.js
index ec2fe53a7..6e169bd55 100644
--- a/src/components/charts/stream/Stream.js
+++ b/src/components/charts/stream/Stream.js
@@ -26,8 +26,9 @@ import {
stackOffsetPropType,
stackOffsetFromProp,
} from '../../../props'
-import { getColorsGenerator } from '../../../lib/colorUtils'
+import { getColorRange } from '../../../lib/colorUtils'
import SvgWrapper from '../SvgWrapper'
+import Container from '../Container'
import Axes from '../../axes/Axes'
import Grid from '../../axes/Grid'
import StreamLayers from './StreamLayers'
@@ -37,6 +38,8 @@ const stackMax = layers => max(layers.reduce((acc, layer) => [...acc, ...layer.m
const Stream = ({
data,
+ keys,
+
order,
offsetType,
curve,
@@ -59,14 +62,13 @@ const Stream = ({
// theming
theme,
color,
+ fillOpacity,
// motion
animate,
motionStiffness,
motionDamping,
}) => {
- const keys = range(5)
-
const stack = d3Stack()
.keys(keys)
.offset(stackOffsetFromProp(offsetType))
@@ -74,12 +76,6 @@ const Stream = ({
const layers = stack(data)
- /*
- console.log('DATA', data)
- console.log('KEYS', keys)
- console.log('LAYERS', layers)
- */
-
const minValue = stackMin(layers)
const maxValue = stackMax(layers)
@@ -92,6 +88,13 @@ const Stream = ({
.y1(d => yScale(d[1]))
.curve(curveFromProp(curve))
+ const enhancedLayers = layers.map((layer, i) => ({
+ id: keys[i],
+ layer,
+ path: area(layer),
+ color: color(i),
+ }))
+
const motionProps = {
animate,
motionDamping,
@@ -99,43 +102,46 @@ const Stream = ({
}
return (
-
-
- ({
- layer,
- path: area(layer),
- color: color(i),
- }))}
- area={area}
- {...motionProps}
- />
-
-
+
+ {({ showTooltip, hideTooltip }) =>
+
+
+
+
+ }
+
)
}
Stream.propTypes = {
// data
data: PropTypes.arrayOf(PropTypes.object).isRequired,
+ keys: PropTypes.array.isRequired,
order: stackOrderPropType.isRequired,
offsetType: stackOffsetPropType.isRequired,
@@ -157,7 +163,7 @@ Stream.propTypes = {
// theming
theme: PropTypes.object.isRequired,
colors: PropTypes.any.isRequired,
- colorBy: PropTypes.oneOfType([PropTypes.string, PropTypes.func]),
+ fillOpacity: PropTypes.number.isRequired,
color: PropTypes.func.isRequired,
// motion
@@ -167,7 +173,7 @@ Stream.propTypes = {
export const StreamDefaultProps = {
order: 'none',
offsetType: 'wiggle',
- curve: 'monotoneX',
+ curve: 'catmullRom',
// dimensions
margin: Nivo.defaults.margin,
@@ -180,7 +186,7 @@ export const StreamDefaultProps = {
// theming
theme: {},
colors: 'nivo',
- colorBy: 'id',
+ fillOpacity: 1,
// motion
animate: true,
@@ -191,8 +197,8 @@ export const StreamDefaultProps = {
const enhance = compose(
defaultProps(StreamDefaultProps),
withPropsOnChange(['theme'], ({ theme }) => ({ theme: merge({}, defaultTheme, theme) })),
- withPropsOnChange(['colors', 'colorBy'], ({ colors, colorBy }) => ({
- color: getColorsGenerator(colors, d => Nivo.defaults.colorRange(d)),
+ withPropsOnChange(['colors'], ({ colors, colorBy }) => ({
+ color: getColorRange(colors),
})),
withPropsOnChange(
(props, nextProps) =>
diff --git a/src/components/charts/stream/StreamLayers.js b/src/components/charts/stream/StreamLayers.js
index e4c3cfe3e..412616c0d 100644
--- a/src/components/charts/stream/StreamLayers.js
+++ b/src/components/charts/stream/StreamLayers.js
@@ -13,6 +13,10 @@ import SmartMotion from '../../SmartMotion'
const StreamLayers = ({
layers,
+ fillOpacity,
+
+ showTooltip,
+ hideTooltip,
// motion
animate,
@@ -22,7 +26,21 @@ const StreamLayers = ({
if (animate !== true) {
return (
- {layers.map(({ path, color }, i) => )}
+ {layers.map(({ id, path, color }, i) =>
+ {
+ showTooltip(id, e)
+ }}
+ onMouseEnter={e => {
+ showTooltip(id, e)
+ }}
+ onMouseLeave={hideTooltip}
+ d={path}
+ fill={color}
+ fillOpacity={fillOpacity}
+ />
+ )}
)
}
@@ -34,15 +52,26 @@ const StreamLayers = ({
return (
- {layers.map(({ path, color }, i) =>
+ {layers.map(({ id, path, color }, i) =>
({
d: spring(path, springConfig),
fill: spring(color, springConfig),
+ fillOpacity: spring(fillOpacity, springConfig),
})}
>
- {style => }
+ {style =>
+ {
+ showTooltip(id, e)
+ }}
+ onMouseEnter={e => {
+ showTooltip(id, e)
+ }}
+ onMouseLeave={hideTooltip}
+ {...style}
+ />}
)}
@@ -51,6 +80,7 @@ const StreamLayers = ({
StreamLayers.propTypes = {
area: PropTypes.func.isRequired,
+ fillOpacity: PropTypes.number.isRequired,
// motion
...motionPropTypes,