Skip to content

Commit

Permalink
Charts refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
matthewlilley committed Nov 28, 2020
1 parent 3d9eeb5 commit dcc26fc
Show file tree
Hide file tree
Showing 19 changed files with 712 additions and 603 deletions.
1 change: 1 addition & 0 deletions jsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
"app/core": ["core/index.js"],
"app/core/api": ["core/api/index.js"],
"app/core/apollo": ["core/apollo/index.js"],
"app/core/chart": ["core/chart.js"],
"app/core/constants": ["core/constants.js"],
"app/core/conversions": ["core/conversions.js"],
"app/core/format": ["core/format.js"],
Expand Down
70 changes: 29 additions & 41 deletions src/components/Area.js
Original file line number Diff line number Diff line change
@@ -1,68 +1,56 @@
import { AxisBottom, AxisLeft, AxisScale } from "@visx/axis";
import { GradientTealBlue, LinearGradient } from "@visx/gradient";
import { AxisBottom, AxisLeft } from "@visx/axis";
import {
axisBottomTickLabelProps,
axisColor,
axisLeftTickLabelProps,
getX,
getY,
} from "app/core";
import { scaleLinear, scaleTime } from "@visx/scale";

import { AppleStock } from "@visx/mock-data/lib/mocks/appleStock";
import { AreaClosed } from "@visx/shape";
import { GradientTealBlue } from "@visx/gradient";
import { Group } from "@visx/group";
import React from "react";
import { curveMonotoneX } from "@visx/curve";
import millify from "millify";

// Initialize some variables
const axisColor = "currentColor";
const axisBottomTickLabelProps = {
textAnchor: "middle",
fontFamily: "Arial",
fontSize: 10,
fill: axisColor,
};
const axisLeftTickLabelProps = {
dx: "-0.25em",
dy: "0.25em",
fontFamily: "Arial",
fontSize: 10,
textAnchor: "end",
fill: axisColor,
};

// accessors
const getDate = (d) => new Date(d.time);
const getStockValue = (d) => d.value;
import { useMemo } from "react";

