|
| 1 | +<script lang="ts"> |
| 2 | + import { scaleLinear, scaleRadial, scaleUtc } from 'd3-scale'; |
| 3 | + import { flatGroup, max, min, range } from 'd3-array'; |
| 4 | + import { curveLinearClosed, curveCatmullRomClosed, curveCatmullRom } from 'd3-shape'; |
| 5 | + import { cls } from 'svelte-ux'; |
| 6 | +
|
| 7 | + import Chart, { Svg } from '$lib/components/Chart.svelte'; |
| 8 | + import Area from '$lib/components/Area.svelte'; |
| 9 | + import Axis from '$lib/components/Axis.svelte'; |
| 10 | + import Group from '$lib/components/Group.svelte'; |
| 11 | + import Spline from '$lib/components/Spline.svelte'; |
| 12 | +
|
| 13 | + import Preview from '$lib/docs/Preview.svelte'; |
| 14 | +
|
| 15 | + export let data; |
| 16 | +
|
| 17 | + $: opacityScale = scaleLinear().domain([1940, 2024]).range([0.1, 0.2]); |
| 18 | + $: dataByYear = flatGroup(data.dailyTemperatures, (d) => d.year); |
| 19 | +
|
| 20 | + /** |
| 21 | + * TODO: |
| 22 | + * - [ ] Tooltip (manual with path, radial bisect?). Work with Highlight |
| 23 | + */ |
| 24 | +</script> |
| 25 | + |
| 26 | +<h1>Examples</h1> |
| 27 | + |
| 28 | +<h2>Complex</h2> |
| 29 | + |
| 30 | +<Preview data={data.sfoTemperature}> |
| 31 | + <div class="h-[500px] p-4 border rounded"> |
| 32 | + <Chart |
| 33 | + data={data.sfoTemperature} |
| 34 | + x="date" |
| 35 | + xScale={scaleUtc()} |
| 36 | + xDomain={[new Date('2000-01-01'), new Date('2001-01-01') - 1]} |
| 37 | + xRange={[0, 2 * Math.PI]} |
| 38 | + y="avg" |
| 39 | + yScale={scaleRadial()} |
| 40 | + yDomain={[ |
| 41 | + min(data.sfoTemperature, (d) => d.minmin), |
| 42 | + max(data.sfoTemperature, (d) => d.maxmax), |
| 43 | + ]} |
| 44 | + yRange={({ height }) => [height / 5, height / 2]} |
| 45 | + let:yScale |
| 46 | + > |
| 47 | + <Svg> |
| 48 | + <Group center> |
| 49 | + <Spline radial curve={curveCatmullRom} class="stroke-primary" /> |
| 50 | + <Area |
| 51 | + radial |
| 52 | + y0={(d) => yScale(d.min)} |
| 53 | + y1={(d) => yScale(d.max)} |
| 54 | + curve={curveCatmullRomClosed} |
| 55 | + class="fill-primary/20" |
| 56 | + /> |
| 57 | + <Area |
| 58 | + radial |
| 59 | + y0={(d) => yScale(d.minmin)} |
| 60 | + y1={(d) => yScale(d.maxmax)} |
| 61 | + curve={curveCatmullRomClosed} |
| 62 | + class="fill-primary/20" |
| 63 | + /> |
| 64 | + <Axis placement="angle" grid /> |
| 65 | + <Axis placement="radius" grid /> |
| 66 | + </Group> |
| 67 | + </Svg> |
| 68 | + </Chart> |
| 69 | + </div> |
| 70 | +</Preview> |
| 71 | + |
| 72 | +<h2>Multi line</h2> |
| 73 | + |
| 74 | +<Preview data={data.dailyTemperatures}> |
| 75 | + <div class="h-[500px] p-4 border rounded"> |
| 76 | + <Chart |
| 77 | + data={data.dailyTemperatures} |
| 78 | + x="dayOfYear" |
| 79 | + xRange={[0, 2 * Math.PI]} |
| 80 | + y="value" |
| 81 | + _yDomain={[50, 65]} |
| 82 | + _yRange={({ height }) => [0, height / 2]} |
| 83 | + yRange={({ height }) => [height / 5, height / 2]} |
| 84 | + > |
| 85 | + <Svg> |
| 86 | + <Group center> |
| 87 | + {#each dataByYear as [year, yearData]} |
| 88 | + <Spline |
| 89 | + data={yearData} |
| 90 | + radial |
| 91 | + curve={curveCatmullRom} |
| 92 | + class={cls( |
| 93 | + year === 2024 |
| 94 | + ? 'stroke-primary' |
| 95 | + : year === 2023 |
| 96 | + ? 'stroke-primary/50' |
| 97 | + : 'stroke-surface-content' |
| 98 | + )} |
| 99 | + opacity={[2023, 2024].includes(year) ? 1 : opacityScale(year)} |
| 100 | + /> |
| 101 | + {/each} |
| 102 | + <Axis placement="angle" grid ticks={range(12).map((x) => x * 30)} /> |
| 103 | + <Axis placement="radius" grid format={(d) => ''} /> |
| 104 | + </Group> |
| 105 | + </Svg> |
| 106 | + </Chart> |
| 107 | + </div> |
| 108 | +</Preview> |
0 commit comments