feat: charts

This commit is contained in:
Alisa | side.one 2023-05-28 01:27:34 +08:00
parent 06574f2f2c
commit bfbe241ff4
10 changed files with 238 additions and 868 deletions

View File

@ -1,74 +0,0 @@
/* color palette from <https://github.com/vuejs/theme> */
:root {
--vt-c-white: #ffffff;
--vt-c-white-soft: #f8f8f8;
--vt-c-white-mute: #f2f2f2;
--vt-c-black: #181818;
--vt-c-black-soft: #222222;
--vt-c-black-mute: #282828;
--vt-c-indigo: #2c3e50;
--vt-c-divider-light-1: rgba(60, 60, 60, 0.29);
--vt-c-divider-light-2: rgba(60, 60, 60, 0.12);
--vt-c-divider-dark-1: rgba(84, 84, 84, 0.65);
--vt-c-divider-dark-2: rgba(84, 84, 84, 0.48);
--vt-c-text-light-1: var(--vt-c-indigo);
--vt-c-text-light-2: rgba(60, 60, 60, 0.66);
--vt-c-text-dark-1: var(--vt-c-white);
--vt-c-text-dark-2: rgba(235, 235, 235, 0.64);
}
/* semantic color variables for this project */
:root {
--color-background: var(--vt-c-white);
--color-background-soft: var(--vt-c-white-soft);
--color-background-mute: var(--vt-c-white-mute);
--color-border: var(--vt-c-divider-light-2);
--color-border-hover: var(--vt-c-divider-light-1);
--color-heading: var(--vt-c-text-light-1);
--color-text: var(--vt-c-text-light-1);
--section-gap: 160px;
}
@media (prefers-color-scheme: dark) {
:root {
--color-background: var(--vt-c-black);
--color-background-soft: var(--vt-c-black-soft);
--color-background-mute: var(--vt-c-black-mute);
--color-border: var(--vt-c-divider-dark-2);
--color-border-hover: var(--vt-c-divider-dark-1);
--color-heading: var(--vt-c-text-dark-1);
--color-text: var(--vt-c-text-dark-2);
}
}
*,
*::before,
*::after {
box-sizing: border-box;
margin: 0;
position: relative;
font-weight: normal;
}
body {
min-height: 100vh;
color: var(--color-text);
background: var(--color-background);
transition: color 0.5s, background-color 0.5s;
line-height: 1.6;
font-family: Inter, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu,
Cantarell, 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif;
font-size: 15px;
text-rendering: optimizeLegibility;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}

View File

@ -1,35 +0,0 @@
@import './base.css';
#app {
max-width: 1280px;
margin: 0 auto;
padding: 2rem;
font-weight: normal;
}
a,
.green {
text-decoration: none;
color: hsla(160, 100%, 37%, 1);
transition: 0.4s;
}
@media (hover: hover) {
a:hover {
background-color: hsla(160, 100%, 37%, 0.2);
}
}
@media (min-width: 1024px) {
body {
display: flex;
place-items: center;
}
#app {
display: grid;
grid-template-columns: 1fr 1fr;
padding: 0 2rem;
}
}

View File