export default function AreaChart({
data,
gradientColor,
width,
yMax,
margin,
xScale,
yScale,
hideBottomAxis = false,
hideLeftAxis = false,
height,
margin = { top: 0, right: 0, bottom: 0, left: 0 },
top,
left,
hideBottomAxis = false,
hideLeftAxis = false,
children,
onTouchStart,
onTouchMove,
onMouseMove,
onMouseLeave,
xScale,
yScale,
yMax,
}) {
if (width < 10) return null;
return (
<Group left={left || margin.left} top={top || margin.top}>
{/* <LinearGradient
id="gradient"
from={gradientColor}
fromOpacity={1}
to={gradientColor}
toOpacity={0.2}
/> */}
<GradientTealBlue id="gradient" />
<AreaClosed
data={data}
x={(d) => xScale(getDate(d)) || 0}
y={(d) => yScale(getStockValue(d)) || 0}
x={(d) => xScale(getX(d)) || 0}
y={(d) => yScale(getY(d)) || 0}
yScale={yScale}
xScale={xScale}
strokeWidth={1}
stroke="url(#gradient)"
fill="url(#gradient)"
curve={curveMonotoneX}
onTouchStart={onTouchStart}
onTouchMove={onTouchMove}
onMouseMove={onMouseMove}
onMouseLeave={onMouseLeave}
/>
{!hideBottomAxis && (
<AxisBottom
Expand Down
54 changes: 9 additions & 45 deletions src/components/AreaChart.js
Original file line number Diff line number Diff line change
@@ -1,35 +1,28 @@
import { Area, AreaClosed, Bar, Line } from "@visx/shape";
import { AreaClosed, Bar } from "@visx/shape";
import { AxisBottom, AxisLeft, AxisRight } from "@visx/axis";
import { GradientOrangeRed, LinearGradient } from "@visx/gradient";
import { GradientPurpleTeal, GradientTealBlue } from "@visx/gradient";
import { Grid, GridColumns, GridRows } from "@visx/grid";
import {
Tooltip,
TooltipWithBounds,
defaultStyles,
withTooltip,
} from "@visx/tooltip";
import { bisector, extent, max } from "d3-array";
import { currencyFormatter, oneMonth, oneWeek } from "app/core";
import { scaleLinear, scaleTime } from "@visx/scale";
import { useCallback, useMemo, useState } from "react";

import ChartOverlay from "./ChartOverlay";
import { GradientTealBlue } from "@visx/gradient";
import { Group } from "@visx/group";
import { curveMonotoneX } from "@visx/curve";
import { bisector } from "d3-array";
import { deepPurple } from "@material-ui/core/colors";
import { localPoint } from "@visx/event";
import millify from "millify";
import { timeFormat } from "d3-time-format";

export const background = "#fff";
export const background2 = "#e2ebf0";
export const accentColor = "#a18cd1";
export const accentColor2 = "#fbc2eb";

const tooltipStyles = {
...defaultStyles,
background,
background: "#fff",
border: "1px solid white",
color: "inherit",
zIndex: 1702,
Expand All @@ -41,7 +34,7 @@ const getValue = (d) => d.value;

const formatDate = timeFormat("%b %d, '%y");

export default withTooltip(function BarChart({
function AreaChart({
data,
tooltipDisabled = false,
overlayEnabled = false,
Expand Down Expand Up @@ -91,7 +84,6 @@ export default withTooltip(function BarChart({
() =>
scaleTime({
range: [0, xMax],
// domain: extent(data, getDate),
domain: [
Math.min(...data.map(getDate)),
Math.max(...data.map(getDate)),
Expand All @@ -103,7 +95,6 @@ export default withTooltip(function BarChart({
() =>
scaleLinear({
range: [yMax, 0],
// domain: [0, (max(data, getValue) || 0) + yMax / 3],
domain: [
Math.min(...data.map((d) => getValue(d))),
Math.max(...data.map((d) => getValue(d))),
Expand Down Expand Up @@ -152,36 +143,15 @@ export default withTooltip(function BarChart({
<ChartOverlay overlay={overlay} onTimespanChange={onTimespanChange} />
)}
<svg width={width} height={height}>
<GradientPurpleTeal id="purple" />
<GradientTealBlue id="teal" fromOffset={0.5} />
<rect
x={0}
y={0}
width={width}
height={height}
fill="transparent"
// fill="url(#purple)"
// rx={14}
/>
<LinearGradient
id="area-background-gradient"
from={background}
to={background2}
/>
<LinearGradient
id="gradient"
// from={accentColor}
// to={accentColor2}
// toOpacity={0.1}
/>
<rect x={0} y={0} width={width} height={height} fill="transparent" />

<Group top={margin.top} left={margin.left}>
<AreaClosed
data={data}
x={(d) => xScale(getDate(d))}
y={(d) => yScale(getValue(d))}
yScale={yScale}
// fill="url(#gradient)"
fill="url(#teal)"
/>
</Group>
Expand All @@ -207,14 +177,6 @@ export default withTooltip(function BarChart({

{tooltipData && (
<Group top={margin.top} left={margin.left}>
{/* <Line
from={{ x: tooltipLeft, y: -margin.top }}
to={{ x: tooltipLeft, y: yMax }}
stroke={deepPurple[400]}
strokeWidth={2}
pointerEvents="none"
strokeDasharray="5,2"
/> */}
<circle
cx={tooltipLeft}
cy={tooltipTop + 1}
Expand Down Expand Up @@ -263,4 +225,6 @@ export default withTooltip(function BarChart({
)}
</div>
);
});
}

export default withTooltip(AreaChart);
106 changes: 106 additions & 0 deletions src/components/Bar.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
import { AxisBottom, AxisLeft } from "@visx/axis";
import {
axisBottomTickLabelProps,
axisColor,
axisLeftTickLabelProps,
getX,
getY,
} from "app/core";
import { scaleBand, scaleLinear } from "@visx/scale";

import { Bar } from "@visx/shape";
import { GradientTealBlue } from "@visx/gradient";
import { Group } from "@visx/group";
import millify from "millify";
import { useMemo } from "react";

export default function BarChart({
data,
width,
height,
margin = { top: 0, right: 0, bottom: 0, left: 0 },
top,
left,
hideBottomAxis = false,
hideLeftAxis = false,
children,
onTouchStart,
onTouchMove,
onMouseMove,
onMouseLeave,
}) {
// Max
const xMax = width - margin.left - margin.right;
const yMax = height - margin.top - margin.bottom;

// Scales
const xScale = useMemo(
() =>
scaleBand({
range: [0, xMax],
domain: data.map(getX),
}),
[xMax, data]
);

const yScale = useMemo(
() =>
scaleLinear({
range: [yMax, 0],
domain: [Math.min(...data.map(getY)), Math.max(...data.map(getY))],
nice: true,
}),
[yMax, data]
);

if (width < 10) return null;
return (
<Group left={left} top={top}>
<GradientTealBlue id="gradient" />
{data.map((d) => {
const date = getX(d);
const barWidth = xScale.bandwidth();
const barHeight = yMax - (yScale(getY(d)) ?? 0);
const barX = xScale(date);
const barY = yMax - barHeight;
return (
<Bar
key={`bar-${date}`}
x={barX}
y={barY}
width={barWidth}
height={barHeight}
stroke="url(#gradient)"
fill="url(#gradient)"
onTouchStart={onTouchStart}
onTouchMove={onTouchMove}
onMouseMove={onMouseMove}
onMouseLeave={onMouseLeave}
/>
);
})}

{!hideBottomAxis && (
<AxisBottom
top={yMax}
scale={xScale}
numTicks={width > 520 ? 10 : 5}
stroke={axisColor}
tickStroke={axisColor}
tickLabelProps={() => axisBottomTickLabelProps}
/>
)}
{!hideLeftAxis && (
<AxisLeft
scale={yScale}
numTicks={5}
tickFormat={millify}
stroke={axisColor}
tickStroke={axisColor}
tickLabelProps={() => axisLeftTickLabelProps}
/>
)}
{children}
</Group>
);
}
Loading

0 comments on commit dcc26fc

Please sign in to comment.