@rokkit/chart 1.0.0-next.87 → 1.0.0-next.89
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +11 -6
- package/src/Chart.svelte +67 -0
- package/src/PatternDefs.svelte +14 -0
- package/src/Symbol.svelte +17 -0
- package/src/{chart/Texture.svelte → Texture.svelte} +3 -3
- package/src/elements/Bar.svelte +2 -2
- package/src/elements/ContinuousLegend.svelte +3 -2
- package/src/elements/DefinePatterns.svelte +22 -0
- package/src/elements/DiscreteLegend.svelte +1 -1
- package/src/elements/Label.svelte +7 -5
- package/src/elements/SymbolGrid.svelte +23 -0
- package/src/elements/index.js +6 -0
- package/src/index.js +5 -15
- package/src/lib/brewer.js +17 -0
- package/src/lib/chart.js +179 -160
- package/src/lib/grid.js +68 -0
- package/src/lib/index.js +4 -0
- package/src/lib/palette.js +279 -28
- package/src/lib/plots.js +23 -0
- package/src/lib/swatch.js +24 -8
- package/src/lib/ticks.js +19 -0
- package/src/patterns/Brick.svelte +17 -0
- package/src/patterns/Circles.svelte +18 -0
- package/src/patterns/CrossHatch.svelte +14 -0
- package/src/patterns/CurvedWave.svelte +9 -0
- package/src/patterns/Dots.svelte +19 -0
- package/src/patterns/OutlineCircles.svelte +15 -0
- package/src/patterns/Texture.svelte +20 -0
- package/src/patterns/Tile.svelte +17 -0
- package/src/patterns/Triangles.svelte +15 -0
- package/src/patterns/Waves.svelte +13 -0
- package/src/patterns/constants.js +43 -0
- package/src/patterns/index.js +13 -0
- package/src/patterns/paths/NamedPattern.svelte +12 -0
- package/src/patterns/paths/constants.js +7 -0
- package/src/patterns/templates/Circles.svelte +18 -0
- package/src/patterns/templates/Lines.svelte +17 -0
- package/src/patterns/templates/Path.svelte +17 -0
- package/src/patterns/templates/index.js +3 -0
- package/src/plots/Plot.svelte +36 -21
- package/src/plots/index.js +1 -10
- package/src/symbols/RoundedSquare.svelte +27 -0
- package/src/symbols/Shape.svelte +31 -0
- package/src/symbols/constants/index.js +7 -0
- package/src/symbols/index.js +9 -0
- package/src/chart/Axis.svelte +0 -81
- package/src/chart/AxisGrid.svelte +0 -22
- package/src/chart/Chart.svelte +0 -40
- package/src/chart/FacetGrid.svelte +0 -49
- package/src/chart/Legend.svelte +0 -16
- package/src/chart/Swatch.svelte +0 -84
- package/src/chart/SwatchButton.svelte +0 -29
- package/src/chart/SwatchGrid.svelte +0 -53
- package/src/chart/TexturedShape.svelte +0 -20
- package/src/chart/TimelapseChart.svelte +0 -90
- package/src/chart/Timer.svelte +0 -27
- package/src/elements/Tooltip.svelte +0 -19
- package/src/lib/axis.js +0 -77
- package/src/lib/color.js +0 -55
- package/src/lib/constants.js +0 -41
- package/src/lib/funnel.js +0 -230
- package/src/lib/geom.js +0 -99
- package/src/lib/heatmap.js +0 -68
- package/src/lib/lookup.js +0 -29
- package/src/lib/pattern.js +0 -182
- package/src/lib/rollup.js +0 -49
- package/src/lib/shape.js +0 -46
- package/src/lib/store.js +0 -63
- package/src/lib/summary.js +0 -28
- package/src/lib/theme.js +0 -31
- package/src/lib/utils.js +0 -158
- package/src/plots/BarPlot.svelte +0 -51
- package/src/plots/BarPlot2.svelte +0 -34
- package/src/plots/BoxPlot.svelte +0 -54
- package/src/plots/FunnelPlot.svelte +0 -26
- package/src/plots/HeatMapCalendar.svelte +0 -121
- package/src/plots/LinePlot.svelte +0 -51
- package/src/plots/RankBarPlot.svelte +0 -38
- package/src/plots/ScatterPlot.svelte +0 -28
- package/src/plots/ViolinPlot.svelte +0 -10
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
import { scaledPath } from '@rokkit/core'
|
|
3
|
+
|
|
4
|
+
export let size = 10
|
|
5
|
+
export let thickness = 0.5
|
|
6
|
+
export let stroke = 'currentColor'
|
|
7
|
+
|
|
8
|
+
const paths = [
|
|
9
|
+
['M', 0, 0.25],
|
|
10
|
+
['A', 0.6, 0.5, 0, 0, 0, 1, 0.25]
|
|
11
|
+
// ['M', 0, 0.75],
|
|
12
|
+
// ['A', 0.6, 0.5, 0, 0, 0, 1, 0.75]
|
|
13
|
+
]
|
|
14
|
+
$: d = scaledPath(size, paths)
|
|
15
|
+
</script>
|
|
16
|
+
|
|
17
|
+
<path {d} {stroke} stroke-width={thickness} fill="none" />
|
package/src/plots/Plot.svelte
CHANGED
|
@@ -1,25 +1,40 @@
|
|
|
1
1
|
<script>
|
|
2
|
-
import {
|
|
2
|
+
import { plotter } from '../lib/plots'
|
|
3
|
+
import { compact } from '@rokkit/core'
|
|
4
|
+
export let data = []
|
|
5
|
+
/** @type {'lineY'|'lineX'|'dot'|'plot'|'bar'} */
|
|
6
|
+
export let type = 'dot'
|
|
7
|
+
export let width = null
|
|
8
|
+
export let height = null
|
|
9
|
+
export let x = 'x'
|
|
10
|
+
export let y = 'y'
|
|
11
|
+
export let fill = null
|
|
12
|
+
export let stroke = null
|
|
13
|
+
export let symbol = null
|
|
14
|
+
export let grid = true
|
|
15
|
+
export let legend = false
|
|
16
|
+
export let labels = {}
|
|
17
|
+
export let tip = true
|
|
18
|
+
export let channels = null
|
|
3
19
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
20
|
+
$: showLegend = compact({
|
|
21
|
+
stroke: stroke ? { legend } : null,
|
|
22
|
+
color: fill && !symbol ? { legend } : null,
|
|
23
|
+
symbol: symbol ? { legend } : null
|
|
24
|
+
})
|
|
25
|
+
$: config = {
|
|
26
|
+
data,
|
|
27
|
+
type,
|
|
28
|
+
aes: compact({ x, y, fill, stroke, symbol, tip, channels }),
|
|
29
|
+
opts: compact({
|
|
30
|
+
width,
|
|
31
|
+
height,
|
|
32
|
+
grid,
|
|
33
|
+
...showLegend,
|
|
34
|
+
x: { label: labels?.x ?? x },
|
|
35
|
+
y: { label: labels?.y ?? y }
|
|
36
|
+
})
|
|
37
|
+
}
|
|
16
38
|
</script>
|
|
17
39
|
|
|
18
|
-
<
|
|
19
|
-
{#if plots.includes('box')}
|
|
20
|
-
<BoxPlot data={nested} {...scales} />
|
|
21
|
-
{/if}
|
|
22
|
-
{#if plots.includes('scatter')}
|
|
23
|
-
<ScatterPlot {data} {x} {y} {...scales} />
|
|
24
|
-
{/if}
|
|
25
|
-
</svg>
|
|
40
|
+
<plot use:plotter={config} />
|
package/src/plots/index.js
CHANGED
|
@@ -1,10 +1 @@
|
|
|
1
|
-
export { default as
|
|
2
|
-
export { default as BoxPlot } from './BoxPlot.svelte'
|
|
3
|
-
export { default as Bar } from './BarPlot.svelte'
|
|
4
|
-
export { default as BarPlot } from './BarPlot.svelte'
|
|
5
|
-
export { default as Line } from './LinePlot.svelte'
|
|
6
|
-
export { default as LinePlot } from './LinePlot.svelte'
|
|
7
|
-
export { default as Violin } from './ViolinPlot.svelte'
|
|
8
|
-
export { default as ViolinPlot } from './ViolinPlot.svelte'
|
|
9
|
-
export { default as Scatter } from './old_ScatterPlot.svelte'
|
|
10
|
-
export { default as ScatterPlot } from './old_ScatterPlot.svelte'
|
|
1
|
+
export { default as Plot } from './Plot.svelte'
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
export let x = 0
|
|
3
|
+
export let y = 0
|
|
4
|
+
export let size = 1
|
|
5
|
+
export let fill = 'currentColor'
|
|
6
|
+
export let stroke = 'currentColor'
|
|
7
|
+
|
|
8
|
+
$: r = size * 3.534
|
|
9
|
+
$: props = { rx: r * 0.1, ry: r * 0.1, ...$$restProps }
|
|
10
|
+
</script>
|
|
11
|
+
|
|
12
|
+
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
|
13
|
+
<rect
|
|
14
|
+
x={x - r}
|
|
15
|
+
y={y - r}
|
|
16
|
+
width={r * 2}
|
|
17
|
+
height={r * 2}
|
|
18
|
+
{fill}
|
|
19
|
+
{stroke}
|
|
20
|
+
{...props}
|
|
21
|
+
role="button"
|
|
22
|
+
on:click
|
|
23
|
+
on:mouseover
|
|
24
|
+
on:mouseleave
|
|
25
|
+
on:focus
|
|
26
|
+
tabindex="0"
|
|
27
|
+
/>
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
import { namedShapes } from './constants'
|
|
3
|
+
|
|
4
|
+
export let x = 0
|
|
5
|
+
export let y = 0
|
|
6
|
+
export let size = 1
|
|
7
|
+
export let fill = 'none'
|
|
8
|
+
export let stroke = 'currentColor'
|
|
9
|
+
export let thickness = 1
|
|
10
|
+
|
|
11
|
+
export let name = 'circle'
|
|
12
|
+
|
|
13
|
+
$: d = name in namedShapes ? namedShapes[name](size) : namedShapes['star'](size)
|
|
14
|
+
</script>
|
|
15
|
+
|
|
16
|
+
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
|
17
|
+
<path
|
|
18
|
+
{d}
|
|
19
|
+
{fill}
|
|
20
|
+
{stroke}
|
|
21
|
+
transform="translate({x},{y})"
|
|
22
|
+
stroke-width={thickness}
|
|
23
|
+
fill-rule="evenodd"
|
|
24
|
+
role="button"
|
|
25
|
+
on:click
|
|
26
|
+
on:mouseover
|
|
27
|
+
on:mouseleave
|
|
28
|
+
on:focus
|
|
29
|
+
on:blur
|
|
30
|
+
tabindex="0"
|
|
31
|
+
/>
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { namedShapes } from './constants'
|
|
2
|
+
import { default as Shape } from './Shape.svelte'
|
|
3
|
+
import { default as RoundedSquare } from './RoundedSquare.svelte'
|
|
4
|
+
|
|
5
|
+
export const shapes = [...Object.keys(namedShapes), 'rounded-square']
|
|
6
|
+
export const components = {
|
|
7
|
+
default: Shape,
|
|
8
|
+
'rounded-square': RoundedSquare
|
|
9
|
+
}
|
package/src/chart/Axis.svelte
DELETED
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
<script>
|
|
2
|
-
import { getContext } from 'svelte'
|
|
3
|
-
const chart = getContext('chart')
|
|
4
|
-
|
|
5
|
-
export let orient = 'bottom'
|
|
6
|
-
export let majorTickStep = 0
|
|
7
|
-
export let minorTickStep = 0
|
|
8
|
-
export let lower = 0
|
|
9
|
-
export let upper = 100
|
|
10
|
-
|
|
11
|
-
function getTicks(lower, upper, majorTickStep, minorTickStep) {
|
|
12
|
-
if (majorTickStep === 0 && minorTickStep === 0) return []
|
|
13
|
-
const minorTicks = Array.from(
|
|
14
|
-
{ length: Math.floor((upper - lower) / minorTickStep) + 1 },
|
|
15
|
-
(_, i) => ({
|
|
16
|
-
position: i * minorTickStep,
|
|
17
|
-
label: i * minorTickStep,
|
|
18
|
-
type: 'minor'
|
|
19
|
-
})
|
|
20
|
-
)
|
|
21
|
-
const majorTicks = Array.from(
|
|
22
|
-
{ length: Math.floor((upper - lower) / majorTickStep) + 1 },
|
|
23
|
-
(_, i) => ({
|
|
24
|
-
position: i * majorTickStep,
|
|
25
|
-
label: i * majorTickStep,
|
|
26
|
-
type: 'major'
|
|
27
|
-
})
|
|
28
|
-
)
|
|
29
|
-
const end = [
|
|
30
|
-
{ position: upper, label: upper, type: 'end' },
|
|
31
|
-
{ position: lower, label: lower, type: 'end' }
|
|
32
|
-
]
|
|
33
|
-
|
|
34
|
-
return [...minorTicks, ...majorTicks, ...end].sort((a, b) => a.position - b.position)
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
let top = orient === 'bottom' ? $chart.height - $chart.margin.bottom : $chart.margin.top
|
|
38
|
-
let left = orient === 'right' ? $chart.width - $chart.margin.right : $chart.margin.left
|
|
39
|
-
|
|
40
|
-
let tickPadding = $chart.theme.tick.size.padding
|
|
41
|
-
|
|
42
|
-
function axisPath(vertical) {
|
|
43
|
-
const range = [lower, upper]
|
|
44
|
-
const size = $chart.theme.tick.size.end
|
|
45
|
-
return vertical
|
|
46
|
-
? `M${k * size},${range[0]}H0V${range[1]}H${k * size}`
|
|
47
|
-
: `M${range[0]},${k * size}V0H${range[1]}V${k * size}`
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
$: anchor = orient === 'right' ? 'start' : orient === 'left' ? 'end' : 'middle'
|
|
51
|
-
$: k = orient === 'top' || orient === 'left' ? -1 : 1
|
|
52
|
-
$: dy = orient === 'top' ? '0em' : orient === 'bottom' ? '0.71em' : '0.32em'
|
|
53
|
-
$: vertical = orient === 'left' || orient === 'right'
|
|
54
|
-
$: ticks = getTicks(lower, upper, majorTickStep, minorTickStep)
|
|
55
|
-
</script>
|
|
56
|
-
|
|
57
|
-
<g
|
|
58
|
-
transform="translate({vertical ? left : 0},{vertical ? 0 : top})"
|
|
59
|
-
fill="none"
|
|
60
|
-
font-size="10"
|
|
61
|
-
font-family="sans-serif"
|
|
62
|
-
text-anchor={anchor}
|
|
63
|
-
class="axis"
|
|
64
|
-
>
|
|
65
|
-
<path class="domain" stroke="currentColor" d="{axisPath(vertical)}}" />
|
|
66
|
-
{#each ticks as tick}
|
|
67
|
-
{@const size = $chart.theme.tick.size[tick.type]}
|
|
68
|
-
<g
|
|
69
|
-
class="tick"
|
|
70
|
-
transform="translate({vertical ? 0 : tick.position},{vertical ? tick.position : 0})"
|
|
71
|
-
>
|
|
72
|
-
<line stroke="currentColor" y2={vertical ? 0 : k * size} x2={vertical ? k * size : 0} />
|
|
73
|
-
<text
|
|
74
|
-
fill="currentColor"
|
|
75
|
-
y={vertical ? 0 : k * (size + tickPadding)}
|
|
76
|
-
x={vertical ? k * (size + tickPadding) : 0}
|
|
77
|
-
{dy}>{tick.label}</text
|
|
78
|
-
>
|
|
79
|
-
</g>
|
|
80
|
-
{/each}
|
|
81
|
-
</g>
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
<script>
|
|
2
|
-
import { getContext } from 'svelte'
|
|
3
|
-
|
|
4
|
-
export let opacity = 1
|
|
5
|
-
export let hideVertical = false
|
|
6
|
-
export let hideHorizontal = false
|
|
7
|
-
let chart = getContext('chart')
|
|
8
|
-
|
|
9
|
-
$: opacityV = hideVertical ? 0 : opacity
|
|
10
|
-
$: opacityH = hideHorizontal ? 0 : opacity
|
|
11
|
-
$: xRange = $chart.axis.x.scale.range()
|
|
12
|
-
$: yRange = $chart.axis.y.scale.range()
|
|
13
|
-
</script>
|
|
14
|
-
|
|
15
|
-
<g class="grid">
|
|
16
|
-
{#each $chart.axis.x.ticks as tick}
|
|
17
|
-
<line x1={tick.position} x2={tick.position} y1={yRange[0]} y2={yRange[1]} opacity={opacityV} />
|
|
18
|
-
{/each}
|
|
19
|
-
{#each $chart.axis.y.ticks as tick}
|
|
20
|
-
<line y1={tick.position} y2={tick.position} x1={xRange[0]} x2={xRange[1]} opacity={opacityH} />
|
|
21
|
-
{/each}
|
|
22
|
-
</g>
|
package/src/chart/Chart.svelte
DELETED
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
<script>
|
|
2
|
-
import { setContext } from 'svelte'
|
|
3
|
-
import { writable } from 'svelte/store'
|
|
4
|
-
import { compact } from '@rokkit/core'
|
|
5
|
-
import { builtIn } from '../lib/theme'
|
|
6
|
-
|
|
7
|
-
let chart = writable({})
|
|
8
|
-
|
|
9
|
-
setContext('chart', chart)
|
|
10
|
-
|
|
11
|
-
export let data
|
|
12
|
-
export let width = 800
|
|
13
|
-
export let height = 450
|
|
14
|
-
export let theme = builtIn
|
|
15
|
-
export let x = 'x'
|
|
16
|
-
export let y = 'y'
|
|
17
|
-
export let fill = null
|
|
18
|
-
export let color = null
|
|
19
|
-
export let padding = 20
|
|
20
|
-
export let curve = 'basis'
|
|
21
|
-
export let stat = 'identity'
|
|
22
|
-
|
|
23
|
-
$: aes = compact({ x, y, fill, color, stat, curve, padding })
|
|
24
|
-
$: chart.set({
|
|
25
|
-
width,
|
|
26
|
-
height,
|
|
27
|
-
data,
|
|
28
|
-
theme,
|
|
29
|
-
aes,
|
|
30
|
-
axis: {
|
|
31
|
-
x: { scale: 'linear', orient: 'bottom' },
|
|
32
|
-
y: { scale: 'linear', orient: 'left' }
|
|
33
|
-
},
|
|
34
|
-
margin: { top: 10, right: 10, bottom: 10, left: 10 }
|
|
35
|
-
})
|
|
36
|
-
</script>
|
|
37
|
-
|
|
38
|
-
<svg viewBox="0 0 {width} {height}" class="chart" width="100%">
|
|
39
|
-
<slot />
|
|
40
|
-
</svg>
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
<script>
|
|
2
|
-
import Chart from './Chart.svelte'
|
|
3
|
-
import AxisGrid from './AxisGrid.svelte'
|
|
4
|
-
import Axis from './Axis.svelte'
|
|
5
|
-
// import AxisTicks from './AxisTicks.svelte'
|
|
6
|
-
// import AxisLabels from './AxisLabels.svelte'
|
|
7
|
-
|
|
8
|
-
export let data
|
|
9
|
-
export let row
|
|
10
|
-
export let col
|
|
11
|
-
export let plot
|
|
12
|
-
export let x
|
|
13
|
-
export let y
|
|
14
|
-
export let labels = { x: true, y: true }
|
|
15
|
-
|
|
16
|
-
$: rowValues = [...new Set(data.map((d) => d[row]))]
|
|
17
|
-
$: colValues = [...new Set(data.map((d) => d[col]))]
|
|
18
|
-
</script>
|
|
19
|
-
|
|
20
|
-
<div class="flex flex-col">
|
|
21
|
-
{#each rowValues as rowItem}
|
|
22
|
-
{@const dataFilteredByRow = data.filter((d) => d[row] === rowItem)}
|
|
23
|
-
|
|
24
|
-
<div class="flex flex-row">
|
|
25
|
-
{#each colValues as colItem}
|
|
26
|
-
{@const dataFilteredByCol = dataFilteredByRow.filter((d) => d[col] === colItem)}
|
|
27
|
-
|
|
28
|
-
<Chart data={dataFilteredByCol} {x} {y}>
|
|
29
|
-
<Axis name="x" count={7} gap={10}>
|
|
30
|
-
<!-- <AxisTicks side="bottom">
|
|
31
|
-
{#if labels.x}
|
|
32
|
-
<AxisLabels angle={-60} />
|
|
33
|
-
{/if}
|
|
34
|
-
</AxisTicks> -->
|
|
35
|
-
</Axis>
|
|
36
|
-
<Axis name="y" gap={10}>
|
|
37
|
-
<!-- <AxisTicks side="left">
|
|
38
|
-
{#if labels.y}
|
|
39
|
-
<AxisLabels />
|
|
40
|
-
{/if}
|
|
41
|
-
</AxisTicks> -->
|
|
42
|
-
<AxisGrid />
|
|
43
|
-
</Axis>
|
|
44
|
-
<svelte:component this={plot} />
|
|
45
|
-
</Chart>
|
|
46
|
-
{/each}
|
|
47
|
-
</div>
|
|
48
|
-
{/each}
|
|
49
|
-
</div>
|
package/src/chart/Legend.svelte
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
<script>
|
|
2
|
-
export let title
|
|
3
|
-
export let items = []
|
|
4
|
-
</script>
|
|
5
|
-
|
|
6
|
-
<ul class="flex flex-col">
|
|
7
|
-
<p>{title}</p>
|
|
8
|
-
{#each items as item}
|
|
9
|
-
<li class="flex flex-row gap-5">
|
|
10
|
-
<svg width="42" height="42" viewBox="0 0 42 42">
|
|
11
|
-
<rect width="42" height="42" fill={item.fillUrl || item.fill} />
|
|
12
|
-
</svg>
|
|
13
|
-
<p class="flex flex-grow">{item.label}</p>
|
|
14
|
-
</li>
|
|
15
|
-
{/each}
|
|
16
|
-
</ul>
|
package/src/chart/Swatch.svelte
DELETED
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
<script>
|
|
2
|
-
import { createEventDispatcher } from 'svelte'
|
|
3
|
-
|
|
4
|
-
import { swatch } from '../lib/utils'
|
|
5
|
-
import { clamp } from 'yootils'
|
|
6
|
-
import { Symbol, DefinePatterns } from '@rokkit/molecules'
|
|
7
|
-
|
|
8
|
-
const dispatch = createEventDispatcher()
|
|
9
|
-
|
|
10
|
-
export let label
|
|
11
|
-
export let size = 30
|
|
12
|
-
export let items = []
|
|
13
|
-
export let type = 'square'
|
|
14
|
-
export let pad = 10
|
|
15
|
-
export let columns
|
|
16
|
-
export let rows
|
|
17
|
-
export let limit
|
|
18
|
-
export let start = 0
|
|
19
|
-
// export let autoscale = false
|
|
20
|
-
export let interactive = false
|
|
21
|
-
export let activeIndex = -1
|
|
22
|
-
|
|
23
|
-
function fill(item) {
|
|
24
|
-
return item.fillUrl || item.fill || item
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
function stroke(item) {
|
|
28
|
-
return item.stroke || item
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
function swapType(inputType) {
|
|
32
|
-
return inputType === 'square' ? 'circle' : inputType === 'circle' ? 'square' : type
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
function click(index) {
|
|
36
|
-
if (interactive) {
|
|
37
|
-
activeIndex = start + index
|
|
38
|
-
dispatch('click', { index: activeIndex, item: items[activeIndex] })
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
function forwardEvent(event, index) {
|
|
43
|
-
if (interactive)
|
|
44
|
-
dispatch(event, {
|
|
45
|
-
index: start + index,
|
|
46
|
-
item: items[start + index]
|
|
47
|
-
})
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
$: grid = swatch(limit || items.length, size, pad, columns, rows)
|
|
51
|
-
$: data = grid.data.map((item, i) => ({
|
|
52
|
-
...item,
|
|
53
|
-
type: i == activeIndex ? swapType(type) : type
|
|
54
|
-
}))
|
|
55
|
-
$: start = clamp(start, 0, items.length - (limit || 0))
|
|
56
|
-
</script>
|
|
57
|
-
|
|
58
|
-
<div class="flex flex-col leading-loose">
|
|
59
|
-
{#if label}
|
|
60
|
-
<span class="py-2">{label}</span>
|
|
61
|
-
{/if}
|
|
62
|
-
<svg viewBox="0 0 {grid.width} {grid.height}" width="100%" class="cursor-pointer">
|
|
63
|
-
{#if label}
|
|
64
|
-
<title>A swatch with label {label}</title>
|
|
65
|
-
{/if}
|
|
66
|
-
|
|
67
|
-
{#each data as { cx, cy, type }, i}
|
|
68
|
-
<Symbol
|
|
69
|
-
x={cx}
|
|
70
|
-
y={cy}
|
|
71
|
-
{size}
|
|
72
|
-
fill={fill(items[i + start])}
|
|
73
|
-
stroke={stroke(items[i + start])}
|
|
74
|
-
shape={items[i + start].shape || type}
|
|
75
|
-
thickness={i + start == activeIndex ? 2 : 0.5}
|
|
76
|
-
on:click={click(i + start)}
|
|
77
|
-
on:mouseover={forwardEvent('mouseover', i + start)}
|
|
78
|
-
on:mouseleave={forwardEvent('mouseleave', i + start)}
|
|
79
|
-
on:focus={forwardEvent('focus', i + start)}
|
|
80
|
-
/>
|
|
81
|
-
{/each}
|
|
82
|
-
<DefinePatterns patterns={items} />
|
|
83
|
-
</svg>
|
|
84
|
-
</div>
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
<script>
|
|
2
|
-
import TexturedShape from './TexturedShape.svelte'
|
|
3
|
-
|
|
4
|
-
export let pattern
|
|
5
|
-
export let shape = 'circle'
|
|
6
|
-
// export let type
|
|
7
|
-
export let fill
|
|
8
|
-
export let stroke
|
|
9
|
-
export let isCurrent = false
|
|
10
|
-
|
|
11
|
-
const size = 40
|
|
12
|
-
</script>
|
|
13
|
-
|
|
14
|
-
<button
|
|
15
|
-
class="h-10 w-10 flex items-center justify-center rounded bg-gray-100 p-1 shadow-md hover:bg-primary-300"
|
|
16
|
-
class:isCurrent
|
|
17
|
-
on:click
|
|
18
|
-
on:mouseover
|
|
19
|
-
on:mouseleave
|
|
20
|
-
on:focus
|
|
21
|
-
>
|
|
22
|
-
<TexturedShape {pattern} {fill} {stroke} {shape} {size} />
|
|
23
|
-
</button>
|
|
24
|
-
|
|
25
|
-
<style>
|
|
26
|
-
.isCurrent {
|
|
27
|
-
@apply bg-primary-200;
|
|
28
|
-
}
|
|
29
|
-
</style>
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
<script>
|
|
2
|
-
import SwatchButton from './SwatchButton.svelte'
|
|
3
|
-
|
|
4
|
-
export let columns
|
|
5
|
-
export let rows
|
|
6
|
-
export let items
|
|
7
|
-
let grid
|
|
8
|
-
|
|
9
|
-
function toGrid(columns, rows, patterns) {
|
|
10
|
-
const count = patterns.length
|
|
11
|
-
if (columns > 0) {
|
|
12
|
-
rows = Math.ceil(count / columns)
|
|
13
|
-
} else if (rows > 0) {
|
|
14
|
-
columns = Math.ceil(count / rows)
|
|
15
|
-
} else {
|
|
16
|
-
columns = Math.ceil(Math.sqrt(count))
|
|
17
|
-
rows = Math.ceil(count / columns)
|
|
18
|
-
}
|
|
19
|
-
const grid = [...Array(rows).keys()].map((row) =>
|
|
20
|
-
[...Array(columns).keys()]
|
|
21
|
-
.filter((column) => row * columns + column < count)
|
|
22
|
-
.map((column) => ({
|
|
23
|
-
item: patterns[row * columns + column],
|
|
24
|
-
isCurrent: false
|
|
25
|
-
}))
|
|
26
|
-
)
|
|
27
|
-
return grid
|
|
28
|
-
}
|
|
29
|
-
let previous
|
|
30
|
-
function handleClick(row, column) {
|
|
31
|
-
if (previous) {
|
|
32
|
-
grid[previous.row][previous.column].isCurrent = false
|
|
33
|
-
}
|
|
34
|
-
grid[row][column].isCurrent = true
|
|
35
|
-
previous = { row, column }
|
|
36
|
-
}
|
|
37
|
-
$: grid = toGrid(columns, rows, items)
|
|
38
|
-
</script>
|
|
39
|
-
|
|
40
|
-
<row class="flex flex-col gap-2">
|
|
41
|
-
{#each grid as items, row}
|
|
42
|
-
<div class="flex flex-row gap-2">
|
|
43
|
-
{#each items as { item, isCurrent }, column}
|
|
44
|
-
<SwatchButton
|
|
45
|
-
shape="shurikan"
|
|
46
|
-
pattern={item}
|
|
47
|
-
on:click={() => handleClick(row, column)}
|
|
48
|
-
{isCurrent}
|
|
49
|
-
/>
|
|
50
|
-
{/each}
|
|
51
|
-
</div>
|
|
52
|
-
{/each}
|
|
53
|
-
</row>
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
<script>
|
|
2
|
-
import { Symbol } from '@rokkit/molecules'
|
|
3
|
-
import Texture from './Texture.svelte'
|
|
4
|
-
|
|
5
|
-
export let pattern
|
|
6
|
-
export let shape = 'circle'
|
|
7
|
-
export let fill
|
|
8
|
-
export let stroke
|
|
9
|
-
|
|
10
|
-
const size = 40
|
|
11
|
-
</script>
|
|
12
|
-
|
|
13
|
-
<svg viewBox="0 0 {size} {size}">
|
|
14
|
-
<Symbol x={size / 2} y={size / 2} {size} fill={pattern.fillUrl || fill} {stroke} {shape} />
|
|
15
|
-
{#if pattern}
|
|
16
|
-
<defs>
|
|
17
|
-
<Texture {...pattern} />
|
|
18
|
-
</defs>
|
|
19
|
-
{/if}
|
|
20
|
-
</svg>
|
|
@@ -1,90 +0,0 @@
|
|
|
1
|
-
<script>
|
|
2
|
-
import { setContext } from 'svelte'
|
|
3
|
-
import { writable } from 'svelte/store'
|
|
4
|
-
import { slidingWindow, uniques, brewer } from '../lib'
|
|
5
|
-
|
|
6
|
-
import Grid from './AxisGrid.svelte'
|
|
7
|
-
import Axis from './Axis.svelte'
|
|
8
|
-
import BoxPlot from '../plots/BoxPlot.svelte'
|
|
9
|
-
import ViolinPlot from '../plots/ViolinPlot.svelte'
|
|
10
|
-
import ScatterPlot from '../plots/ScatterPlot.svelte'
|
|
11
|
-
|
|
12
|
-
let chart = writable({})
|
|
13
|
-
let axis
|
|
14
|
-
setContext('chart', chart)
|
|
15
|
-
|
|
16
|
-
export let data
|
|
17
|
-
export let x
|
|
18
|
-
export let y
|
|
19
|
-
export let time
|
|
20
|
-
export let theme
|
|
21
|
-
|
|
22
|
-
export let current
|
|
23
|
-
export let stages
|
|
24
|
-
|
|
25
|
-
function base(data, x, y) {
|
|
26
|
-
return {
|
|
27
|
-
data,
|
|
28
|
-
x,
|
|
29
|
-
y,
|
|
30
|
-
width: 800,
|
|
31
|
-
height: 350,
|
|
32
|
-
values: {
|
|
33
|
-
x: uniques(data, x),
|
|
34
|
-
y: uniques(data, y)
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
function sliceBy(data, attr, size, step, offset) {
|
|
40
|
-
const values = uniques(data, attr)
|
|
41
|
-
const groups = slidingWindow(values, size, step, offset).map((x) => ({
|
|
42
|
-
...x,
|
|
43
|
-
data: data.filter((y) => y.Petal_Length >= x.lowerBound && y.Petal_Length < x.upperBound)
|
|
44
|
-
}))
|
|
45
|
-
|
|
46
|
-
return groups
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
function timed(data, x, y, time) {
|
|
50
|
-
let chart = base(data, x, y)
|
|
51
|
-
let temp = brewer().chart(data, x, y).use(theme).computeAxis()
|
|
52
|
-
axis = temp.axis
|
|
53
|
-
chart.data = sliceBy(chart.data, time, 3, 1)
|
|
54
|
-
stages = chart.data.length - 1
|
|
55
|
-
return chart
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
function switchChart(index) {
|
|
59
|
-
let chart = {}
|
|
60
|
-
if (index != null) {
|
|
61
|
-
chart = brewer().chart(phased.data[index].data, x, y).use(theme).computeAxis()
|
|
62
|
-
chart.axis = axis
|
|
63
|
-
// chart.margin = { left: 40, right: 10, top: 10, bottom: 30 }
|
|
64
|
-
}
|
|
65
|
-
return chart
|
|
66
|
-
}
|
|
67
|
-
let phased
|
|
68
|
-
|
|
69
|
-
$: phased = timed(data, x, y, time)
|
|
70
|
-
$: $chart = switchChart(current)
|
|
71
|
-
|
|
72
|
-
// setup chart attributes that do not change over time
|
|
73
|
-
// get scales for x & y
|
|
74
|
-
// set margins
|
|
75
|
-
|
|
76
|
-
// nest data by time attribute
|
|
77
|
-
// set up sequence based on ascending values of time
|
|
78
|
-
// set up the timer to switch between data values
|
|
79
|
-
// On change set the context with new data set
|
|
80
|
-
// Old data set needs exit animation, new data set needs entry animation
|
|
81
|
-
</script>
|
|
82
|
-
|
|
83
|
-
<svg viewBox="0 0 {phased.width} {phased.height}" class="chart flex">
|
|
84
|
-
<Grid />
|
|
85
|
-
<Axis orient="bottom" />
|
|
86
|
-
<Axis orient="left" />
|
|
87
|
-
<BoxPlot />
|
|
88
|
-
<ViolinPlot />
|
|
89
|
-
<ScatterPlot jitterWidth={50} offset={50} />
|
|
90
|
-
</svg>
|