|
| 1 | +<script> |
| 2 | + const now = new Date() |
| 3 | + const previousHour = new Date(now - 60 * 60 * 1000) |
| 4 | + const previous24Hours = new Date(now - 24 * 60 * 60 * 1000) |
| 5 | + const previous7Days = new Date(now - 7 * 24 * 60 * 60 * 1000) |
| 6 | + const previous30Days = new Date(now - 30 * 24 * 60 * 60 * 1000) |
| 7 | +
|
| 8 | + const MetricView = {{ |
| 9 | + Js::from([ |
| 10 | + 'last_hour' => \Cachet\Enums\MetricViewEnum::last_hour->value, |
| 11 | + 'today' => \Cachet\Enums\MetricViewEnum::today->value, |
| 12 | + 'week' => \Cachet\Enums\MetricViewEnum::week->value, |
| 13 | + 'month' => \Cachet\Enums\MetricViewEnum::month->value, |
| 14 | + ]) |
| 15 | + }} |
| 16 | +
|
| 17 | + function getCssVar(name) { |
| 18 | + return getComputedStyle(document.documentElement).getPropertyValue(name).trim() |
| 19 | + } |
| 20 | +
|
| 21 | + function getFontColor() { |
| 22 | + if (window.matchMedia('(prefers-color-scheme: dark)').matches === true) { |
| 23 | + return `rgba(${getCssVar('--gray-100')}, 1)` |
| 24 | + } |
| 25 | +
|
| 26 | + return `rgba(${getCssVar('--gray-800')}, 1)` |
| 27 | + } |
| 28 | +
|
| 29 | + function getThemeColors() { |
| 30 | + const fontColor = getFontColor() |
| 31 | + const accent = `rgba(${getCssVar('--accent')}, 1)` |
| 32 | + const accentBackground = `rgba(${getCssVar('--accent-background')}, 0.2)` |
| 33 | +
|
| 34 | + return { |
| 35 | + fontColor: fontColor, |
| 36 | + backgroundColors: [accent, accentBackground], |
| 37 | + borderColor: accent, |
| 38 | + } |
| 39 | + } |
| 40 | +
|
| 41 | + let themeColors = getThemeColors() |
| 42 | +
|
| 43 | + function init() { |
| 44 | + // Parse metric points |
| 45 | + const metricPoints = this.metric.metric_points.map((point) => { |
| 46 | + return { |
| 47 | + x: new Date(point.x), |
| 48 | + y: point.y, |
| 49 | + } |
| 50 | + }) |
| 51 | +
|
| 52 | + // Filter points based on the selected period |
| 53 | + this.points[0] = metricPoints.filter((point) => point.x >= previousHour) |
| 54 | + this.points[1] = metricPoints.filter((point) => point.x >= previous24Hours) |
| 55 | + this.points[2] = metricPoints.filter((point) => point.x >= previous7Days) |
| 56 | + this.points[3] = metricPoints.filter((point) => point.x >= previous30Days) |
| 57 | +
|
| 58 | + // Initialize chart |
| 59 | + const chart = new Chart(this.$refs.canvas, { |
| 60 | + type: 'line', |
| 61 | + data: { |
| 62 | + datasets: [ |
| 63 | + { |
| 64 | + label: this.metric.suffix, |
| 65 | + data: this.points[this.period], |
| 66 | + fill: false, |
| 67 | + backgroundColor: themeColors.backgroundColors, |
| 68 | + borderColor: themeColors.borderColor, |
| 69 | + tension: 0.1, |
| 70 | + }, |
| 71 | + ], |
| 72 | + }, |
| 73 | + options: { |
| 74 | + scales: { |
| 75 | + x: { |
| 76 | + ticks: { |
| 77 | + color: themeColors.fontColor, |
| 78 | + }, |
| 79 | + type: 'timeseries', |
| 80 | + }, |
| 81 | + y: { |
| 82 | + ticks: { |
| 83 | + color: themeColors.fontColor, |
| 84 | + }, |
| 85 | + }, |
| 86 | + }, |
| 87 | + }, |
| 88 | + }) |
| 89 | +
|
| 90 | + this.$watch('period', () => { |
| 91 | + chart.data.datasets[0].data = this.points[this.period] |
| 92 | + chart.options.scales.x.time.unit = getTimeUnit(this.period) |
| 93 | +
|
| 94 | + chart.update() |
| 95 | + }) |
| 96 | +
|
| 97 | + function getTimeUnit(period) { |
| 98 | + if (period == MetricView.last_hour) return 'minute' |
| 99 | + if (period == MetricView.today) return 'hour' |
| 100 | + if (period == MetricView.week) return 'week' |
| 101 | + if (period == MetricView.month) return 'month' |
| 102 | + return 'day' |
| 103 | + } |
| 104 | +
|
| 105 | + window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', () => { |
| 106 | + themeColors = getThemeColors() |
| 107 | +
|
| 108 | + chart.data.datasets[0].backgroundColor = themeColors.backgroundColors |
| 109 | + chart.data.datasets[0].borderColor = themeColors.borderColor |
| 110 | + chart.options.plugins.legend.labels.color = themeColors.fontColor |
| 111 | + chart.options.plugins.tooltip.bodyColor = themeColors.fontColor |
| 112 | + chart.options.plugins.tooltip.titleColor = themeColors.fontColor |
| 113 | + chart.options.scales.x.ticks.color = themeColors.fontColor |
| 114 | + chart.options.scales.y.ticks.color = themeColors.fontColor |
| 115 | +
|
| 116 | + chart.update() |
| 117 | + }) |
| 118 | + } |
| 119 | +</script> |
| 120 | + |
| 121 | +<div class="flex flex-col gap-8"> |
| 122 | + @foreach ($metrics as $metric) |
| 123 | + <x-cachet::metric :metric="$metric" /> |
| 124 | + @endforeach |
| 125 | +</div> |
0 commit comments