@ -7,7 +7,7 @@ const props = defineProps<{
themes: ThemeSwitcherTheme[]; themes: ThemeSwitcherTheme[];
}>(); }>();
const theme = ref('light'); const theme = ref(window.localStorage.getItem('theme') || 'dark');
const { const {
state: currentThemeName, state: currentThemeName,
next: getNextThemeName, next: getNextThemeName,
@ -37,6 +37,7 @@ const changeMode = (val: 'dark' | 'light' | 'system') => {
document.documentElement.classList.remove('dark'); document.documentElement.classList.remove('dark');
} }
document.documentElement.setAttribute('data-theme', value); document.documentElement.setAttribute('data-theme', value);
window.localStorage.setItem('theme', value);
}; };
// Update icon if theme is changed from other sources // Update icon if theme is changed from other sources
watch(theme, (val: 'dark' | 'light' | 'system') => { watch(theme, (val: 'dark' | 'light' | 'system') => {

View File

@ -1,24 +1,17 @@
<script lang="ts" setup> <script lang="ts" setup>
import ApexCharts from 'vue3-apexcharts'; import ApexCharts from 'vue3-apexcharts';
import { useTheme } from 'vuetify'; import { computed } from 'vue';
import { getDonutChartConfig } from './apexChartConfig'; import { getDonutChartConfig } from './apexChartConfig';
const props = defineProps(['series', 'labels']); const props = defineProps(['series', 'labels']);
const vuetifyTheme = useTheme();
const expenseRationChartConfig = computed(() => const expenseRationChartConfig = computed(() =>
getDonutChartConfig(vuetifyTheme.current.value, props.labels) getDonutChartConfig(window.localStorage.getItem('theme') || 'dark', props.labels)
); );
</script> </script>
<template> <template>
<ApexCharts <ApexCharts type="donut" height="410" :options="expenseRationChartConfig" :series="series" />
type="donut"
height="410"
:options="expenseRationChartConfig"
:series="series"
/>
</template> </template>
<script lang="ts"> <script lang="ts">

View File

@ -1,15 +1,13 @@
<script lang="ts" setup> <script lang="ts" setup>
import ApexCharts from 'vue3-apexcharts'; import ApexCharts from 'vue3-apexcharts';
import { useTheme } from 'vuetify';
import { getMarketPriceChartConfig } from './apexChartConfig'; import { getMarketPriceChartConfig } from './apexChartConfig';
import { useIndexModule } from '@/modules/[chain]/indexStore'; import { useIndexModule } from '@/modules/[chain]/indexStore';
import { computed, ref } from '@vue/reactivity'; import { computed, ref } from '@vue/reactivity';
const store = useIndexModule(); const store = useIndexModule();
const vuetifyTheme = useTheme();
const chartConfig = computed(() => { const chartConfig = computed(() => {
const labels = store.marketData.prices.map((item: any) => item[0]); const labels = store.marketData.prices.map((item: any) => item[0]);
return getMarketPriceChartConfig(vuetifyTheme.current.value, labels); return getMarketPriceChartConfig(window.localStorage.getItem('theme') || 'dark', labels);
}); });
const kind = ref('price'); const kind = ref('price');
const series = computed(() => { const series = computed(() => {
@ -31,25 +29,14 @@ function changeChart(type: string) {
<template> <template>
<div class="tabs tabs-boxed bg-transparent justify-end"> <div class="tabs tabs-boxed bg-transparent justify-end">
<a <a class="tab text-xs mr-2 text-gray-400 uppercase" :class="{ 'tab-active': kind === 'price' }"
class="tab text-xs mr-2 text-gray-400 uppercase" @click="changeChart('price')">
:class="{ 'tab-active': kind === 'price' }"
@click="changeChart('price')"
>
Price Price
</a> </a>
<a <a class="tab text-xs text-gray-400 uppercase" :class="{ 'tab-active': kind === 'volume' }"
class="tab text-xs text-gray-400 uppercase" @click="changeChart('volume')">
:class="{ 'tab-active': kind === 'volume' }"
@click="changeChart('volume')"
>
Volume Volume
</a> </a>
</div> </div>
<ApexCharts <ApexCharts type="area" height="230" :options="chartConfig" :series="series" />
type="area"
height="230"
:options="chartConfig"
:series="series"
/>
</template> </template>

View File

@ -1,38 +1,191 @@
import type { ThemeInstance } from 'vuetify';
import { hexToRgb } from '@/plugins/vuetify/@layouts/utils';
import numeral from 'numeral'; import numeral from 'numeral';
// 👉 Colors variables const themeColors = (theme: string) => {
const colorVariables = ( if (theme === 'light') {
themeColors: ThemeInstance['themes']['value']['colors']
) => {
const themeSecondaryTextColor = `rgba(${hexToRgb(
themeColors.colors['on-surface']
)},${themeColors.variables['medium-emphasis-opacity']})`;
const themeDisabledTextColor = `rgba(${hexToRgb(
themeColors.colors['on-surface']
)},${themeColors.variables['disabled-opacity']})`;
const themeBorderColor = `rgba(${hexToRgb(
String(themeColors.variables['border-color'])
)},${themeColors.variables['border-opacity']})`;
const themePrimaryTextColor = `rgba(${hexToRgb(
themeColors.colors['on-surface']
)},${themeColors.variables['high-emphasis-opacity']})`;
return { return {
themeSecondaryTextColor, dark: false,
themeDisabledTextColor, colors: {
themeBorderColor, background: '#F7F7F9',
themePrimaryTextColor, surface: '#FFFFFF',
'surface-variant': '#424242',
'on-surface-variant': '#EEEEEE',
primary: '#666CFF',
'primary-darken-1': '#3700B3',
secondary: '#6D788D',
'secondary-darken-1': '#018786',
error: '#FF4D49',
info: '#26C6F9',
success: '#72E128',
warning: '#FDB528',
'on-primary': '#fff',
'on-secondary': '#fff',
'on-success': '#fff',
'on-info': '#fff',
'on-warning': '#fff',
'on-background': '#4c4e64',
'on-surface': '#4c4e64',
'perfect-scrollbar-thumb': '#DBDADE',
'snackbar-background': '#212121',
'tooltip-background': '#262732',
'alert-background': '#F7F7F9',
'grey-50': '#FAFAFA',
'grey-100': '#F4F5FA',
'grey-200': '#F5F5F7',
'grey-300': '#E0E0E0',
'grey-400': '#BDBDBD',
'grey-500': '#9E9E9E',
'grey-600': '#757575',
'grey-700': '#616161',
'grey-800': '#424242',
'grey-900': '#212121',
'on-primary-darken-1': '#fff',
'on-secondary-darken-1': '#fff',
'on-error': '#fff',
'on-perfect-scrollbar-thumb': '#000',
'on-snackbar-background': '#fff',
'on-tooltip-background': '#fff',
'on-alert-background': '#000',
'on-grey-50': '#000',
'on-grey-100': '#000',
'on-grey-200': '#000',
'on-grey-300': '#000',
'on-grey-400': '#000',
'on-grey-500': '#fff',
'on-grey-600': '#fff',
'on-grey-700': '#fff',
'on-grey-800': '#fff',
'on-grey-900': '#fff',
},
variables: {
'border-color': '#4c4e64',
'border-opacity': 0.12,
'high-emphasis-opacity': 0.87,
'medium-emphasis-opacity': 0.6,
'disabled-opacity': 0.38,
'idle-opacity': 0.04,
'hover-opacity': 0.05,
'focus-opacity': 0.12,
'selected-opacity': 0.08,
'activated-opacity': 0.12,
'pressed-opacity': 0.12,
'dragged-opacity': 0.08,
'theme-kbd': '#212529',
'theme-on-kbd': '#FFFFFF',
'theme-code': '#F5F5F5',
'theme-on-code': '#000000',
'code-color': '#d400ff',
'overlay-scrim-background': '#4C4E64',
'overlay-scrim-opacity': 0.5,
'shadow-key-umbra-opacity': 'rgba(var(--v-theme-on-surface), 0.08)',
'shadow-key-penumbra-opacity': 'rgba(var(--v-theme-on-surface), 0.05)',
'shadow-key-ambient-opacity': 'rgba(var(--v-theme-on-surface), 0.03)',
},
};
}
return {
dark: true,
colors: {
background: '#282A42',
surface: '#30334E',
'surface-variant': '#BDBDBD',
'on-surface-variant': '#424242',
primary: '#666CFF',
'primary-darken-1': '#3700B3',
secondary: '#6D788D',
'secondary-darken-1': '#03DAC5',
error: '#FF4D49',
info: '#26C6F9',
success: '#72E128',
warning: '#FDB528',
'on-primary': '#fff',
'on-secondary': '#fff',
'on-success': '#fff',
'on-info': '#fff',
'on-warning': '#fff',
'on-background': '#eaeaff',
'on-surface': '#eaeaff',
'perfect-scrollbar-thumb': '#4A5072',
'snackbar-background': '#F5F5F5',
'on-snackbar-background': '#30334E',
'tooltip-background': '#464A65',
'alert-background': '#282A42',
'grey-50': '#2A2E42',
'grey-100': '#41435c',
'grey-200': '#3A3E5B',
'grey-300': '#5E6692',
'grey-400': '#7983BB',
'grey-500': '#8692D0',
'grey-600': '#AAB3DE',
'grey-700': '#B6BEE3',
'grey-800': '#CFD3EC',
'grey-900': '#E7E9F6',
'on-primary-darken-1': '#fff',
'on-secondary-darken-1': '#000',
'on-error': '#fff',
'on-perfect-scrollbar-thumb': '#fff',
'on-tooltip-background': '#fff',
'on-alert-background': '#fff',
'on-grey-50': '#fff',
'on-grey-100': '#fff',
'on-grey-200': '#fff',
'on-grey-300': '#fff',
'on-grey-400': '#fff',
'on-grey-500': '#fff',
'on-grey-600': '#000',
'on-grey-700': '#000',
'on-grey-800': '#000',
'on-grey-900': '#000',
},
variables: {
'border-color': '#eaeaff',
'border-opacity': 0.12,
'high-emphasis-opacity': 0.87,
'medium-emphasis-opacity': 0.6,
'disabled-opacity': 0.38,
'idle-opacity': 0.1,
'hover-opacity': 0.05,
'focus-opacity': 0.12,
'selected-opacity': 0.08,
'activated-opacity': 0.12,
'pressed-opacity': 0.16,
'dragged-opacity': 0.08,
'theme-kbd': '#212529',
'theme-on-kbd': '#FFFFFF',
'theme-code': '#343434',
'theme-on-code': '#CCCCCC',
'code-color': '#d400ff',
'overlay-scrim-background': '#101121',
'overlay-scrim-opacity': 0.6,
'shadow-key-umbra-opacity': 'rgba(20, 21, 33, 0.08)',
'shadow-key-penumbra-opacity': 'rgba(20, 21, 33, 0.05)',
'shadow-key-ambient-opacity': 'rgba(20, 21, 33, 0.03)',
},
};
};
// 👉 Colors variables
const colorVariables = (theme: string) => {
if (theme === 'light') {
return {
themeSecondaryTextColor: 'rgba(76,78,100,0.6)',
themeDisabledTextColor: 'rgba(76,78,100,0.38)',
themeBorderColor: 'rgba(76,78,100,0.12)',
themePrimaryTextColor: 'rgba(76,78,100,0.87)',
};
}
return {
themeSecondaryTextColor: 'rgba(234,234,255,0.6)',
themeDisabledTextColor: 'rgba(234,234,255,0.38)',
themeBorderColor: 'rgba(234,234,255,0.12)',
themePrimaryTextColor: 'rgba(234,234,255,0.87)',
}; };
}; };
/// Price Chart config /// Price Chart config
export const getMarketPriceChartConfig = ( export const getMarketPriceChartConfig = (
themeColors: ThemeInstance['themes']['value']['colors'], theme: string,
categories: string[] categories: string[]
) => { ) => {
const { themeSecondaryTextColor, themeBorderColor, themeDisabledTextColor } = const { themeSecondaryTextColor, themeBorderColor, themeDisabledTextColor } =
colorVariables(themeColors); colorVariables(theme);
return { return {
chart: { chart: {
@ -66,7 +219,7 @@ export const getMarketPriceChartConfig = (
}, },
}, },
colors: [themeColors.colors.primary], colors: [themeColors(theme).colors.primary],
fill: { fill: {
opacity: 0.5, opacity: 0.5,
type: 'gradient', type: 'gradient',
@ -102,338 +255,8 @@ export const getMarketPriceChartConfig = (
}, },
}; };
}; };
/// default config
export const getScatterChartConfig = (
themeColors: ThemeInstance['themes']['value']['colors']
) => {
const scatterColors = {
series1: '#ff9f43',
series2: '#7367f0',
series3: '#28c76f',
};
const { themeSecondaryTextColor, themeBorderColor, themeDisabledTextColor } =
colorVariables(themeColors);
return {
chart: {
parentHeightOffset: 0,
toolbar: { show: false },
zoom: {
type: 'xy',
enabled: true,
},
},
legend: {
position: 'top',
horizontalAlign: 'left',
markers: { offsetX: -3 },
labels: { colors: themeSecondaryTextColor },
itemMargin: {
vertical: 3,
horizontal: 10,
},
},
colors: [
scatterColors.series1,
scatterColors.series2,
scatterColors.series3,
],
grid: {
borderColor: themeBorderColor,
xaxis: {
lines: { show: true },
},
},
yaxis: {
labels: {
style: { colors: themeDisabledTextColor },
},
},
xaxis: {
tickAmount: 10,
axisBorder: { show: false },
axisTicks: { color: themeBorderColor },
crosshairs: {
stroke: { color: themeBorderColor },
},
labels: {
style: { colors: themeDisabledTextColor },
formatter: (val: string) => parseFloat(val).toFixed(1),
},
},
};
};
export const getLineChartSimpleConfig = (
themeColors: ThemeInstance['themes']['value']['colors']
) => {
const { themeBorderColor, themeDisabledTextColor } =
colorVariables(themeColors);
return {
chart: {
parentHeightOffset: 0,
zoom: { enabled: false },
toolbar: { show: false },
},
colors: ['#ff9f43'],
stroke: { curve: 'straight' },
dataLabels: { enabled: false },
markers: {
strokeWidth: 7,
strokeOpacity: 1,
colors: ['#ff9f43'],
strokeColors: ['#fff'],
},
grid: {
padding: { top: -10 },
borderColor: themeBorderColor,
xaxis: {
lines: { show: true },
},
},
tooltip: {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
custom(data: any) {
return `<div class='bar-chart pa-2'>
<span>${data.series[data.seriesIndex][data.dataPointIndex]}%</span>
</div>`;
},
},
yaxis: {
labels: {
style: { colors: themeDisabledTextColor },
},
},
xaxis: {
axisBorder: { show: false },
axisTicks: { color: themeBorderColor },
crosshairs: {
stroke: { color: themeBorderColor },
},
labels: {
style: { colors: themeDisabledTextColor },
},
categories: [
'7/12',
'8/12',
'9/12',
'10/12',
'11/12',
'12/12',
'13/12',
'14/12',
'15/12',
'16/12',
'17/12',
'18/12',
'19/12',
'20/12',
'21/12',
],
},
};
};
export const getBarChartConfig = (
themeColors: ThemeInstance['themes']['value']['colors']
) => {
const { themeBorderColor, themeDisabledTextColor } =
colorVariables(themeColors);
return {
chart: {
parentHeightOffset: 0,
toolbar: { show: false },
},
colors: ['#00cfe8'],
dataLabels: { enabled: false },
plotOptions: {
bar: {
borderRadius: 8,
barHeight: '30%',
horizontal: true,
startingShape: 'rounded',
},
},
grid: {
borderColor: themeBorderColor,
xaxis: {
lines: { show: false },
},
padding: {
top: -10,
},
},
yaxis: {
labels: {
style: { colors: themeDisabledTextColor },
},
},
xaxis: {
axisBorder: { show: false },
axisTicks: { color: themeBorderColor },
categories: [
'MON, 11',
'THU, 14',
'FRI, 15',
'MON, 18',
'WED, 20',
'FRI, 21',
'MON, 23',
],
labels: {
style: { colors: themeDisabledTextColor },
},
},
};
};
export const getCandlestickChartConfig = (
themeColors: ThemeInstance['themes']['value']['colors']
) => {
const candlestickColors = {
series1: '#28c76f',
series2: '#ea5455',
};
const { themeBorderColor, themeDisabledTextColor } =
colorVariables(themeColors);
return {
chart: {
parentHeightOffset: 0,
toolbar: { show: false },
},
plotOptions: {
bar: { columnWidth: '40%' },
candlestick: {
colors: {
upward: candlestickColors.series1,
downward: candlestickColors.series2,
},
},
},
grid: {
padding: { top: -10 },
borderColor: themeBorderColor,
xaxis: {
lines: { show: true },
},
},
yaxis: {
tooltip: { enabled: true },
crosshairs: {
stroke: { color: themeBorderColor },
},
labels: {
style: { colors: themeDisabledTextColor },
},
},
xaxis: {
type: 'datetime',
axisBorder: { show: false },
axisTicks: { color: themeBorderColor },
crosshairs: {
stroke: { color: themeBorderColor },
},
labels: {
style: { colors: themeDisabledTextColor },
},
},
};
};
export const getRadialBarChartConfig = (
themeColors: ThemeInstance['themes']['value']['colors']
) => {
const radialBarColors = {
series1: '#fdd835',
series2: '#32baff',
series3: '#00d4bd',
series4: '#7367f0',
series5: '#FFA1A1',
};
const { themeSecondaryTextColor, themePrimaryTextColor } =
colorVariables(themeColors);
return {
stroke: { lineCap: 'round' },
labels: ['Comments', 'Replies', 'Shares'],
legend: {
show: true,
position: 'bottom',
labels: {
colors: themeSecondaryTextColor,
},
markers: {
offsetX: -3,
},
itemMargin: {
vertical: 3,
horizontal: 10,
},
},
colors: [
radialBarColors.series1,
radialBarColors.series2,
radialBarColors.series4,
],
plotOptions: {
radialBar: {
hollow: { size: '30%' },
track: {
margin: 15,
background: themeColors.colors['grey-100'],
},
dataLabels: {
name: {
fontSize: '2rem',
},
value: {
fontSize: '1rem',
color: themeSecondaryTextColor,
},
total: {
show: true,
fontWeight: 400,
label: 'Comments',
fontSize: '1.125rem',
color: themePrimaryTextColor,
// eslint-disable-next-line @typescript-eslint/no-explicit-any
formatter(w: {
globals: { seriesTotals: any[]; series: string | any[] };
}) {
const totalValue =
w.globals.seriesTotals.reduce((a: number, b: number) => {
return a + b;
}, 0) / w.globals.series.length;
if (totalValue % 1 === 0) return `${totalValue}%`;
else return `${totalValue.toFixed(2)}%`;
},
},
},
},
},
grid: {
padding: {
top: -35,
bottom: -30,
},
},
};
};
export const getDonutChartConfig = ( export const getDonutChartConfig = (
themeColors: ThemeInstance['themes']['value']['colors'], theme: string,
labels: string[] labels: string[]
) => { ) => {
const donutColors = { const donutColors = {
@ -445,7 +268,7 @@ export const getDonutChartConfig = (
}; };
const { themeSecondaryTextColor, themePrimaryTextColor } = const { themeSecondaryTextColor, themePrimaryTextColor } =
colorVariables(themeColors); colorVariables(theme);
return { return {
stroke: { width: 0 }, stroke: { width: 0 },
@ -535,340 +358,3 @@ export const getDonutChartConfig = (
}; };
}; };
export const getAreaChartSplineConfig = (
themeColors: ThemeInstance['themes']['value']['colors']
) => {
const areaColors = {
series3: '#e0cffe',
series2: '#b992fe',
series1: '#ab7efd',
};
const { themeSecondaryTextColor, themeBorderColor, themeDisabledTextColor } =
colorVariables(themeColors);
return {
chart: {
parentHeightOffset: 0,
toolbar: { show: false },
},
tooltip: { shared: false },
dataLabels: { enabled: false },
stroke: {
show: false,
curve: 'straight',
},
legend: {
position: 'top',
horizontalAlign: 'left',
labels: { colors: themeSecondaryTextColor },
markers: {
offsetY: 1,
offsetX: -3,
},
itemMargin: {
vertical: 3,
horizontal: 10,
},
},
colors: [areaColors.series3, areaColors.series2, areaColors.series1],
fill: {
opacity: 1,
type: 'solid',
},
grid: {
show: true,
borderColor: themeBorderColor,
xaxis: {
lines: { show: true },
},
},
yaxis: {
labels: {
style: { colors: themeDisabledTextColor },
},
},
xaxis: {
axisBorder: { show: false },
axisTicks: { color: themeBorderColor },
crosshairs: {
stroke: { color: themeBorderColor },
},
labels: {
style: { colors: themeDisabledTextColor },
},
categories: [
'7/12',
'8/12',
'9/12',
'10/12',
'11/12',
'12/12',
'13/12',
'14/12',
'15/12',
'16/12',
'17/12',
'18/12',
'19/12',
],
},
};
};
export const getColumnChartConfig = (
themeColors: ThemeInstance['themes']['value']['colors']
) => {
const columnColors = {
series1: '#826af9',
series2: '#d2b0ff',
bg: '#f8d3ff',
};
const { themeSecondaryTextColor, themeBorderColor, themeDisabledTextColor } =
colorVariables(themeColors);
return {
chart: {
offsetX: -10,
stacked: true,
parentHeightOffset: 0,
toolbar: { show: false },
},
fill: { opacity: 1 },
dataLabels: { enabled: false },
colors: [columnColors.series1, columnColors.series2],
legend: {
position: 'top',
horizontalAlign: 'left',
labels: { colors: themeSecondaryTextColor },
markers: {
offsetY: 1,
offsetX: -3,
},
itemMargin: {
vertical: 3,
horizontal: 10,
},
},
stroke: {
show: true,
colors: ['transparent'],
},
plotOptions: {
bar: {
columnWidth: '15%',
colors: {
backgroundBarRadius: 10,
backgroundBarColors: [
columnColors.bg,
columnColors.bg,
columnColors.bg,
columnColors.bg,
columnColors.bg,
],
},
},
},
grid: {
borderColor: themeBorderColor,
xaxis: {
lines: { show: true },
},
},
yaxis: {
labels: {
style: { colors: themeDisabledTextColor },
},
},
xaxis: {
axisBorder: { show: false },
axisTicks: { color: themeBorderColor },
categories: [
'7/12',
'8/12',
'9/12',
'10/12',
'11/12',
'12/12',
'13/12',
'14/12',
'15/12',
],
crosshairs: {
stroke: { color: themeBorderColor },
},
labels: {
style: { colors: themeDisabledTextColor },
},
},
responsive: [
{
breakpoint: 600,
options: {
plotOptions: {
bar: {
columnWidth: '35%',
},
},
},
},
],
};
};
export const getHeatMapChartConfig = (
themeColors: ThemeInstance['themes']['value']['colors']
) => {
const { themeSecondaryTextColor, themeDisabledTextColor } =
colorVariables(themeColors);
return {
chart: {
parentHeightOffset: 0,
toolbar: { show: false },
},
dataLabels: { enabled: false },
stroke: {
colors: [themeColors.colors.surface],
},
legend: {
position: 'bottom',
labels: {
colors: themeSecondaryTextColor,
},
markers: {
offsetY: 0,
offsetX: -3,
},
itemMargin: {
vertical: 3,
horizontal: 10,
},
},
plotOptions: {
heatmap: {
enableShades: false,
colorScale: {
ranges: [
{ to: 10, from: 0, name: '0-10', color: '#b9b3f8' },
{ to: 20, from: 11, name: '10-20', color: '#aba4f6' },
{ to: 30, from: 21, name: '20-30', color: '#9d95f5' },
{ to: 40, from: 31, name: '30-40', color: '#8f85f3' },
{ to: 50, from: 41, name: '40-50', color: '#8176f2' },
{ to: 60, from: 51, name: '50-60', color: '#7367f0' },
],
},
},
},
grid: {
padding: { top: -20 },
},
yaxis: {
labels: {
style: {
colors: themeDisabledTextColor,
},
},
},
xaxis: {
labels: { show: false },
axisTicks: { show: false },
axisBorder: { show: false },
},
};
};
export const getRadarChartConfig = (
themeColors: ThemeInstance['themes']['value']['colors']
) => {
const radarColors = {
series1: '#9b88fa',
series2: '#ffa1a1',
};
const { themeSecondaryTextColor, themeBorderColor, themeDisabledTextColor } =
colorVariables(themeColors);
return {
chart: {
parentHeightOffset: 0,
toolbar: { show: false },
dropShadow: {
top: 1,
blur: 8,
left: 1,
opacity: 0.2,
enabled: false,
},
},
markers: { size: 0 },
fill: { opacity: [1, 0.8] },
colors: [radarColors.series1, radarColors.series2],
stroke: {
width: 0,
show: false,
},
legend: {
labels: {
colors: themeSecondaryTextColor,
},
markers: {
offsetX: -3,
},
itemMargin: {
vertical: 3,
horizontal: 10,
},
},
plotOptions: {
radar: {
polygons: {
strokeColors: themeBorderColor,
connectorColors: themeBorderColor,
},
},
},
grid: {
show: false,
padding: {
top: -20,
bottom: -20,
},
},
yaxis: { show: false },
xaxis: {
categories: [
'Battery',
'Brand',
'Camera',
'Memory',
'Storage',
'Display',
'OS',
'Price',
],
labels: {
style: {
colors: [
themeDisabledTextColor,
themeDisabledTextColor,
themeDisabledTextColor,
themeDisabledTextColor,
themeDisabledTextColor,
themeDisabledTextColor,
themeDisabledTextColor,
themeDisabledTextColor,
],
},
},
},
};
};

View File

@ -3,10 +3,10 @@ import Notifications from '@core/components/Notifications.vue';
import type { Notification } from '@layouts/types'; import type { Notification } from '@layouts/types';
// Images // Images
import avatar3 from '@/images/avatars/avatar-3.png'; import avatar3 from '@/assets/images/avatars/avatar-3.png';
import avatar4 from '@/images/avatars/avatar-4.png'; import avatar4 from '@/assets/images/avatars/avatar-4.png';
import avatar5 from '@/images/avatars/avatar-5.png'; import avatar5 from '@/assets/images/avatars/avatar-5.png';
import paypal from '@/images/svg/paypal.svg'; import paypal from '@/assets/images/svg/paypal.svg';
const notifications = ref<Notification[]>([ const notifications = ref<Notification[]>([
{ {

View File

@ -114,7 +114,7 @@ const tokenList = computed(() => {
</div> </div>
<div class="bg-base-100"> <div class="bg-base-100">
<DonutChart :series="Object.values(tokenValues)" :labels="Object.keys(tokenValues)"/> <DonutChart :series="Object.values(tokenValues)" :labels="Object.keys(tokenValues)"/>
<table class="table w-100"> <table class="table w-full">
<thead> <thead>
<tr> <tr>
<th>Token</th> <th>Token</th>

View File

@ -1,5 +1,5 @@
<script setup lang="ts"> <script setup lang="ts">
import misc404 from '@/images/pages/404.png'; import misc404 from '@/assets/images/pages/404.png';
</script> </script>
<template> <template>
@ -13,7 +13,7 @@ import misc404 from '@/images/pages/404.png';
</div> </div>
<!-- 👉 Image --> <!-- 👉 Image -->
<div class="misc-avatar w-100 text-center"> <div class="misc-avatar w-full text-center">
<RouterLink to="/" class="btn no-underline btn-primary mt-4"> <RouterLink to="/" class="btn no-underline btn-primary mt-4">
Back to Home Back to Home
</RouterLink> </RouterLink>

View File

@ -2,19 +2,31 @@
@tailwind components; @tailwind components;
@tailwind utilities; @tailwind utilities;
@layer base { body {
min-height: 100vh;
transition: color 0.5s, background-color 0.5s;
line-height: 1.6;
font-family: Inter, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto,
Oxygen, Ubuntu, Cantarell, 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
sans-serif;
font-size: 15px;
text-rendering: optimizeLegibility;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
:root { :root {
--text-main: #333; --text-main: #333;
--text-secondary: #4b525d; --text-secondary: #4b525d;
--bg-active: #fbfbfc; --bg-active: #fbfbfc;
} }
html.dark { html.dark,
html[data-theme='dark'] {
--text-main: #f7f7f7; --text-main: #f7f7f7;
--text-secondary: #6f6e84; --text-secondary: #6f6e84;
--bg-active: #242b40; --bg-active: #242b40;
} }
}
.table th:first-child { .table th:first-child {
position: relative; position: relative;