diff --git a/src/Cartesian/Axis.js b/src/Cartesian/Axis.js
index bbd0542..e069b0a 100644
--- a/src/Cartesian/Axis.js
+++ b/src/Cartesian/Axis.js
@@ -1,6 +1,6 @@
import React from "react"
import PropTypes from "prop-types"
-import * as d3 from 'd3'
+import { format } from 'd3-format'
import { useDimensionsContext } from "../Components/Chart";
const axisComponentsByDimension = {
@@ -31,7 +31,7 @@ Axis.propTypes = {
Axis.defaultProps = {
dimension: "x",
scale: null,
- formatTick: d3.format(","),
+ formatTick: format(","),
}
export default Axis
diff --git a/src/Charts/BarChart.js b/src/Charts/BarChart.js
index ee2da60..1375392 100644
--- a/src/Charts/BarChart.js
+++ b/src/Charts/BarChart.js
@@ -1,6 +1,8 @@
import React, { useCallback, useMemo } from "react"
import PropTypes from "prop-types"
-import * as d3 from "d3"
+import { scaleBand, scaleLinear } from 'd3-scale'
+import { max } from 'd3-array'
+import { format } from 'd3-format'
import Chart from "../Components/Chart"
import Bars from "../Components/Bars"
@@ -11,7 +13,7 @@ import { useChartDimensions, accessorPropsType } from "../Utils/utils"
import { useTooltip } from "../Utils/useTooltip"
const DEFAULT_COLOR = '#9980FA'
-const fmt = d3.format(",")
+const fmt = format(",")
const BarChart = ({
data, xAccessor, yAccessor, xLabel, yLabel,
@@ -22,7 +24,7 @@ const BarChart = ({
const { wrapperRef, tooltip, showTooltip, moveTooltip, hideTooltip } = useTooltip()
const xScale = useMemo(() =>
- d3.scaleBand()
+ scaleBand()
.domain(data ? data.map(xAccessor) : [])
.range([0, dimensions.boundedWidth])
.padding(barPadding ?? 0.2),
@@ -30,8 +32,8 @@ const BarChart = ({
)
const yScale = useMemo(() =>
- d3.scaleLinear()
- .domain([yMin ?? 0, d3.max(data, yAccessor) || 0])
+ scaleLinear()
+ .domain([yMin ?? 0, max(data, yAccessor) || 0])
.range([dimensions.boundedHeight, 0])
.nice(),
[data, yAccessor, dimensions.boundedHeight, yMin]
diff --git a/src/Charts/Histogram.js b/src/Charts/Histogram.js
index 6087c00..bf36de9 100644
--- a/src/Charts/Histogram.js
+++ b/src/Charts/Histogram.js
@@ -1,6 +1,8 @@
import React, { useCallback, useMemo } from "react"
import PropTypes from "prop-types"
-import * as d3 from "d3"
+import { scaleLinear } from 'd3-scale'
+import { extent, max, histogram } from 'd3-array'
+import { format } from 'd3-format'
import Chart from "../Components/Chart"
import Bars from "../Components/Bars"
@@ -13,8 +15,8 @@ import { useTooltip } from "../Utils/useTooltip"
const DEFAULT_GRADIENT = ["#9980FA", "rgb(226, 222, 243)"]
const DEFAULT_COLOR = '#9980FA'
-const fmt = d3.format(",")
-const fmtFixed = d3.format(",.2~f")
+const fmt = format(",")
+const fmtFixed = format(",.2~f")
const BAR_PADDING = 2
const Histogram = ({
@@ -30,15 +32,15 @@ const Histogram = ({
const numberOfThresholds = thresholds || 9
const xScale = useMemo(() =>
- d3.scaleLinear()
- .domain(d3.extent(data, xAccessor))
+ scaleLinear()
+ .domain(extent(data, xAccessor))
.range([0, dimensions.boundedWidth])
.nice(numberOfThresholds),
[data, xAccessor, dimensions.boundedWidth, numberOfThresholds]
)
const bins = useMemo(() =>
- d3.histogram()
+ histogram()
.domain(xScale.domain())
.value(xAccessor)
.thresholds(xScale.ticks(numberOfThresholds))(data),
@@ -46,8 +48,8 @@ const Histogram = ({
)
const yScale = useMemo(() =>
- d3.scaleLinear()
- .domain([0, d3.max(bins, d => d.length) || 0])
+ scaleLinear()
+ .domain([0, max(bins, d => d.length) || 0])
.range([dimensions.boundedHeight, 0])
.nice(),
[bins, dimensions.boundedHeight]
diff --git a/src/Charts/PieChart.js b/src/Charts/PieChart.js
index 11bc32c..c4b8c4f 100644
--- a/src/Charts/PieChart.js
+++ b/src/Charts/PieChart.js
@@ -1,6 +1,10 @@
import React, { useCallback, useMemo } from "react"
import PropTypes from "prop-types"
-import * as d3 from "d3"
+import { scaleOrdinal } from 'd3-scale'
+import { arc, pie } from 'd3-shape'
+import { sum } from 'd3-array'
+import { schemeSet2 } from 'd3-scale-chromatic'
+import { format } from 'd3-format'
import Chart from "../Components/Chart"
import ChartLayout from "../Components/ChartLayout"
@@ -10,7 +14,7 @@ import { useTooltip } from "../Utils/useTooltip"
const DEFAULT_MARGIN = { marginTop: 20, marginRight: 20, marginBottom: 20, marginLeft: 20 }
const MIN_LABEL_ANGLE = 0.35
-const fmt = d3.format(",")
+const fmt = format(",")
const PieChart = ({
data, valueAccessor, labelAccessor,
@@ -21,7 +25,7 @@ const PieChart = ({
const { wrapperRef, tooltip, showTooltip, moveTooltip, hideTooltip } = useTooltip()
const colorScale = useMemo(() =>
- d3.scaleOrdinal(Array.isArray(colors) ? colors : d3.schemeSet2),
+ scaleOrdinal(Array.isArray(colors) ? colors : schemeSet2),
[colors]
)
@@ -34,7 +38,7 @@ const PieChart = ({
: 0
const arcGenerator = useMemo(() =>
- d3.arc().innerRadius(resolvedInnerRadius).outerRadius(outerRadius),
+ arc().innerRadius(resolvedInnerRadius).outerRadius(outerRadius),
[resolvedInnerRadius, outerRadius]
)
@@ -42,11 +46,11 @@ const PieChart = ({
const r = resolvedInnerRadius > 0
? (resolvedInnerRadius + outerRadius) / 2
: outerRadius * 0.65
- return d3.arc().innerRadius(r).outerRadius(r)
+ return arc().innerRadius(r).outerRadius(r)
}, [resolvedInnerRadius, outerRadius])
const arcs = useMemo(() =>
- data ? d3.pie()
+ data ? pie()
.value(valueAccessor)
.padAngle(padAngle ?? 0.02)
.sort(null)(data)
@@ -55,7 +59,7 @@ const PieChart = ({
)
const total = useMemo(() =>
- data ? d3.sum(data, valueAccessor) : 0,
+ data ? sum(data, valueAccessor) : 0,
[data, valueAccessor]
)
@@ -95,22 +99,22 @@ const PieChart = ({
- {arcs.map((arc, i) => {
+ {arcs.map((a, i) => {
const label = labelAccessor ? labelAccessor(data[i]) : String(i)
return (
handleSliceEnter(data[i], label, e)}
onMouseMove={e => handleSliceMove(data[i], label, e)}
onMouseLeave={hideTooltip}
/>
- {displayLabels && (arc.endAngle - arc.startAngle) >= MIN_LABEL_ANGLE && (
+ {displayLabels && (a.endAngle - a.startAngle) >= MIN_LABEL_ANGLE && (
{label}
diff --git a/src/Charts/ScatterPlot.js b/src/Charts/ScatterPlot.js
index 29589c0..1d9a432 100644
--- a/src/Charts/ScatterPlot.js
+++ b/src/Charts/ScatterPlot.js
@@ -1,6 +1,8 @@
import React, { useCallback, useMemo } from "react"
import PropTypes from "prop-types"
-import * as d3 from "d3"
+import { scaleLinear } from 'd3-scale'
+import { extent } from 'd3-array'
+import { format } from 'd3-format'
import Chart from "../Components/Chart"
import Circles from "../Components/Circles"
@@ -11,7 +13,7 @@ import { useChartDimensions, accessorPropsType } from "../Utils/utils"
import { useTooltip } from "../Utils/useTooltip"
const DEFAULT_COLOR = '#9980FA'
-const fmt = d3.format(",")
+const fmt = format(",")
const ScatterPlot = ({
data, xAccessor, yAccessor, xLabel, yLabel,
@@ -22,15 +24,15 @@ const ScatterPlot = ({
const { wrapperRef, tooltip, showTooltip, moveTooltip, hideTooltip } = useTooltip()
const xScale = useMemo(() => {
- const extent = d3.extent(data, xAccessor)
- const domain = extent[0] === extent[1] ? [extent[0] - 1, extent[0] + 1] : extent
- return d3.scaleLinear().domain(domain).range([0, dimensions.boundedWidth]).nice()
+ const ext = extent(data, xAccessor)
+ const domain = ext[0] === ext[1] ? [ext[0] - 1, ext[0] + 1] : ext
+ return scaleLinear().domain(domain).range([0, dimensions.boundedWidth]).nice()
}, [data, xAccessor, dimensions.boundedWidth])
const yScale = useMemo(() => {
- const extent = d3.extent(data, yAccessor)
- const domain = extent[0] === extent[1] ? [extent[0] - 1, extent[0] + 1] : extent
- return d3.scaleLinear().domain(domain).range([dimensions.boundedHeight, 0]).nice()
+ const ext = extent(data, yAccessor)
+ const domain = ext[0] === ext[1] ? [ext[0] - 1, ext[0] + 1] : ext
+ return scaleLinear().domain(domain).range([dimensions.boundedHeight, 0]).nice()
}, [data, yAccessor, dimensions.boundedHeight])
const legendItems = useMemo(() =>
diff --git a/src/Charts/StackedBarChart.js b/src/Charts/StackedBarChart.js
index 9f706f1..4c70efa 100644
--- a/src/Charts/StackedBarChart.js
+++ b/src/Charts/StackedBarChart.js
@@ -1,6 +1,10 @@
import React, { useCallback, useMemo } from "react"
import PropTypes from "prop-types"
-import * as d3 from "d3"
+import { scaleOrdinal, scaleBand, scaleLinear } from 'd3-scale'
+import { stack } from 'd3-shape'
+import { max } from 'd3-array'
+import { schemeSet2 } from 'd3-scale-chromatic'
+import { format } from 'd3-format'
import Chart from "../Components/Chart"
import Axis from "../Cartesian/Axis"
@@ -9,7 +13,7 @@ import Tooltip from "../Components/Tooltip"
import { useChartDimensions, accessorPropsType } from "../Utils/utils"
import { useTooltip } from "../Utils/useTooltip"
-const fmt = d3.format(",")
+const fmt = format(",")
const StackedBarChart = ({
data, xAccessor, keys, colors,
@@ -20,17 +24,17 @@ const StackedBarChart = ({
const { wrapperRef, tooltip, showTooltip, moveTooltip, hideTooltip } = useTooltip()
const colorScale = useMemo(() =>
- d3.scaleOrdinal(Array.isArray(colors) ? colors : d3.schemeSet2).domain(keys),
+ scaleOrdinal(Array.isArray(colors) ? colors : schemeSet2).domain(keys),
[colors, keys]
)
const series = useMemo(() =>
- data && keys && keys.length ? d3.stack().keys(keys)(data) : [],
+ data && keys && keys.length ? stack().keys(keys)(data) : [],
[data, keys]
)
const xScale = useMemo(() =>
- d3.scaleBand()
+ scaleBand()
.domain(data ? data.map(xAccessor) : [])
.range([0, dimensions.boundedWidth])
.padding(barPadding ?? 0.2),
@@ -38,8 +42,8 @@ const StackedBarChart = ({
)
const yScale = useMemo(() =>
- d3.scaleLinear()
- .domain([0, d3.max(series, s => d3.max(s, d => d[1])) || 0])
+ scaleLinear()
+ .domain([0, max(series, s => max(s, d => d[1])) || 0])
.range([dimensions.boundedHeight, 0])
.nice(),
[series, dimensions.boundedHeight]
diff --git a/src/Charts/Timeline.js b/src/Charts/Timeline.js
index 624c535..c93a77f 100644
--- a/src/Charts/Timeline.js
+++ b/src/Charts/Timeline.js
@@ -1,6 +1,9 @@
import React, { useCallback, useMemo, useState } from "react"
import PropTypes from "prop-types"
-import * as d3 from "d3"
+import { scaleTime, scaleLinear } from 'd3-scale'
+import { extent, bisector } from 'd3-array'
+import { timeFormat } from 'd3-time-format'
+import { format } from 'd3-format'
import Chart from "../Components/Chart"
import Line from "../Components/Line"
@@ -12,11 +15,11 @@ import Tooltip from "../Components/Tooltip"
import { useChartDimensions, accessorPropsType, useUniqueId } from "../Utils/utils"
import { useTooltip } from "../Utils/useTooltip"
-const formatDate = d3.timeFormat("%-b %-d")
-const formatTooltipDate = d3.timeFormat("%-b %-d, %Y")
+const formatDate = timeFormat("%-b %-d")
+const formatTooltipDate = timeFormat("%-b %-d, %Y")
const DEFAULT_GRADIENT = ["rgb(226, 222, 243)", "#f8f9fa"]
const DEFAULT_COLOR = '#9980FA'
-const fmt = d3.format(",")
+const fmt = format(",")
const Timeline = ({
data, xAccessor, yAccessor, xLabel, yLabel,
@@ -34,15 +37,15 @@ const Timeline = ({
|| (color ? [`${color}55`, "rgba(255,255,255,0)"] : DEFAULT_GRADIENT)
const xScale = useMemo(() =>
- d3.scaleTime()
- .domain(d3.extent(data, xAccessor))
+ scaleTime()
+ .domain(extent(data, xAccessor))
.range([0, dimensions.boundedWidth]),
[data, xAccessor, dimensions.boundedWidth]
)
const yScale = useMemo(() =>
- d3.scaleLinear()
- .domain(d3.extent(data, yAccessor))
+ scaleLinear()
+ .domain(extent(data, yAccessor))
.range([dimensions.boundedHeight, 0])
.nice(),
[data, yAccessor, dimensions.boundedHeight]
@@ -53,20 +56,20 @@ const Timeline = ({
[yLabel, color]
)
- const bisect = useMemo(() => d3.bisector(xAccessor).left, [xAccessor])
+ const dateBisector = useMemo(() => bisector(xAccessor).left, [xAccessor])
const handleMouseMove = useCallback(e => {
const svgEl = e.currentTarget.ownerSVGElement
const { left: svgLeft } = svgEl.getBoundingClientRect()
const mouseX = e.clientX - svgLeft - dimensions.marginLeft
const date = xScale.invert(mouseX)
- const idx = bisect(data, date, 1)
+ const idx = dateBisector(data, date, 1)
const d0 = data[idx - 1]
const d1 = data[idx]
const i = !d1 || (d0 && date - xAccessor(d0) < xAccessor(d1) - date) ? idx - 1 : idx
setHoveredIndex(i)
showTooltip(e, { datum: data[i] })
- }, [data, xAccessor, xScale, bisect, dimensions.marginLeft, showTooltip])
+ }, [data, xAccessor, xScale, dateBisector, dimensions.marginLeft, showTooltip])
const handleMouseLeave = useCallback(() => {
setHoveredIndex(null)
diff --git a/src/Components/Bars.js b/src/Components/Bars.js
index af32fa7..f9ba6dc 100644
--- a/src/Components/Bars.js
+++ b/src/Components/Bars.js
@@ -1,6 +1,6 @@
import React from "react"
import PropTypes from "prop-types"
-import * as d3 from 'd3'
+import { max } from 'd3-array'
import { accessorPropsType, callAccessor } from "../Utils/utils";
const Bars = ({ data, keyAccessor, xAccessor, yAccessor, widthAccessor, heightAccessor, onMouseEnter, onMouseLeave, onMouseMove, ...props }) => (
@@ -11,8 +11,8 @@ const Bars = ({ data, keyAccessor, xAccessor, yAccessor, widthAccessor, heightAc
key={keyAccessor(d, i)}
x={callAccessor(xAccessor, d, i)}
y={callAccessor(yAccessor, d, i)}
- width={d3.max([callAccessor(widthAccessor, d, i), 0])}
- height={d3.max([callAccessor(heightAccessor, d, i), 0])}
+ width={max([callAccessor(widthAccessor, d, i), 0])}
+ height={max([callAccessor(heightAccessor, d, i), 0])}
onMouseEnter={onMouseEnter ? e => onMouseEnter(d, i, e) : undefined}
onMouseLeave={onMouseLeave ? e => onMouseLeave(d, i, e) : undefined}
onMouseMove={onMouseMove ? e => onMouseMove(d, i, e) : undefined}
diff --git a/src/Components/Line.js b/src/Components/Line.js
index 660863a..131be72 100644
--- a/src/Components/Line.js
+++ b/src/Components/Line.js
@@ -1,10 +1,12 @@
import React from "react"
import PropTypes from "prop-types"
-import * as d3 from "d3"
+import { line, area, curveMonotoneX } from 'd3-shape'
import { accessorPropsType } from "../Utils/utils";
+const generators = { line, area }
+
const Line = ({ type, data, xAccessor, yAccessor, y0Accessor, interpolation, ...props }) => {
- const lineGenerator = d3[type]()
+ const lineGenerator = generators[type]()
.x(xAccessor)
.y(yAccessor)
.curve(interpolation)
@@ -35,7 +37,7 @@ Line.propTypes = {
Line.defaultProps = {
type: "line",
y0Accessor: 0,
- interpolation: d3.curveMonotoneX,
+ interpolation: curveMonotoneX,
}
export default Line