Skip to content

Commit

Permalink
[Brush] Begin to support scaleBand() (Bar charts)
Browse files Browse the repository at this point in the history
  • Loading branch information
techniq committed Jul 19, 2024
1 parent 67fbd8d commit 3248970
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 7 deletions.
5 changes: 5 additions & 0 deletions .changeset/metal-windows-wait.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'layerchart': minor
---

[Brush] Support scaleBand() (Bar charts)
10 changes: 6 additions & 4 deletions packages/layerchart/src/lib/components/Brush.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import { chartContext } from './ChartContext.svelte';
import Frame from './Frame.svelte';
import { localPoint } from '$lib/utils/event.js';
import { scaleInvert } from '$lib/utils/scales.js';
import Group from './Group.svelte';
const { xScale, yScale, width, height, padding } = chartContext();
Expand Down Expand Up @@ -68,21 +69,22 @@
) => void
) {
return (e: PointerEvent) => {
// TODO: Handle scaleBand domains
const start = {
xDomain: [xDomain[0] ?? xDomainMin, xDomain[1] ?? xDomainMax] as [number, number],
yDomain: [yDomain[0] ?? yDomainMin, yDomain[1] ?? yDomainMax] as [number, number],
value: {
x: $xScale.invert?.(localPoint(frameEl, e)?.x ?? 0 - $padding.left),
y: $yScale.invert?.(localPoint(frameEl, e)?.y ?? 0 - $padding.top),
x: scaleInvert($xScale, localPoint(frameEl, e)?.x ?? 0 - $padding.left),
y: scaleInvert($yScale, localPoint(frameEl, e)?.y ?? 0 - $padding.top),
},
};
dispatch('brushStart', { xDomain, yDomain });
const onPointerMove = (e: PointerEvent) => {
fn(start, {
x: $xScale.invert?.(localPoint(frameEl, e)?.x ?? 0 - $padding.left),
y: $yScale.invert?.(localPoint(frameEl, e)?.y ?? 0 - $padding.top),
x: scaleInvert($xScale, localPoint(frameEl, e)?.x ?? 0 - $padding.left),
y: scaleInvert($yScale, localPoint(frameEl, e)?.y ?? 0 - $padding.top),
});
// if (xDomain[0] === xDomain[1] || yDomain[0] === yDomain[1]) {
Expand Down
67 changes: 64 additions & 3 deletions packages/layerchart/src/routes/docs/components/Brush/+page.svelte
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
<script lang="ts">
import { scaleOrdinal, scaleTime } from 'd3-scale';
import { range } from 'd3-array';
import { PeriodType, State, cls, format } from 'svelte-ux';
import { scaleBand, scaleOrdinal, scaleTime } from 'd3-scale';
import { bin, range, sum } from 'd3-array';
import { timeMonths } from 'd3-time';
import { PeriodType, State, cls, format, formatDate } from 'svelte-ux';
import { subDays } from 'date-fns';
import { mdiChevronRight } from '@mdi/js';
Expand All @@ -19,6 +20,7 @@
Rule,
Tooltip,
Svg,
Bars,
} from 'layerchart';
import Preview from '$lib/docs/Preview.svelte';
Expand All @@ -39,10 +41,69 @@
const randomData = range(200).map((d) => {
return { x: d, y: Math.random() };
});
$: binByTime = bin()
.thresholds((_data, min, max) => timeMonths(min, max))
.value((d) => d.date);
$: appleStockBinByMonth = binByTime(data.appleStock);
// Simplify data for simplier brush example
$: appleStockByMonth = appleStockBinByMonth.map((monthBin) => {
return {
date: monthBin.x0,
value: sum(monthBin, (d) => d.value),
};
});
</script>

<h1>Examples</h1>

<h2>Bar (scaleBand) support</h2>

<Preview data={appleStockByMonth}>
<div class="border rounded p-4 grid gap-1">
<State initial={[null, null]} let:value={xDomain} let:set>
<div class="h-[300px]">
<Chart
_data={appleStockByMonth}
data={appleStockByMonth.filter(
(d) =>
(xDomain[0] == null || d.date >= xDomain[0]) &&
(xDomain[1] == null || d.date <= xDomain[1])
)}
x="date"
xScale={scaleBand().padding(0.2)}
y="value"
yDomain={[0, null]}
yNice
padding={{ left: 24, bottom: 24 }}
>
<Svg>
<Axis placement="left" grid rule />
<Axis
placement="bottom"
rule
ticks={(scale) => scaleTime(scale.domain(), scale.range()).ticks(4)}
format={(value) => formatDate(value, PeriodType.Custom, { custom: 'MMM yyyy' })}
/>
<ChartClipPath>
<Bars radius={4} strokeWidth={1} class="fill-primary" />
</ChartClipPath>

<Brush
axis="x"
resetOnEnd
on:brushEnd={(e) => {
console.log(e.detail);
set(e.detail.xDomain);
}}
/>
</Svg>
</Chart>
</div>
</State>
</div>
</Preview>

<h2>Styling via classes</h2>

<Preview data={data.appleStock}>
Expand Down

0 comments on commit 3248970

Please sign in to comment.