-
-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
8 changed files
with
770 additions
and
16 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,137 @@ | ||
import { addMinutes, startOfDay, startOfToday, subDays } from 'date-fns'; | ||
import { degreesToRadians, radiansToDegrees } from './math'; | ||
|
||
/** | ||
* Get random number between min (inclusive) and max (exclusive) | ||
* see: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/random#getting_a_random_number_between_0_inclusive_and_1_exclusive | ||
*/ | ||
export function getRandomNumber(min: number, max: number) { | ||
return Math.random() * (max - min) + min; | ||
} | ||
|
||
/** | ||
* Get random integer between min (inclusive) and max (inclusive by default) | ||
* see: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/random#getting_a_random_integer_between_two_values_inclusive | ||
*/ | ||
export function getRandomInteger(min: number, max: number, includeMax = true) { | ||
min = Math.ceil(min); | ||
max = Math.floor(max); | ||
return Math.floor(Math.random() * (max - min + (includeMax ? 1 : 0)) + min); | ||
} | ||
|
||
export function createSeries(options: { count?: number; min: number; max: number; keys?: Array<string>; value?: 'number' | 'integer' }) { | ||
const count = options.count ?? 10; | ||
const min = options.min; | ||
const max = options.max; | ||
const keys = options.keys ?? ['y']; | ||
|
||
return Array.from({ length: count }).map((_) => { | ||
return { | ||
x: options.value === 'integer' ? getRandomInteger(min, max) : getRandomNumber(min, max), | ||
...Object.fromEntries( | ||
keys.map((key) => { | ||
return [key, options.value === 'integer' ? getRandomInteger(min, max) : getRandomNumber(min, max)]; | ||
}) | ||
) | ||
}; | ||
}); | ||
} | ||
|
||
export function createDateSeries(options: { | ||
count?: number; | ||
min: number; | ||
max: number; | ||
keys?: Array<string>; | ||
value?: 'number' | 'integer'; | ||
}) { | ||
const now = startOfToday(); | ||
|
||
const count = options.count ?? 10; | ||
const min = options.min; | ||
const max = options.max; | ||
const keys = options.keys ?? ['value']; | ||
|
||
return Array.from({ length: count }).map((_, i) => { | ||
return { | ||
date: subDays(now, count - i - 1), | ||
...Object.fromEntries( | ||
keys.map((key) => { | ||
return [key, options.value === 'integer' ? getRandomInteger(min, max) : getRandomNumber(min, max)]; | ||
}) | ||
) | ||
}; | ||
}); | ||
} | ||
|
||
export function createTimeSeries(options: { count?: number; min: number; max: number; keys: Array<string>; value: 'number' | 'integer' }) { | ||
const count = options.count ?? 10; | ||
const min = options.min; | ||
const max = options.max; | ||
const keys = options.keys ?? ['value']; | ||
|
||
let lastStartDate = startOfDay(new Date()); | ||
|
||
const timeSeries = Array.from({ length: count }).map((_, i) => { | ||
const startDate = addMinutes(lastStartDate, getRandomInteger(0, 60)); | ||
const endDate = addMinutes(startDate, getRandomInteger(5, 60)); | ||
lastStartDate = startDate; | ||
return { | ||
name: `item ${i + 1}`, | ||
startDate, | ||
endDate, | ||
...Object.fromEntries( | ||
keys.map((key) => { | ||
return [key, options.value === 'integer' ? getRandomInteger(min, max) : getRandomNumber(min, max)]; | ||
}) | ||
) | ||
}; | ||
}); | ||
|
||
return timeSeries; | ||
} | ||
|
||
export const wideData = [ | ||
{ year: '2019', apples: 3840, bananas: 1920, cherries: 960, dates: 400 }, | ||
{ year: '2018', apples: 1600, bananas: 1440, cherries: 960, dates: 400 }, | ||
{ year: '2017', apples: 820, bananas: 1000, cherries: 640, dates: 400 }, | ||
{ year: '2016', apples: 820, bananas: 560, cherries: 720, dates: 400 } | ||
]; | ||
|
||
export const longData = [ | ||
{ year: '2019', basket: 1, fruit: 'apples', value: 3840 }, | ||
{ year: '2019', basket: 1, fruit: 'bananas', value: 1920 }, | ||
{ year: '2019', basket: 2, fruit: 'cherries', value: 960 }, | ||
{ year: '2019', basket: 2, fruit: 'dates', value: 400 }, | ||
|
||
{ year: '2018', basket: 1, fruit: 'apples', value: 1600 }, | ||
{ year: '2018', basket: 1, fruit: 'bananas', value: 1440 }, | ||
{ year: '2018', basket: 2, fruit: 'cherries', value: 960 }, | ||
{ year: '2018', basket: 2, fruit: 'dates', value: 400 }, | ||
|
||
{ year: '2017', basket: 1, fruit: 'apples', value: 820 }, | ||
{ year: '2017', basket: 1, fruit: 'bananas', value: 1000 }, | ||
{ year: '2017', basket: 2, fruit: 'cherries', value: 640 }, | ||
{ year: '2017', basket: 2, fruit: 'dates', value: 400 }, | ||
|
||
{ year: '2016', basket: 1, fruit: 'apples', value: 820 }, | ||
{ year: '2016', basket: 1, fruit: 'bananas', value: 560 }, | ||
{ year: '2016', basket: 2, fruit: 'cherries', value: 720 }, | ||
{ year: '2016', basket: 2, fruit: 'dates', value: 400 } | ||
]; | ||
|
||
export function getPhyllotaxis({ radius, count, width, height }) { | ||
// Phyllotaxis: https://www.youtube.com/watch?v=KWoJgHFYWxY | ||
const rads = Math.PI * (3 - Math.sqrt(5)); // ~2.4 rads or ~137.5 degrees | ||
return getSpiral({ angle: radiansToDegrees(rads), radius, count, width, height }); | ||
} | ||
|
||
export function getSpiral({ angle, radius, count, width, height }) { | ||
return Array.from({ length: count }, (_, i) => { | ||
const r = radius * Math.sqrt(i); | ||
const a = degreesToRadians(angle * i); | ||
return { | ||
x: width / 2 + r * Math.cos(a), | ||
y: height / 2 + r * Math.sin(a) | ||
}; | ||
}); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
/** | ||
* Convert degrees to radians | ||
*/ | ||
export function degreesToRadians(degrees: number) { | ||
return (degrees * Math.PI) / 180; | ||
} | ||
|
||
/** | ||
* Convert radians to degrees | ||
*/ | ||
export function radiansToDegrees(radians: number) { | ||
return radians * (180 / Math.PI); | ||
} |
32 changes: 32 additions & 0 deletions
32
apps/console2/src/routes/(app)/dashboard/reports/+page.svelte
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
<script lang="ts"> | ||
import { formatDate, PeriodType } from 'svelte-ux'; | ||
import { scaleBand } from 'd3-scale'; | ||
import { Chart, Svg, Axis, Bars } from 'layerchart'; | ||
import { createDateSeries } from '$lib/utils/genData'; | ||
const data = createDateSeries({ | ||
count: 30, | ||
min: 20, | ||
max: 100, | ||
value: 'integer', | ||
keys: ['value', 'baseline'] | ||
}); | ||
</script> | ||
|
||
<div class="h-[300px] rounded border p-4"> | ||
<Chart | ||
{data} | ||
x="date" | ||
xScale={scaleBand().padding(0.4)} | ||
y="value" | ||
yDomain={[0, null]} | ||
yNice | ||
padding={{ left: 16, bottom: 24 }} | ||
> | ||
<Svg> | ||
<Axis placement="left" grid rule /> | ||
<Axis placement="bottom" format={(d) => formatDate(d, PeriodType.Day, 'short')} rule /> | ||
<Bars radius={4} strokeWidth={1} class="fill-accent-500" /> | ||
</Svg> | ||
</Chart> | ||
</div> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,17 +1,22 @@ | ||
import baseConfig from '@spectacular/skeleton/tailwind.config'; | ||
import colors from 'tailwindcss/colors'; | ||
import type { Config } from 'tailwindcss'; | ||
|
||
export default { | ||
presets: [baseConfig], | ||
content: [...baseConfig.content], | ||
content: [...baseConfig.content, './node_modules/layerchart/**/*.{svelte,js}'], | ||
theme: { | ||
extend: { | ||
colors: { | ||
accent: colors.indigo | ||
}, | ||
fontFamily: { | ||
heading: "'Sora Variable', sans-serif", | ||
sans: "'Inter Variable', sans-serif", | ||
mono: "'JetBrains Mono', monospace", | ||
serif: "'Roboto Slab Variable', sans-serif" | ||
} | ||
} | ||
} | ||
}, | ||
plugins: [...baseConfig.plugins, require('svelte-ux/plugins/tailwind.cjs')] | ||
} satisfies Config; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1 @@ | ||
export { default as Tick } from './tick.astro'; | ||
export { default as Tick } from './Tick.astro'; |
Oops, something went wrong.
f7ab953
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Successfully deployed to the following URLs:
spectacular-docs – ./apps/docs
spectacular-docs.vercel.app
spectacular-docs-git-main-xmlking.vercel.app
spectacular-docs-xmlking.vercel.app