@rokkit/chart 1.0.0-next.11
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/LICENSE +21 -0
- package/README.md +55 -0
- package/package.json +63 -0
- package/src/chart/FacetGrid.svelte +51 -0
- package/src/chart/Grid.svelte +34 -0
- package/src/chart/Legend.svelte +16 -0
- package/src/chart/PatternDefs.svelte +13 -0
- package/src/chart/Swatch.svelte +93 -0
- package/src/chart/SwatchButton.svelte +29 -0
- package/src/chart/SwatchGrid.svelte +55 -0
- package/src/chart/Symbol.svelte +37 -0
- package/src/chart/Texture.svelte +16 -0
- package/src/chart/TexturedShape.svelte +27 -0
- package/src/chart/TimelapseChart.svelte +97 -0
- package/src/chart/Timer.svelte +27 -0
- package/src/chart.js +9 -0
- package/src/components/charts/Axis.svelte +66 -0
- package/src/components/charts/Chart.svelte +35 -0
- package/src/components/index.js +23 -0
- package/src/components/lib/axis.js +0 -0
- package/src/components/lib/chart.js +187 -0
- package/src/components/lib/color.js +327 -0
- package/src/components/lib/funnel.js +204 -0
- package/src/components/lib/index.js +19 -0
- package/src/components/lib/pattern.js +190 -0
- package/src/components/lib/rollup.js +55 -0
- package/src/components/lib/shape.js +199 -0
- package/src/components/lib/summary.js +145 -0
- package/src/components/lib/theme.js +23 -0
- package/src/components/lib/timer.js +41 -0
- package/src/components/lib/utils.js +165 -0
- package/src/components/plots/BarPlot.svelte +36 -0
- package/src/components/plots/BoxPlot.svelte +54 -0
- package/src/components/plots/ScatterPlot.svelte +30 -0
- package/src/components/store.js +70 -0
- package/src/constants.js +66 -0
- package/src/elements/Bar.svelte +35 -0
- package/src/elements/ColorRamp.svelte +51 -0
- package/src/elements/ContinuousLegend.svelte +46 -0
- package/src/elements/DiscreteLegend.svelte +41 -0
- package/src/elements/Label.svelte +12 -0
- package/src/elements/PatternDefs.svelte +13 -0
- package/src/elements/PatternMask.svelte +20 -0
- package/src/elements/Symbol.svelte +38 -0
- package/src/elements/Tooltip.svelte +23 -0
- package/src/funnel.svelte +35 -0
- package/src/geom.js +105 -0
- package/src/index.js +16 -0
- package/src/lib/axis.js +75 -0
- package/src/lib/colors.js +32 -0
- package/src/lib/geom.js +4 -0
- package/src/lib/shapes.js +144 -0
- package/src/lib/timer.js +44 -0
- package/src/lib/utils.js +157 -0
- package/src/lookup.js +29 -0
- package/src/plots/BarPlot.svelte +55 -0
- package/src/plots/BoxPlot.svelte +0 -0
- package/src/plots/FunnelPlot.svelte +33 -0
- package/src/plots/HeatMap.svelte +5 -0
- package/src/plots/HeatMapCalendar.svelte +129 -0
- package/src/plots/LinePlot.svelte +55 -0
- package/src/plots/Plot.svelte +25 -0
- package/src/plots/RankBarPlot.svelte +38 -0
- package/src/plots/ScatterPlot.svelte +20 -0
- package/src/plots/ViolinPlot.svelte +11 -0
- package/src/plots/heatmap.js +70 -0
- package/src/plots/index.js +10 -0
- package/src/swatch.js +11 -0
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
import { getContext } from 'svelte'
|
|
3
|
+
export let orient = 'bottom'
|
|
4
|
+
|
|
5
|
+
let chart = getContext('chart')
|
|
6
|
+
|
|
7
|
+
let top =
|
|
8
|
+
orient === 'bottom'
|
|
9
|
+
? $chart.height - $chart.margin.bottom
|
|
10
|
+
: $chart.margin.top
|
|
11
|
+
let left =
|
|
12
|
+
orient === 'right' ? $chart.width - $chart.margin.right : $chart.margin.left
|
|
13
|
+
let tickSizeInner = $chart.theme.tick.size.inner || 6
|
|
14
|
+
let tickSizeOuter = $chart.theme.tick.size.outer || 6
|
|
15
|
+
let tickPadding = $chart.theme.tick.size.padding || 3
|
|
16
|
+
|
|
17
|
+
function axisPath(vertical, scale) {
|
|
18
|
+
const range = scale.range()
|
|
19
|
+
return vertical
|
|
20
|
+
? `M${k * tickSizeOuter},${range[0]}H0V${range[1]}H${k * tickSizeOuter}`
|
|
21
|
+
: `M${range[0]},${k * tickSizeOuter}V0H${range[1]}V${k * tickSizeOuter}`
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
$: anchor =
|
|
25
|
+
orient === 'right' ? 'start' : orient === 'left' ? 'end' : 'middle'
|
|
26
|
+
$: k = orient === 'top' || orient === 'left' ? -1 : 1
|
|
27
|
+
$: dy = orient === 'top' ? '0em' : orient === 'bottom' ? '0.71em' : '0.32em'
|
|
28
|
+
$: vertical = orient === 'left' || orient === 'right'
|
|
29
|
+
// $: range = axis.scale.range()
|
|
30
|
+
$: axis = vertical ? $chart.axis.y : $chart.axis.x
|
|
31
|
+
</script>
|
|
32
|
+
|
|
33
|
+
<g
|
|
34
|
+
transform="translate({vertical ? left : 0},{vertical ? 0 : top})"
|
|
35
|
+
fill="none"
|
|
36
|
+
font-size="10"
|
|
37
|
+
font-family="sans-serif"
|
|
38
|
+
text-anchor={anchor}
|
|
39
|
+
class="axis"
|
|
40
|
+
>
|
|
41
|
+
<path
|
|
42
|
+
class="domain"
|
|
43
|
+
stroke="currentColor"
|
|
44
|
+
d="{axisPath(vertical, axis.scale)}}"
|
|
45
|
+
/>
|
|
46
|
+
{#each axis.ticks as tick}
|
|
47
|
+
<g
|
|
48
|
+
class="tick"
|
|
49
|
+
transform="translate({vertical ? 0 : tick.position},{vertical
|
|
50
|
+
? tick.position
|
|
51
|
+
: 0})"
|
|
52
|
+
>
|
|
53
|
+
<line
|
|
54
|
+
stroke="currentColor"
|
|
55
|
+
y2={vertical ? 0 : k * tickSizeInner}
|
|
56
|
+
x2={vertical ? k * tickSizeInner : 0}
|
|
57
|
+
/>
|
|
58
|
+
<text
|
|
59
|
+
fill="currentColor"
|
|
60
|
+
y={vertical ? 0 : k * (tickSizeInner + tickPadding)}
|
|
61
|
+
x={vertical ? k * (tickSizeInner + tickPadding) : 0}
|
|
62
|
+
{dy}>{tick.label}</text
|
|
63
|
+
>
|
|
64
|
+
</g>
|
|
65
|
+
{/each}
|
|
66
|
+
</g>
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
import { setContext } from 'svelte'
|
|
3
|
+
import { writable } from 'svelte/store'
|
|
4
|
+
import { compact } from '../lib/utils'
|
|
5
|
+
import { builtIn } from '../lib/theme'
|
|
6
|
+
|
|
7
|
+
let chart = writable({})
|
|
8
|
+
|
|
9
|
+
setContext('chart', chart)
|
|
10
|
+
|
|
11
|
+
export let width = 800
|
|
12
|
+
export let height = 450
|
|
13
|
+
export let data
|
|
14
|
+
export let theme = builtIn
|
|
15
|
+
export let x
|
|
16
|
+
export let y
|
|
17
|
+
export let fill
|
|
18
|
+
export let color
|
|
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
|
+
})
|
|
31
|
+
</script>
|
|
32
|
+
|
|
33
|
+
<svg viewBox="0 0 {width} {height}" class="chart" width="100%">
|
|
34
|
+
<slot />
|
|
35
|
+
</svg>
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export { default as ColorRamp } from './elements/ColorRamp.svelte'
|
|
2
|
+
|
|
3
|
+
export { default as Symbol } from './chart/Symbol.svelte'
|
|
4
|
+
export { default as PatternDefs } from './chart/PatternDefs.svelte'
|
|
5
|
+
export { default as Swatch } from './chart/Swatch.svelte'
|
|
6
|
+
export { default as SwatchButton } from './chart/SwatchButton.svelte'
|
|
7
|
+
export { default as SwatchGrid } from './chart/SwatchGrid.svelte'
|
|
8
|
+
|
|
9
|
+
export { default as Axis } from './chart/Axis.svelte'
|
|
10
|
+
export { default as Grid } from './chart/Grid.svelte'
|
|
11
|
+
|
|
12
|
+
export { default as BoxPlot } from './plots/BoxPlot.svelte'
|
|
13
|
+
export { default as ViolinPlot } from '../plots/ViolinPlot.svelte'
|
|
14
|
+
export { default as ScatterPlot } from './plots/ScatterPlot.svelte'
|
|
15
|
+
export { default as FunnelPlot } from '../plots/FunnelPlot.svelte'
|
|
16
|
+
|
|
17
|
+
export { default as Chart } from './chart/Chart.svelte'
|
|
18
|
+
export { default as TimelapseChart } from './chart/TimelapseChart.svelte'
|
|
19
|
+
export { default as Timer } from './chart/Timer.svelte'
|
|
20
|
+
export { default as BarPlot } from './plots/BarPlot.svelte'
|
|
21
|
+
export { default as HeatMapCalendar } from '../plots/HeatMapCalendar.svelte'
|
|
22
|
+
export { toHexString, initCap, uniqueId, toNested } from './lib/utils'
|
|
23
|
+
export { brewer, uniques, slidingWindow, colors } from './lib/index'
|
|
File without changes
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
import { nest } from 'd3-collection'
|
|
2
|
+
import { max, quantile, ascending, histogram } from 'd3-array'
|
|
3
|
+
import { scaleLinear } from 'd3-scale'
|
|
4
|
+
import { area, curveCatmullRom } from 'd3-shape'
|
|
5
|
+
import { getScale } from './utils'
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* axis, theme, params, fields
|
|
9
|
+
*/
|
|
10
|
+
export class ChartBrewer {
|
|
11
|
+
constructor(data, x, y) {
|
|
12
|
+
this.data = data
|
|
13
|
+
this.x = x
|
|
14
|
+
this.y = y
|
|
15
|
+
this.fill = x
|
|
16
|
+
this.axis = null
|
|
17
|
+
this.stats = {}
|
|
18
|
+
// this.yOffset = 20
|
|
19
|
+
this.padding = 10
|
|
20
|
+
this.margin = {
|
|
21
|
+
left: 10,
|
|
22
|
+
top: 10,
|
|
23
|
+
right: 10,
|
|
24
|
+
bottom: 10
|
|
25
|
+
}
|
|
26
|
+
this.params = {
|
|
27
|
+
ticks: {}
|
|
28
|
+
}
|
|
29
|
+
this.labels = []
|
|
30
|
+
this.width = 800
|
|
31
|
+
this.height = (this.width * 7) / 16
|
|
32
|
+
this.scaleValues = null
|
|
33
|
+
this.theme = {}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
computeMargin(xAxisOrientation, yAxisOrientation) {
|
|
37
|
+
this.scaleValues = {
|
|
38
|
+
x: [...new Set(this.data.map((item) => item[this.x]))],
|
|
39
|
+
y: [...new Set(this.data.map((item) => item[this.y]))],
|
|
40
|
+
fill: [...new Set(this.data.map((item) => item[this.fill]))]
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
let xOffset =
|
|
44
|
+
max(this.scaleValues.y.map((value) => value.toString().length)) * 10
|
|
45
|
+
let yOffset = 20
|
|
46
|
+
|
|
47
|
+
this.margin = {
|
|
48
|
+
left: this.padding + (yAxisOrientation === 'left' ? xOffset : 0),
|
|
49
|
+
right: this.padding + (yAxisOrientation === 'left' ? 0 : xOffset),
|
|
50
|
+
top: this.padding + (xAxisOrientation === 'bottom' ? 0 : yOffset),
|
|
51
|
+
bottom: this.padding + (xAxisOrientation === 'bottom' ? yOffset : 0)
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
computeAxis(buffer = 0, inverse = false) {
|
|
56
|
+
let x = {}
|
|
57
|
+
let y = {}
|
|
58
|
+
let fill = {}
|
|
59
|
+
|
|
60
|
+
if (!this.scaleValues) {
|
|
61
|
+
this.computeMargin('bottom', 'left')
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
x.scale = getScale(
|
|
65
|
+
this.scaleValues.x,
|
|
66
|
+
[this.margin.left, this.width - this.margin.right],
|
|
67
|
+
buffer
|
|
68
|
+
)
|
|
69
|
+
const domainY = inverse
|
|
70
|
+
? [this.margin.top, this.height - this.margin.bottom]
|
|
71
|
+
: [this.height - this.margin.bottom, this.margin.top]
|
|
72
|
+
y.scale = getScale(this.scaleValues.y, domainY, buffer)
|
|
73
|
+
|
|
74
|
+
x.ticks = tickValues(x.scale, 'x', this.params)
|
|
75
|
+
y.ticks = tickValues(y.scale, 'y', this.params)
|
|
76
|
+
|
|
77
|
+
this.axis = { x, y, fill }
|
|
78
|
+
return this
|
|
79
|
+
}
|
|
80
|
+
use(theme) {
|
|
81
|
+
this.theme = theme
|
|
82
|
+
return this
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
params(margin, ticks) {
|
|
86
|
+
this.margin = margin
|
|
87
|
+
this.ticks = ticks
|
|
88
|
+
return this
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
fillWith(fill) {
|
|
92
|
+
this.fill = fill
|
|
93
|
+
return this
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
highlight(values) {
|
|
97
|
+
this.highlight = values
|
|
98
|
+
return this
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
animate() {
|
|
102
|
+
return this
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
summary() {
|
|
106
|
+
const result = nest()
|
|
107
|
+
.key((d) => d[this.x])
|
|
108
|
+
.rollup((d) => {
|
|
109
|
+
let values = d.map((g) => g[this.y]).sort(ascending)
|
|
110
|
+
let q1 = quantile(values, 0.25)
|
|
111
|
+
let q3 = quantile(values, 0.75)
|
|
112
|
+
let median = quantile(values, 0.5)
|
|
113
|
+
let interQuantileRange = q3 - q1
|
|
114
|
+
let min = q1 - 1.5 * interQuantileRange
|
|
115
|
+
let max = q3 + 1.5 * interQuantileRange
|
|
116
|
+
return { q1, q3, median, interQuantileRange, min, max }
|
|
117
|
+
})
|
|
118
|
+
.entries(this.data)
|
|
119
|
+
return result
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// assumes axis has been computes
|
|
123
|
+
violin() {
|
|
124
|
+
if (!this.axis) this.computeAxis()
|
|
125
|
+
// Features of the histogram
|
|
126
|
+
var histogramBins = bin()
|
|
127
|
+
.domain(this.axis.y.scale.domain())
|
|
128
|
+
.thresholds(this.axis.y.scale.ticks(20)) // Important: how many bins approx are going to be made? It is the 'resolution' of the violin plot
|
|
129
|
+
.value((d) => d)
|
|
130
|
+
|
|
131
|
+
// Compute the binning for each group of the dataset
|
|
132
|
+
var sumstat = nest()
|
|
133
|
+
.key((d) => d[this.x])
|
|
134
|
+
.rollup((d) => histogramBins(d.map((g) => +g[this.y])))
|
|
135
|
+
.entries(this.data)
|
|
136
|
+
|
|
137
|
+
// console.log(sumstat)
|
|
138
|
+
// What is the biggest number of value in a bin? We need it cause this value will have a width of 100% of the bandwidth.
|
|
139
|
+
var maxNum = 0
|
|
140
|
+
for (let i in sumstat) {
|
|
141
|
+
let allBins = sumstat[i].value
|
|
142
|
+
let lengths = allBins.map((a) => a.length)
|
|
143
|
+
let longest = max(lengths)
|
|
144
|
+
if (longest > maxNum) {
|
|
145
|
+
maxNum = longest
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
// console.log(
|
|
149
|
+
// maxNum,
|
|
150
|
+
// this.axis.x.scale.bandwidth(),
|
|
151
|
+
// this.axis.x.scale('setosa')
|
|
152
|
+
// )
|
|
153
|
+
|
|
154
|
+
// The maximum width of a violin must be x.bandwidth = the width dedicated to a group
|
|
155
|
+
var xNum = scaleLinear()
|
|
156
|
+
.range([0, this.axis.x.scale.bandwidth()])
|
|
157
|
+
.domain([0, maxNum])
|
|
158
|
+
|
|
159
|
+
let result = area()
|
|
160
|
+
.x0(xNum(0))
|
|
161
|
+
.x1(function (d) {
|
|
162
|
+
return xNum(d.length)
|
|
163
|
+
})
|
|
164
|
+
.y((d) => this.axis.y.scale(d.x0))
|
|
165
|
+
.curve(curveCatmullRom)
|
|
166
|
+
|
|
167
|
+
let areas = sumstat.map((d) => ({
|
|
168
|
+
curve: result(d.value),
|
|
169
|
+
x: this.axis.x.scale(d.key)
|
|
170
|
+
}))
|
|
171
|
+
return areas
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
function tickValues(scale, whichAxis, params) {
|
|
176
|
+
let { values, count } =
|
|
177
|
+
whichAxis in params.ticks ? params.ticks[whichAxis] : {}
|
|
178
|
+
values =
|
|
179
|
+
Array.isArray(values) && values.length > 2
|
|
180
|
+
? values
|
|
181
|
+
: scale.ticks
|
|
182
|
+
? scale.ticks.apply(scale, [count])
|
|
183
|
+
: scale.domain()
|
|
184
|
+
const ticks = values.map((label) => ({ label, position: scale(label) }))
|
|
185
|
+
|
|
186
|
+
return ticks
|
|
187
|
+
}
|
|
@@ -0,0 +1,327 @@
|
|
|
1
|
+
export const colors = [
|
|
2
|
+
'#FFDE6B',
|
|
3
|
+
'#EF89EE',
|
|
4
|
+
'#F79F1E',
|
|
5
|
+
'#02B8FF',
|
|
6
|
+
'#9F84EC',
|
|
7
|
+
'#15CBC4',
|
|
8
|
+
'#0092FD',
|
|
9
|
+
'#F63A57',
|
|
10
|
+
'#A2CB39',
|
|
11
|
+
'#FF6E2F',
|
|
12
|
+
'#FEB8B9',
|
|
13
|
+
'#af7aa1',
|
|
14
|
+
'#7EFFF5'
|
|
15
|
+
]
|
|
16
|
+
export const palette = {
|
|
17
|
+
indigo: {
|
|
18
|
+
50: '#eef2ff',
|
|
19
|
+
100: '#e0e7ff',
|
|
20
|
+
200: '#c7d2fe',
|
|
21
|
+
300: '#a5b4fc',
|
|
22
|
+
400: '#818cf8',
|
|
23
|
+
500: '#6366f1',
|
|
24
|
+
600: '#4f46e5',
|
|
25
|
+
700: '#4338ca',
|
|
26
|
+
800: '#3730a3',
|
|
27
|
+
900: '#312e81'
|
|
28
|
+
},
|
|
29
|
+
blue: {
|
|
30
|
+
50: '#eff6ff',
|
|
31
|
+
100: '#dbeafe',
|
|
32
|
+
200: '#bfdbfe',
|
|
33
|
+
300: '#93c5fd',
|
|
34
|
+
400: '#60a5fa',
|
|
35
|
+
500: '#3b82f6',
|
|
36
|
+
600: '#2563eb',
|
|
37
|
+
700: '#1d4ed8',
|
|
38
|
+
800: '#1e40af',
|
|
39
|
+
900: '#1e3a8a'
|
|
40
|
+
},
|
|
41
|
+
sky: {
|
|
42
|
+
50: '#f0f9ff',
|
|
43
|
+
100: '#e0f2fe',
|
|
44
|
+
200: '#bae6fd',
|
|
45
|
+
300: '#7dd3fc',
|
|
46
|
+
400: '#38bdf8',
|
|
47
|
+
500: '#0ea5e9',
|
|
48
|
+
600: '#0284c7',
|
|
49
|
+
700: '#0369a1',
|
|
50
|
+
800: '#075985',
|
|
51
|
+
900: '#0c4a6e'
|
|
52
|
+
},
|
|
53
|
+
cyan: {
|
|
54
|
+
50: '#ecfeff',
|
|
55
|
+
100: '#cffafe',
|
|
56
|
+
200: '#a5f3fc',
|
|
57
|
+
300: '#67e8f9',
|
|
58
|
+
400: '#22d3ee',
|
|
59
|
+
500: '#06b6d4',
|
|
60
|
+
600: '#0891b2',
|
|
61
|
+
700: '#0e7490',
|
|
62
|
+
800: '#155e75',
|
|
63
|
+
900: '#164e63'
|
|
64
|
+
},
|
|
65
|
+
teal: {
|
|
66
|
+
50: '#f0fdfa',
|
|
67
|
+
100: '#ccfbf1',
|
|
68
|
+
200: '#99f6e4',
|
|
69
|
+
300: '#5eead4',
|
|
70
|
+
400: '#2dd4bf',
|
|
71
|
+
500: '#14b8a6',
|
|
72
|
+
600: '#0d9488',
|
|
73
|
+
700: '#0f766e',
|
|
74
|
+
800: '#115e59',
|
|
75
|
+
900: '#134e4a'
|
|
76
|
+
},
|
|
77
|
+
emerald: {
|
|
78
|
+
50: '#ecfdf5',
|
|
79
|
+
100: '#d1fae5',
|
|
80
|
+
200: '#a7f3d0',
|
|
81
|
+
300: '#6ee7b7',
|
|
82
|
+
400: '#34d399',
|
|
83
|
+
500: '#10b981',
|
|
84
|
+
600: '#059669',
|
|
85
|
+
700: '#047857',
|
|
86
|
+
800: '#065f46',
|
|
87
|
+
900: '#064e3b'
|
|
88
|
+
},
|
|
89
|
+
green: {
|
|
90
|
+
50: '#f0fdf4',
|
|
91
|
+
100: '#dcfce7',
|
|
92
|
+
200: '#bbf7d0',
|
|
93
|
+
300: '#86efac',
|
|
94
|
+
400: '#4ade80',
|
|
95
|
+
500: '#22c55e',
|
|
96
|
+
600: '#16a34a',
|
|
97
|
+
700: '#15803d',
|
|
98
|
+
800: '#166534',
|
|
99
|
+
900: '#14532d'
|
|
100
|
+
},
|
|
101
|
+
lime: {
|
|
102
|
+
50: '#f7fee7',
|
|
103
|
+
100: '#ecfccb',
|
|
104
|
+
200: '#d9f99d',
|
|
105
|
+
300: '#bef264',
|
|
106
|
+
400: '#a3e635',
|
|
107
|
+
500: '#84cc16',
|
|
108
|
+
600: '#65a30d',
|
|
109
|
+
700: '#4d7c0f',
|
|
110
|
+
800: '#3f6212',
|
|
111
|
+
900: '#365314'
|
|
112
|
+
},
|
|
113
|
+
yellow: {
|
|
114
|
+
50: '#fefce8',
|
|
115
|
+
100: '#fef9c3',
|
|
116
|
+
200: '#fef08a',
|
|
117
|
+
300: '#fde047',
|
|
118
|
+
400: '#facc15',
|
|
119
|
+
500: '#eab308',
|
|
120
|
+
600: '#ca8a04',
|
|
121
|
+
700: '#a16207',
|
|
122
|
+
800: '#854d0e',
|
|
123
|
+
900: '#713f12'
|
|
124
|
+
},
|
|
125
|
+
amber: {
|
|
126
|
+
50: '#fffbeb',
|
|
127
|
+
100: '#fef3c7',
|
|
128
|
+
200: '#fde68a',
|
|
129
|
+
300: '#fcd34d',
|
|
130
|
+
400: '#fbbf24',
|
|
131
|
+
500: '#f59e0b',
|
|
132
|
+
600: '#d97706',
|
|
133
|
+
700: '#b45309',
|
|
134
|
+
800: '#92400e',
|
|
135
|
+
900: '#78350f'
|
|
136
|
+
},
|
|
137
|
+
orange: {
|
|
138
|
+
50: '#fff7ed',
|
|
139
|
+
100: '#ffedd5',
|
|
140
|
+
200: '#fed7aa',
|
|
141
|
+
300: '#fdba74',
|
|
142
|
+
400: '#fb923c',
|
|
143
|
+
500: '#f97316',
|
|
144
|
+
600: '#ea580c',
|
|
145
|
+
700: '#c2410c',
|
|
146
|
+
800: '#9a3412',
|
|
147
|
+
900: '#7c2d12'
|
|
148
|
+
},
|
|
149
|
+
red: {
|
|
150
|
+
50: '#fef2f2',
|
|
151
|
+
100: '#fee2e2',
|
|
152
|
+
200: '#fecaca',
|
|
153
|
+
300: '#fca5a5',
|
|
154
|
+
400: '#f87171',
|
|
155
|
+
500: '#ef4444',
|
|
156
|
+
600: '#dc2626',
|
|
157
|
+
700: '#b91c1c',
|
|
158
|
+
800: '#991b1b',
|
|
159
|
+
900: '#7f1d1d'
|
|
160
|
+
},
|
|
161
|
+
rose: {
|
|
162
|
+
50: '#fff1f2',
|
|
163
|
+
100: '#ffe4e6',
|
|
164
|
+
200: '#fecdd3',
|
|
165
|
+
300: '#fda4af',
|
|
166
|
+
400: '#fb7185',
|
|
167
|
+
500: '#f43f5e',
|
|
168
|
+
600: '#e11d48',
|
|
169
|
+
700: '#be123c',
|
|
170
|
+
800: '#9f1239',
|
|
171
|
+
900: '#881337'
|
|
172
|
+
},
|
|
173
|
+
pink: {
|
|
174
|
+
50: '#fdf2f8',
|
|
175
|
+
100: '#fce7f3',
|
|
176
|
+
200: '#fbcfe8',
|
|
177
|
+
300: '#f9a8d4',
|
|
178
|
+
400: '#f472b6',
|
|
179
|
+
500: '#ec4899',
|
|
180
|
+
600: '#db2777',
|
|
181
|
+
700: '#be185d',
|
|
182
|
+
800: '#9d174d',
|
|
183
|
+
900: '#831843'
|
|
184
|
+
},
|
|
185
|
+
fuchsia: {
|
|
186
|
+
50: '#fdf4ff',
|
|
187
|
+
100: '#fae8ff',
|
|
188
|
+
200: '#f5d0fe',
|
|
189
|
+
300: '#f0abfc',
|
|
190
|
+
400: '#e879f9',
|
|
191
|
+
500: '#d946ef',
|
|
192
|
+
600: '#c026d3',
|
|
193
|
+
700: '#a21caf',
|
|
194
|
+
800: '#86198f',
|
|
195
|
+
900: '#701a75'
|
|
196
|
+
},
|
|
197
|
+
purple: {
|
|
198
|
+
50: '#faf5ff',
|
|
199
|
+
100: '#f3e8ff',
|
|
200
|
+
200: '#e9d5ff',
|
|
201
|
+
300: '#d8b4fe',
|
|
202
|
+
400: '#c084fc',
|
|
203
|
+
500: '#a855f7',
|
|
204
|
+
600: '#9333ea',
|
|
205
|
+
700: '#7e22ce',
|
|
206
|
+
800: '#6b21a8',
|
|
207
|
+
900: '#581c87'
|
|
208
|
+
},
|
|
209
|
+
violet: {
|
|
210
|
+
50: '#f5f3ff',
|
|
211
|
+
100: '#ede9fe',
|
|
212
|
+
200: '#ddd6fe',
|
|
213
|
+
300: '#c4b5fd',
|
|
214
|
+
400: '#a78bfa',
|
|
215
|
+
500: '#8b5cf6',
|
|
216
|
+
600: '#7c3aed',
|
|
217
|
+
700: '#6d28d9',
|
|
218
|
+
800: '#5b21b6',
|
|
219
|
+
900: '#4c1d95'
|
|
220
|
+
},
|
|
221
|
+
warmGray: {
|
|
222
|
+
50: '#fafaf9',
|
|
223
|
+
100: '#f5f5f4',
|
|
224
|
+
200: '#e7e5e4',
|
|
225
|
+
300: '#d6d3d1',
|
|
226
|
+
400: '#a8a29e',
|
|
227
|
+
500: '#78716c',
|
|
228
|
+
600: '#57534e',
|
|
229
|
+
700: '#44403c',
|
|
230
|
+
800: '#292524',
|
|
231
|
+
900: '#1c1917'
|
|
232
|
+
},
|
|
233
|
+
trueGray: {
|
|
234
|
+
50: '#fafafa',
|
|
235
|
+
100: '#f5f5f5',
|
|
236
|
+
200: '#e5e5e5',
|
|
237
|
+
300: '#d4d4d4',
|
|
238
|
+
400: '#a3a3a3',
|
|
239
|
+
500: '#737373',
|
|
240
|
+
600: '#525252',
|
|
241
|
+
700: '#404040',
|
|
242
|
+
800: '#262626',
|
|
243
|
+
900: '#171717'
|
|
244
|
+
},
|
|
245
|
+
gray: {
|
|
246
|
+
50: '#fafafa',
|
|
247
|
+
100: '#f4f4f5',
|
|
248
|
+
200: '#e4e4e7',
|
|
249
|
+
300: '#d4d4d8',
|
|
250
|
+
400: '#a1a1aa',
|
|
251
|
+
500: '#71717a',
|
|
252
|
+
600: '#52525b',
|
|
253
|
+
700: '#3f3f46',
|
|
254
|
+
800: '#27272a',
|
|
255
|
+
900: '#18181b'
|
|
256
|
+
},
|
|
257
|
+
blueGray: {
|
|
258
|
+
50: '#f8fafc',
|
|
259
|
+
100: '#f1f5f9',
|
|
260
|
+
200: '#e2e8f0',
|
|
261
|
+
300: '#cbd5e1',
|
|
262
|
+
400: '#94a3b8',
|
|
263
|
+
500: '#64748b',
|
|
264
|
+
600: '#475569',
|
|
265
|
+
700: '#334155',
|
|
266
|
+
800: '#1e293b',
|
|
267
|
+
900: '#0f172a'
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
export class ColorBrewer {
|
|
272
|
+
constructor() {
|
|
273
|
+
this.colors = ['blue', 'pink', 'teal', 'indigo', 'purple', 'amber', 'rose']
|
|
274
|
+
this.palette = palette
|
|
275
|
+
this.grayscale = this.palette['trueGray']
|
|
276
|
+
this.fill = 100
|
|
277
|
+
this.stroke = 600
|
|
278
|
+
this.contrast = 600
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
dark() {
|
|
282
|
+
this.fill = 500
|
|
283
|
+
this.stroke = 700
|
|
284
|
+
this.contrast = 100
|
|
285
|
+
return this
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
mix(fill, stroke, contrast) {
|
|
289
|
+
this.fill = Object.keys(this.grayscale).includes(fill) ? fill : this.fill
|
|
290
|
+
this.stroke = Object.keys(this.grayscale).includes(stroke)
|
|
291
|
+
? stroke
|
|
292
|
+
: this.stroke
|
|
293
|
+
this.contrast = Object.keys(this.grayscale).includes(contrast)
|
|
294
|
+
? contrast
|
|
295
|
+
: this.contrast
|
|
296
|
+
|
|
297
|
+
return this
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
swatch(colors) {
|
|
301
|
+
this.palette = colors
|
|
302
|
+
return this
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
filter(colors) {
|
|
306
|
+
this.colors = colors
|
|
307
|
+
return this
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
gray() {
|
|
311
|
+
return {
|
|
312
|
+
fill: this.grayscale[this.fill],
|
|
313
|
+
stroke: this.grayscale[this.stroke],
|
|
314
|
+
contrast: this.grayscale[this.contrast]
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
brew() {
|
|
319
|
+
const palette = this.colors.map((color) => ({
|
|
320
|
+
fill: this.palette[color][this.fill],
|
|
321
|
+
stroke: this.palette[color][this.stroke],
|
|
322
|
+
contrast: this.palette[color][this.contrast]
|
|
323
|
+
}))
|
|
324
|
+
|
|
325
|
+
return palette
|
|
326
|
+
}
|
|
327
|
+
}
|