@rokkit/chart 1.0.0-next.11 → 1.0.0-next.121
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/README.md +132 -46
- package/dist/Plot/index.d.ts +5 -0
- package/dist/elements/index.d.ts +6 -0
- package/dist/index.d.ts +14 -0
- package/dist/lib/brewing/axes.svelte.d.ts +72 -0
- package/dist/lib/brewing/bars.svelte.d.ts +54 -0
- package/dist/lib/brewing/dimensions.svelte.d.ts +35 -0
- package/dist/lib/brewing/index.svelte.d.ts +118 -0
- package/dist/lib/brewing/legends.svelte.d.ts +54 -0
- package/dist/lib/brewing/scales.svelte.d.ts +29 -0
- package/dist/lib/brewing/types.d.ts +162 -0
- package/dist/lib/context.d.ts +13 -0
- package/dist/lib/scales.svelte.d.ts +35 -0
- package/dist/lib/utils.d.ts +58 -0
- package/dist/old_lib/brewer.d.ts +9 -0
- package/dist/old_lib/chart.d.ts +40 -0
- package/dist/old_lib/grid.d.ts +72 -0
- package/dist/old_lib/index.d.ts +4 -0
- package/dist/old_lib/plots.d.ts +3 -0
- package/dist/old_lib/swatch.d.ts +285 -0
- package/dist/old_lib/ticks.d.ts +36 -0
- package/dist/old_lib/utils.d.ts +1 -0
- package/dist/patterns/index.d.ts +9 -0
- package/dist/patterns/paths/constants.d.ts +1 -0
- package/dist/symbols/constants/index.d.ts +1 -0
- package/dist/symbols/index.d.ts +5 -0
- package/dist/template/constants.d.ts +43 -0
- package/dist/template/shapes/index.d.ts +4 -0
- package/package.json +28 -44
- package/src/Plot/Axis.svelte +103 -0
- package/src/Plot/Bar.svelte +95 -0
- package/src/Plot/Grid.svelte +68 -0
- package/src/Plot/Legend.svelte +129 -0
- package/src/Plot/Root.svelte +112 -0
- package/src/Plot/index.js +5 -0
- package/src/Symbol.svelte +21 -0
- package/src/{chart/Texture.svelte → Texture.svelte} +3 -3
- package/src/elements/Bar.svelte +2 -8
- package/src/elements/ColorRamp.svelte +3 -5
- package/src/elements/ContinuousLegend.svelte +4 -5
- package/src/elements/DefinePatterns.svelte +22 -0
- package/src/elements/DiscreteLegend.svelte +3 -5
- package/src/elements/Label.svelte +6 -5
- package/src/elements/SymbolGrid.svelte +23 -0
- package/src/elements/index.js +6 -0
- package/src/examples/BarChartExample.svelte +81 -0
- package/src/index.js +18 -16
- package/src/lib/brewing/axes.svelte.js +179 -0
- package/src/lib/brewing/bars.svelte.js +114 -0
- package/src/lib/brewing/dimensions.svelte.js +54 -0
- package/src/lib/brewing/index.svelte.js +214 -0
- package/src/lib/brewing/legends.svelte.js +95 -0
- package/src/lib/brewing/scales.svelte.js +94 -0
- package/src/lib/brewing/types.js +73 -0
- package/src/lib/context.js +122 -0
- package/src/lib/scales.svelte.js +129 -0
- package/src/lib/utils.js +110 -132
- package/src/old_lib/brewer.js +25 -0
- package/src/old_lib/chart.js +213 -0
- package/src/old_lib/grid.js +85 -0
- package/src/old_lib/index.js +4 -0
- package/src/old_lib/plots.js +27 -0
- package/src/old_lib/swatch.js +16 -0
- package/src/old_lib/ticks.js +46 -0
- package/src/old_lib/utils.js +8 -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/Tile.svelte +17 -0
- package/src/patterns/Triangles.svelte +15 -0
- package/src/patterns/Waves.svelte +13 -0
- package/src/patterns/index.js +14 -0
- package/src/patterns/paths/NamedPattern.svelte +12 -0
- package/src/patterns/paths/constants.js +4 -0
- package/src/symbols/RoundedSquare.svelte +27 -0
- package/src/symbols/Shape.svelte +31 -0
- package/src/symbols/constants/index.js +4 -0
- package/src/symbols/index.js +9 -0
- package/src/symbols/outline.svelte +60 -0
- package/src/symbols/solid.svelte +60 -0
- package/src/template/Texture.svelte +16 -0
- package/src/template/constants.js +43 -0
- package/src/template/shapes/Circles.svelte +16 -0
- package/src/template/shapes/Lines.svelte +17 -0
- package/src/template/shapes/Path.svelte +12 -0
- package/src/template/shapes/Polygons.svelte +18 -0
- package/src/template/shapes/index.js +4 -0
- package/LICENSE +0 -21
- package/src/chart/FacetGrid.svelte +0 -51
- package/src/chart/Grid.svelte +0 -34
- package/src/chart/Legend.svelte +0 -16
- package/src/chart/PatternDefs.svelte +0 -13
- package/src/chart/Swatch.svelte +0 -93
- package/src/chart/SwatchButton.svelte +0 -29
- package/src/chart/SwatchGrid.svelte +0 -55
- package/src/chart/Symbol.svelte +0 -37
- package/src/chart/TexturedShape.svelte +0 -27
- package/src/chart/TimelapseChart.svelte +0 -97
- package/src/chart/Timer.svelte +0 -27
- package/src/chart.js +0 -9
- package/src/components/charts/Axis.svelte +0 -66
- package/src/components/charts/Chart.svelte +0 -35
- package/src/components/index.js +0 -23
- package/src/components/lib/axis.js +0 -0
- package/src/components/lib/chart.js +0 -187
- package/src/components/lib/color.js +0 -327
- package/src/components/lib/funnel.js +0 -204
- package/src/components/lib/index.js +0 -19
- package/src/components/lib/pattern.js +0 -190
- package/src/components/lib/rollup.js +0 -55
- package/src/components/lib/shape.js +0 -199
- package/src/components/lib/summary.js +0 -145
- package/src/components/lib/theme.js +0 -23
- package/src/components/lib/timer.js +0 -41
- package/src/components/lib/utils.js +0 -165
- package/src/components/plots/BarPlot.svelte +0 -36
- package/src/components/plots/BoxPlot.svelte +0 -54
- package/src/components/plots/ScatterPlot.svelte +0 -30
- package/src/components/store.js +0 -70
- package/src/constants.js +0 -66
- package/src/elements/PatternDefs.svelte +0 -13
- package/src/elements/PatternMask.svelte +0 -20
- package/src/elements/Symbol.svelte +0 -38
- package/src/elements/Tooltip.svelte +0 -23
- package/src/funnel.svelte +0 -35
- package/src/geom.js +0 -105
- package/src/lib/axis.js +0 -75
- package/src/lib/colors.js +0 -32
- package/src/lib/geom.js +0 -4
- package/src/lib/shapes.js +0 -144
- package/src/lib/timer.js +0 -44
- package/src/lookup.js +0 -29
- package/src/plots/BarPlot.svelte +0 -55
- package/src/plots/BoxPlot.svelte +0 -0
- package/src/plots/FunnelPlot.svelte +0 -33
- package/src/plots/HeatMap.svelte +0 -5
- package/src/plots/HeatMapCalendar.svelte +0 -129
- package/src/plots/LinePlot.svelte +0 -55
- package/src/plots/Plot.svelte +0 -25
- package/src/plots/RankBarPlot.svelte +0 -38
- package/src/plots/ScatterPlot.svelte +0 -20
- package/src/plots/ViolinPlot.svelte +0 -11
- package/src/plots/heatmap.js +0 -70
- package/src/plots/index.js +0 -10
- package/src/swatch.js +0 -11
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
import { min, max } from 'd3-array'
|
|
2
|
+
import { scaleBand, scaleLinear, scaleTime } from 'd3-scale'
|
|
3
|
+
|
|
4
|
+
function getScale(domain, range, padding = 0) {
|
|
5
|
+
if (domain.some(isNaN)) {
|
|
6
|
+
return scaleBand().domain(domain).range(range).padding(padding)
|
|
7
|
+
} else if (domain[0] instanceof Date) {
|
|
8
|
+
return scaleTime()
|
|
9
|
+
.domain([min(domain), max(domain)])
|
|
10
|
+
.range(range)
|
|
11
|
+
.nice()
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
return scaleLinear()
|
|
15
|
+
.domain([min([0, ...domain]), max([0, ...domain])])
|
|
16
|
+
.range(range)
|
|
17
|
+
.nice()
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
class Chart {
|
|
21
|
+
// data = []
|
|
22
|
+
// width = 512
|
|
23
|
+
// height = 512
|
|
24
|
+
// origin = { x: 0, y: 0 }
|
|
25
|
+
// range = {
|
|
26
|
+
// x: [0, this.width],
|
|
27
|
+
// y: [this.height, 0]
|
|
28
|
+
// }
|
|
29
|
+
// x
|
|
30
|
+
// y
|
|
31
|
+
// stat = 'identity'
|
|
32
|
+
// scale
|
|
33
|
+
// fill
|
|
34
|
+
// color
|
|
35
|
+
// value
|
|
36
|
+
// shape
|
|
37
|
+
// valueFormat
|
|
38
|
+
// valueLabel
|
|
39
|
+
// domain
|
|
40
|
+
// margin
|
|
41
|
+
// spacing
|
|
42
|
+
// padding
|
|
43
|
+
// flipCoords = false
|
|
44
|
+
|
|
45
|
+
constructor(data, opts) {
|
|
46
|
+
this.width = Number(opts.width) || 2048
|
|
47
|
+
this.height = Number(opts.height) || 2048
|
|
48
|
+
this.flipCoords = opts.flipCoords || false
|
|
49
|
+
this.x = opts.x
|
|
50
|
+
this.y = opts.y
|
|
51
|
+
this.value = opts.value || opts.y
|
|
52
|
+
this.valueLabel = opts.valueLabel || this.value
|
|
53
|
+
this.valueFormat = opts.valueFormat || ((d) => d)
|
|
54
|
+
this.fill = opts.fill || opts.x
|
|
55
|
+
this.color = opts.color || opts.fill
|
|
56
|
+
this.shape = opts.shape || opts.fill
|
|
57
|
+
|
|
58
|
+
this.padding = opts.padding !== undefined ? Number(opts.padding) : 32
|
|
59
|
+
|
|
60
|
+
this.spacing =
|
|
61
|
+
Number(opts.spacing) >= 0 && Number(opts.spacing) <= 0.5 ? Number(opts.spacing) : 0
|
|
62
|
+
this.margin = {
|
|
63
|
+
top: Number(opts.margin?.top) || 0,
|
|
64
|
+
left: Number(opts.margin?.left) || 0,
|
|
65
|
+
right: Number(opts.margin?.right) || 0,
|
|
66
|
+
bottom: Number(opts.margin?.bottom) || 0
|
|
67
|
+
}
|
|
68
|
+
this.domain = {
|
|
69
|
+
x: [...new Set(data.map((d) => d[this.x]))],
|
|
70
|
+
y: [...new Set(data.map((d) => d[this.y]))]
|
|
71
|
+
}
|
|
72
|
+
if (this.flipCoords) {
|
|
73
|
+
this.domain = { y: this.domain.x, x: this.domain.y }
|
|
74
|
+
}
|
|
75
|
+
this.stat = opts.stat || 'identity'
|
|
76
|
+
|
|
77
|
+
this.data = data.map((d) => ({
|
|
78
|
+
x: this.flipCoords ? d[this.y] : d[this.x],
|
|
79
|
+
y: this.flipCoords ? d[this.x] : d[this.y],
|
|
80
|
+
// fill: d[this.fill],
|
|
81
|
+
color: d[this.color]
|
|
82
|
+
// shape: d[this.shape]
|
|
83
|
+
}))
|
|
84
|
+
|
|
85
|
+
this.refresh()
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
padding(value) {
|
|
89
|
+
this.padding = value
|
|
90
|
+
return this.refresh()
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
margin(value) {
|
|
94
|
+
this.margin = value
|
|
95
|
+
return this.refresh()
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
refresh() {
|
|
99
|
+
this.range = {
|
|
100
|
+
x: [this.margin.left + this.padding, this.width - this.margin.right - this.padding],
|
|
101
|
+
y: [this.height - this.padding - this.margin.bottom, this.margin.top + this.padding]
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
const scale = {
|
|
105
|
+
x: getScale(this.domain.x, this.range.x, this.spacing),
|
|
106
|
+
y: getScale(this.domain.y, this.range.y, this.spacing)
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// scale['value'] = this.value === this.x ? scale.x : scale.y
|
|
110
|
+
|
|
111
|
+
this.origin = {
|
|
112
|
+
x: getOriginValue(scale.x),
|
|
113
|
+
y: getOriginValue(scale.y)
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
this.scale = scale
|
|
117
|
+
|
|
118
|
+
return this
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// get scale() {
|
|
122
|
+
// return this.scale
|
|
123
|
+
// }
|
|
124
|
+
// get origin() {
|
|
125
|
+
// return this.origin
|
|
126
|
+
// }
|
|
127
|
+
// get margin() {
|
|
128
|
+
// return this.margin
|
|
129
|
+
// }
|
|
130
|
+
// get range() {
|
|
131
|
+
// const [x1, x2] = this.scale.x.range()
|
|
132
|
+
// const [y1, y2] = this.scale.y.range()
|
|
133
|
+
|
|
134
|
+
// return { x1, y1, x2, y2 }
|
|
135
|
+
// }
|
|
136
|
+
// get data() {
|
|
137
|
+
// // aggregate data group by x,y,fill,shape, color
|
|
138
|
+
// // stat = [min, max, avg, std, q1, q3, median, sum, count, box, all]
|
|
139
|
+
|
|
140
|
+
// return this.data
|
|
141
|
+
// }
|
|
142
|
+
// get width() {
|
|
143
|
+
// return this.width
|
|
144
|
+
// }
|
|
145
|
+
// get height() {
|
|
146
|
+
// return this.height
|
|
147
|
+
// }
|
|
148
|
+
// set width(value) {
|
|
149
|
+
// this.width = value
|
|
150
|
+
// }
|
|
151
|
+
// set height(value) {
|
|
152
|
+
// this.height = value
|
|
153
|
+
// }
|
|
154
|
+
// get domain() {
|
|
155
|
+
// return this.domain
|
|
156
|
+
// }
|
|
157
|
+
// get flipCoords() {
|
|
158
|
+
// return this.flipCoords
|
|
159
|
+
// }
|
|
160
|
+
aggregate(value, stat) {
|
|
161
|
+
this.value = value
|
|
162
|
+
this.stat = stat
|
|
163
|
+
|
|
164
|
+
// this.data = nest(this.data)
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
ticks(axis, count, fontSize = 8) {
|
|
168
|
+
const scale = this.scale[axis]
|
|
169
|
+
const [minRange, maxRange] = scale.range()
|
|
170
|
+
let ticks = []
|
|
171
|
+
let offset = 0
|
|
172
|
+
|
|
173
|
+
count = count || Math.abs((maxRange - minRange) / (fontSize * (axis === 'y' ? 8 : 8)))
|
|
174
|
+
|
|
175
|
+
if (scale.ticks) {
|
|
176
|
+
ticks = scale.ticks(Math.round(count))
|
|
177
|
+
} else {
|
|
178
|
+
offset = scale.bandwidth() / 2
|
|
179
|
+
count = Math.min(Math.round(count), scale.domain().length)
|
|
180
|
+
|
|
181
|
+
ticks = scale.domain()
|
|
182
|
+
if (count < scale.domain().length) {
|
|
183
|
+
const diff = scale.domain().length - count
|
|
184
|
+
ticks = ticks.filter((d, i) => i % diff === 0)
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
ticks = ticks
|
|
189
|
+
.map((t) => ({
|
|
190
|
+
label: t,
|
|
191
|
+
pos: scale(t)
|
|
192
|
+
}))
|
|
193
|
+
.map(({ label, pos }) => ({
|
|
194
|
+
label,
|
|
195
|
+
offset: {
|
|
196
|
+
x: axis === 'x' ? offset : 0,
|
|
197
|
+
y: axis === 'y' ? offset : 0
|
|
198
|
+
},
|
|
199
|
+
x: axis === 'x' ? pos : this.origin.x,
|
|
200
|
+
y: axis === 'y' ? pos : this.origin.y
|
|
201
|
+
}))
|
|
202
|
+
|
|
203
|
+
return ticks
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
function getOriginValue(scale) {
|
|
208
|
+
return scale.ticks ? scale(Math.max(0, Math.min(...scale.domain()))) : scale.range()[0]
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
export function chart(data, aes) {
|
|
212
|
+
return new Chart(data, aes)
|
|
213
|
+
}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @typedef GridPoint
|
|
3
|
+
* @property {number} x - x-coordinate of the point
|
|
4
|
+
* @property {number} y - y-coordinate of the point
|
|
5
|
+
* @property {number} r - radius of the point
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* @typedef SwatchGrid
|
|
10
|
+
* @property {number} width - width of the grid
|
|
11
|
+
* @property {number} height - height of the grid
|
|
12
|
+
* @property {GridPoint[]} data - data points of the grid
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* @tyoedef {Object} GridOptions
|
|
17
|
+
* @property {number} [pad=0] - The padding between the items
|
|
18
|
+
* @property {number} [columns=0] - The number of columns
|
|
19
|
+
* @property {number} [rows=0] - The number of rows
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Calculates a grid of centres to fit a list of items of `size` within the number of `columns` and `rows`.
|
|
24
|
+
*
|
|
25
|
+
* - Attempts to find a best fit square if both columns and rows are not specified
|
|
26
|
+
* - Value in columns is prioritized over rows for recalculating the grid
|
|
27
|
+
* - Supports padding between the items
|
|
28
|
+
*
|
|
29
|
+
* @param {number} count - number of items
|
|
30
|
+
* @param {number} size - size of the items
|
|
31
|
+
* @param {GridOptions} options - options for the grid
|
|
32
|
+
* @returns {SwatchGrid}
|
|
33
|
+
*/
|
|
34
|
+
export function swatchGrid(count, size, options) {
|
|
35
|
+
const { pad = 0 } = options || {}
|
|
36
|
+
let { columns = 0, rows = 0 } = options || {}
|
|
37
|
+
if (columns > 0) {
|
|
38
|
+
rows = Math.ceil(count / columns)
|
|
39
|
+
} else if (rows > 0) {
|
|
40
|
+
columns = Math.ceil(count / rows)
|
|
41
|
+
} else {
|
|
42
|
+
columns = Math.ceil(Math.sqrt(count))
|
|
43
|
+
rows = Math.ceil(count / columns)
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const width = (size + pad) * columns + pad
|
|
47
|
+
const height = (size + pad) * rows + pad
|
|
48
|
+
const radius = size / 2
|
|
49
|
+
const data = [...Array(count).keys()].map((index) => ({
|
|
50
|
+
x: pad + radius + (index % columns) * (size + pad),
|
|
51
|
+
y: pad + radius + Math.floor(index / columns) * (size + pad),
|
|
52
|
+
r: radius
|
|
53
|
+
}))
|
|
54
|
+
|
|
55
|
+
return { width, height, data }
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Spreads values as patterns with colors from a palette
|
|
60
|
+
*
|
|
61
|
+
* @param {number[]} values - values to spread
|
|
62
|
+
* @param {string[]} patterns - patterns to spread
|
|
63
|
+
* @param {string[]} palette - colors to spread
|
|
64
|
+
* @returns {Record<number, { id: string, pattern: string, color: string }>}
|
|
65
|
+
*/
|
|
66
|
+
export function spreadValuesAsPatterns(values, patterns, palette) {
|
|
67
|
+
const result = values
|
|
68
|
+
.map((value, index) => ({
|
|
69
|
+
pattern: patterns[index % patterns.length],
|
|
70
|
+
color: palette[index % palette.length],
|
|
71
|
+
value
|
|
72
|
+
}))
|
|
73
|
+
.reduce(
|
|
74
|
+
(acc, { value, pattern, color }) => ({
|
|
75
|
+
...acc,
|
|
76
|
+
[value]: {
|
|
77
|
+
id: `${pattern}_${color}`,
|
|
78
|
+
pattern,
|
|
79
|
+
color
|
|
80
|
+
}
|
|
81
|
+
}),
|
|
82
|
+
{}
|
|
83
|
+
)
|
|
84
|
+
return result
|
|
85
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
// skipcq: JS-C1003 - Importing all plots from observablehq/plot
|
|
2
|
+
import * as Plot from '@observablehq/plot'
|
|
3
|
+
|
|
4
|
+
export function plotter(node, options) {
|
|
5
|
+
let { data, aes, type, opts } = options
|
|
6
|
+
// let chart = Plot.lineY(options.data).plot({ grid: true })
|
|
7
|
+
|
|
8
|
+
function render() {
|
|
9
|
+
const chart = Plot[type](data, aes).plot({
|
|
10
|
+
color: { scheme: 'turbo', range: [0.1, 0.9] },
|
|
11
|
+
...opts
|
|
12
|
+
})
|
|
13
|
+
node.firstChild?.remove() // remove old chart, if any
|
|
14
|
+
node.append(chart)
|
|
15
|
+
}
|
|
16
|
+
render()
|
|
17
|
+
|
|
18
|
+
return {
|
|
19
|
+
update: (input) => {
|
|
20
|
+
data = input.data
|
|
21
|
+
aes = input.aes
|
|
22
|
+
type = input.type
|
|
23
|
+
opts = input.opts
|
|
24
|
+
render()
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { writable } from 'svelte/store'
|
|
2
|
+
import palette from './palette.json'
|
|
3
|
+
// skipcq: JS-C1003 - Importing all patterns
|
|
4
|
+
import * as patterns from '../patterns'
|
|
5
|
+
import { shapes } from '../symbols'
|
|
6
|
+
|
|
7
|
+
export const swatch = writable({
|
|
8
|
+
palette,
|
|
9
|
+
patterns,
|
|
10
|
+
keys: {
|
|
11
|
+
gray: ['gray'],
|
|
12
|
+
color: Object.keys(palette).filter((name) => name !== 'gray'),
|
|
13
|
+
symbol: shapes,
|
|
14
|
+
pattern: Object.keys(patterns)
|
|
15
|
+
}
|
|
16
|
+
})
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @typedef {Object} TickSteps
|
|
3
|
+
* @property {number} major - count of major ticks
|
|
4
|
+
* @property {number} minor - count of minor ticks
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Generate an array of ticks for a given axis and the tick type
|
|
9
|
+
*
|
|
10
|
+
* @param {number} lower - The lower bound of the axis
|
|
11
|
+
* @param {number} upper - The upper bound of the axis
|
|
12
|
+
* @param {TickSteps} steps - The number of steps between major and minor ticks
|
|
13
|
+
* @param {string} type - The type of tick to generate
|
|
14
|
+
*
|
|
15
|
+
* @returns {Array} - An array of objects representing the ticks
|
|
16
|
+
*/
|
|
17
|
+
export function ticksByType(lower, upper, steps, type) {
|
|
18
|
+
if (steps <= 0) return []
|
|
19
|
+
return Array.from({ length: Math.floor((upper - lower) / steps) + 1 }, (_, i) => ({
|
|
20
|
+
position: i * steps,
|
|
21
|
+
label: i * steps,
|
|
22
|
+
type
|
|
23
|
+
})).filter((tick) => tick.position > lower && tick.position < upper)
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Generate an array of ticks for a given axis
|
|
28
|
+
*
|
|
29
|
+
* @param {number} lower - The lower bound of the axis
|
|
30
|
+
* @param {number} upper - The upper bound of the axis
|
|
31
|
+
* @param {TickSteps} steps - The number of steps between major and minor ticks
|
|
32
|
+
*
|
|
33
|
+
* @returns {Array} - An array of objects representing the ticks
|
|
34
|
+
*/
|
|
35
|
+
export function getTicks(lower, upper, steps = { major: 10, minor: 0 }) {
|
|
36
|
+
const majorTicks = ticksByType(lower, upper, steps.major, 'major')
|
|
37
|
+
const minorTicks = ticksByType(lower, upper, steps.minor, 'minor').filter(
|
|
38
|
+
(tick) => !majorTicks.find((major) => major.position === tick.position)
|
|
39
|
+
)
|
|
40
|
+
const end = [
|
|
41
|
+
{ position: upper, label: upper, type: 'end' },
|
|
42
|
+
{ position: lower, label: lower, type: 'end' }
|
|
43
|
+
]
|
|
44
|
+
|
|
45
|
+
return [...minorTicks, ...majorTicks, ...end].sort((a, b) => a.position - b.position)
|
|
46
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
export let size = 10
|
|
3
|
+
export let thickness = 0.5
|
|
4
|
+
export let stroke = 'currentColor'
|
|
5
|
+
|
|
6
|
+
$: lines = [
|
|
7
|
+
{ x1: 0, y1: 0.25 * size, x2: 0.5 * size, y2: 0.25 * size },
|
|
8
|
+
{ x1: 0.5 * size, y1: 0.75 * size, x2: size, y2: 0.75 * size },
|
|
9
|
+
{ x1: 0, y1: 0, x2: 0, y2: size },
|
|
10
|
+
{ x1: size, y1: 0, x2: size, y2: size },
|
|
11
|
+
{ x1: 0.5 * size, y1: 0, x2: 0.5 * size, y2: size }
|
|
12
|
+
]
|
|
13
|
+
</script>
|
|
14
|
+
|
|
15
|
+
{#each lines as line}
|
|
16
|
+
<line {...line} {stroke} stroke-width={thickness} stroke-linecap="round" />
|
|
17
|
+
{/each}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
export let size = 10
|
|
3
|
+
export let fill = 'currentColor'
|
|
4
|
+
export let stroke = 'currentColor'
|
|
5
|
+
|
|
6
|
+
$: data = [
|
|
7
|
+
{ cx: 0, cy: 0, r: 0.5 },
|
|
8
|
+
{ cx: 1, cy: 1, r: 0.5 }
|
|
9
|
+
].map(({ cx, cy, r }) => ({
|
|
10
|
+
cx: cx * size,
|
|
11
|
+
cy: cy * size,
|
|
12
|
+
r: r * size
|
|
13
|
+
}))
|
|
14
|
+
</script>
|
|
15
|
+
|
|
16
|
+
{#each data as { cx, cy, r }}
|
|
17
|
+
<circle {cx} {cy} {r} {fill} {stroke} />
|
|
18
|
+
{/each}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
export let size = 10
|
|
3
|
+
export let thickness = 0.5
|
|
4
|
+
export let stroke = 'currentColor'
|
|
5
|
+
|
|
6
|
+
$: lines = [
|
|
7
|
+
{ x1: 0, y1: 0, x2: size, y2: size },
|
|
8
|
+
{ x1: 0, y1: size, x2: size, y2: 0 }
|
|
9
|
+
]
|
|
10
|
+
</script>
|
|
11
|
+
|
|
12
|
+
{#each lines as line}
|
|
13
|
+
<line {...line} {stroke} stroke-width={thickness} stroke-linecap="round" />
|
|
14
|
+
{/each}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
export let size = 10
|
|
3
|
+
export let fill = 'currentColor'
|
|
4
|
+
|
|
5
|
+
$: data = [
|
|
6
|
+
{ cx: 0.2 * size, cy: 0.2 * size },
|
|
7
|
+
{ cx: 0.4 * size, cy: 0.4 * size },
|
|
8
|
+
{ cx: 0.6 * size, cy: 0.6 * size },
|
|
9
|
+
{ cx: 0.8 * size, cy: 0.8 * size },
|
|
10
|
+
{ cx: 0.8 * size, cy: 0.2 * size },
|
|
11
|
+
{ cx: 0.6 * size, cy: 0.4 * size },
|
|
12
|
+
{ cx: 0.4 * size, cy: 0.6 * size },
|
|
13
|
+
{ cx: 0.2 * size, cy: 0.8 * size }
|
|
14
|
+
].map((x) => ({ ...x, r: 0.08 * size }))
|
|
15
|
+
</script>
|
|
16
|
+
|
|
17
|
+
{#each data as { cx, cy, r }}
|
|
18
|
+
<circle {cx} {cy} {r} {fill} />
|
|
19
|
+
{/each}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
export let size = 10
|
|
3
|
+
export let fill = 'currentColor'
|
|
4
|
+
export let stroke = 'currentColor'
|
|
5
|
+
|
|
6
|
+
const centres = [
|
|
7
|
+
{ cx: 0, cy: 0 },
|
|
8
|
+
{ cx: size, cy: size }
|
|
9
|
+
]
|
|
10
|
+
$: r = 0.5 * size
|
|
11
|
+
</script>
|
|
12
|
+
|
|
13
|
+
{#each centres as { cx, cy }}
|
|
14
|
+
<circle {cx} {cy} {r} {fill} {stroke} />
|
|
15
|
+
{/each}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
const thickness = 0.5
|
|
3
|
+
export let size = 10
|
|
4
|
+
export let stroke = 'currentColor'
|
|
5
|
+
|
|
6
|
+
const lines = [
|
|
7
|
+
{ x1: 0, y1: 0.25 * size, x2: 0.5 * size, y2: 0.25 * size },
|
|
8
|
+
{ x1: 0.5 * size, y1: 0.75 * size, x2: size, y2: 0.75 * size },
|
|
9
|
+
{ x1: 0, y1: 0, x2: 0, y2: size },
|
|
10
|
+
{ x1: size, y1: 0, x2: size, y2: size },
|
|
11
|
+
{ x1: 0.5 * size, y1: 0, x2: 0.5 * size, y2: size }
|
|
12
|
+
]
|
|
13
|
+
</script>
|
|
14
|
+
|
|
15
|
+
{#each lines as line}
|
|
16
|
+
<line {...line} {stroke} stroke-width={thickness} stroke-linecap="round" />
|
|
17
|
+
{/each}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
export let size = 10
|
|
3
|
+
export let fill = 'currentColor'
|
|
4
|
+
export let stroke = 'currentColor'
|
|
5
|
+
|
|
6
|
+
const polygons = [
|
|
7
|
+
[0, 0.5 * size, 0.5 * size, size, 0, size],
|
|
8
|
+
[0.5 * size, 0, 0, 0, 0, 0.5 * size],
|
|
9
|
+
[size, 0, 0.5 * size, 0.5 * size, size, size]
|
|
10
|
+
]
|
|
11
|
+
</script>
|
|
12
|
+
|
|
13
|
+
{#each polygons as points}
|
|
14
|
+
<polygon points={points.join(', ')} {fill} {stroke} stroke-width="0" />
|
|
15
|
+
{/each}
|
|
@@ -0,0 +1,13 @@
|
|
|
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
|
+
export let fill = 'none'
|
|
8
|
+
export let data = []
|
|
9
|
+
|
|
10
|
+
$: d = scaledPath(size, data)
|
|
11
|
+
</script>
|
|
12
|
+
|
|
13
|
+
<path {d} {stroke} stroke-width={thickness} {fill} />
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export { default as Brick } from './Brick.svelte'
|
|
2
|
+
export { default as Circles } from './Circles.svelte'
|
|
3
|
+
export { default as Dots } from './Dots.svelte'
|
|
4
|
+
export { default as CrossHatch } from './CrossHatch.svelte'
|
|
5
|
+
export { default as Waves } from './Waves.svelte'
|
|
6
|
+
// export { default as Squares } from './Squares.svelte'
|
|
7
|
+
export { default as Tile } from './Tile.svelte'
|
|
8
|
+
export { default as Triangles } from './Triangles.svelte'
|
|
9
|
+
// export { default as Waves } from './Waves.svelte'
|
|
10
|
+
// export { default as ZigZag } from './ZigZag.svelte'
|
|
11
|
+
// export { default as Flower } from './Flower.svelte'
|
|
12
|
+
// export { default as NamedPath } from './NamedPath.svelte'
|
|
13
|
+
export { default as CurvedWave } from './CurvedWave.svelte'
|
|
14
|
+
export { default as OutlineCircles } from './OutlineCircles.svelte'
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
import { patterns } from './constants'
|
|
3
|
+
|
|
4
|
+
export let size = 10
|
|
5
|
+
export let thickness = 0.5
|
|
6
|
+
export let stroke = 'currentColor'
|
|
7
|
+
export let name = 'cross-hatch'
|
|
8
|
+
|
|
9
|
+
$: d = patterns[name](size)
|
|
10
|
+
</script>
|
|
11
|
+
|
|
12
|
+
<path {d} {stroke} stroke-width={thickness} fill="none" />
|
|
@@ -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['circle'](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
|
+
}
|