Back to Gallery
Stream Graph
// This custom path component is supplied to `Area` as the `pathComponent` prop function GradientPath(props) { const toGrayscale = color => { const integerColor = parseInt(color.replace("#", ""), 16); const r = (integerColor >> 16) & 255; // eslint-disable-line no-bitwise const g = (integerColor >> 8) & 255; // eslint-disable-line no-bitwise const b = integerColor & 255; // eslint-disable-line no-bitwise const gray = parseInt(0.299 * r + 0.587 * g + 0.114 * b, 10); return `rgb(${gray}, ${gray}, ${gray})`; }; const { percent, style = {}, ...rest } = props; const gradientId = `gradient-${Math.random()}`; const isBrowser = typeof window !== "undefined" && window.__STATIC_GENERATOR !== true; const loc = isBrowser ? window.location.href : ""; const areaStyle = Object.assign({}, style, { fill: `url(${loc}#${gradientId})`, stroke: "none" }); return ( <g key="area"> <defs> <linearGradient id={gradientId}> <stop offset="0%" stopColor={style.fill} /> <stop offset={`${percent}%`} stopColor={style.fill} /> <stop offset={`${percent}%`} stopColor={toGrayscale(style.fill)} /> <stop offset="100%" stopColor={toGrayscale(style.fill)} /> </linearGradient> </defs> <path key="area" {...rest} style={areaStyle} /> </g> ); } function App() { const [state, setState] = React.useState({ percent: 62 }); const streamData = getStreamData(); const colors = [ "#006064", "#00796B", "#8BC34A", "#DCE775", "#FFF59D", "#F4511E", "#c33409" ]; return ( <VictoryChart domain={{ x: [0, 25], y: [-300, 300] }} > <VictoryAxis style={{ axis: { stroke: "none" }, tickLabels: { fill: "none" }, grid: { stroke: "gray" } }} tickValues={[2, 4, 6, 8, 10, 12, 14, 17, 19, 21, 23, 25]} /> <VictoryAxis dependentAxis style={{ tickLabels: { fontSize: 15 } }} crossAxis={false} /> {streamData.map((d, i) => ( <VictoryArea key={i} interpolation="monotoneX" data={d} style={{ data: { fill: colors[i] } }} dataComponent={ <Area pathComponent={<GradientPath percent={state.percent} />} /> } /> ))} <VictoryLine style={{ data: { stroke: "#c33409", strokeWidth: 3 } }} data={[ { x: (25 * state.percent) / 100, y: -300 }, { x: (25 * state.percent) / 100, y: 300 } ]} /> </VictoryChart> ); } function getStreamData() { return _.range(7).map(i => _.range(26).map(j => ({ x: j, y: (10 - i) * _.random(10 - i, 20 - 2 * i), _y0: -1 * (10 - i) * _.random(10 - i, 20 - 2 * i) })) ); } render(<App/>);