Skip to content

Commit

Permalink
refactor: chart component updates (#597)
Browse files Browse the repository at this point in the history
  • Loading branch information
alexbarnsley authored Oct 2, 2023
1 parent 1ab1867 commit 8d05795
Show file tree
Hide file tree
Showing 3 changed files with 110 additions and 35 deletions.
15 changes: 11 additions & 4 deletions resources/assets/js/chart-theme.js
Original file line number Diff line number Diff line change
Expand Up @@ -213,21 +213,28 @@ export function getAxisThemeConfig(mode) {
const config = {
light: {
x: {
color: "rgba(238,243,245,1)", // theme-secondary-200
color: "rgba(219, 222, 229, 1)", // theme-secondary-300
},
y: {
color: "rgba(238,243,245,1)", // theme-secondary-200
color: "rgba(219, 222, 229, 1)", // theme-secondary-300
},
},
dark: {
x: {
color: "rgba(60,66,73,1)", // theme-secondary-800
color: "rgba(61, 68, 77, 1)", // theme-dark-700
},
y: {
color: "rgba(60,66,73,1)", // theme-secondary-800
color: "rgba(61, 68, 77, 1)", // theme-dark-700
},
},
};

return config[mode];
}

export function getCrosshairColor(mode) {
return {
light: "rgba(99, 114, 130, 1)", // theme-secondary-700,
dark: "rgba(164, 177, 188, 1)", // theme-dark-200,
}[mode];
}
119 changes: 89 additions & 30 deletions resources/assets/js/chart.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@ import {
makeGradient,
getFontConfig,
getAxisThemeConfig,
getCrosshairColor,
} from "./chart-theme";

import { Chart, registerables } from "chart.js";
import { Chart, registerables, LineController } from "chart.js";

Chart.register(...registerables);

Expand All @@ -18,6 +19,9 @@ Chart.register(...registerables);
* @param {Array<Object{name, mode}>} theme
* @param {Number} time
* @param {String} currency
* @param {Number} yPadding
* @param {Number} xPadding
* @param {Boolean} showCrosshair
* @return {Object}
*/
const CustomChart = (
Expand All @@ -28,8 +32,64 @@ const CustomChart = (
tooltips,
theme,
time,
currency
currency,
yPadding = 15,
xPadding = 10,
showCrosshair = false
) => {
const themeMode = () => {
if (theme.mode === "auto") {
return ["light", "dark"].includes(localStorage.theme)
? localStorage.theme
: "light";
}

return theme.mode;
};

class LineWithCrosshair extends LineController {
draw() {
super.draw(arguments);

// Based on https://stackoverflow.com/a/70245628/3637093
if (
this.chart.tooltip._active &&
this.chart.tooltip._active.length
) {
const activePoint = this.chart.tooltip._active[0].element;
const ctx = this.chart.ctx;
const x = activePoint.x;
const y = activePoint.y;
const topY = this.chart.legend.bottom;
const bottomY = this.chart.chartArea.bottom;
const left = this.chart.chartArea.left;
const right = this.chart.chartArea.right;

ctx.save();
ctx.lineWidth = 1;
ctx.setLineDash([3, 3]);
ctx.strokeStyle = getCrosshairColor(themeMode());

ctx.beginPath();
ctx.moveTo(x, topY);
ctx.lineTo(x, bottomY);
ctx.stroke();

ctx.beginPath();
ctx.moveTo(left, y);
ctx.lineTo(right, y);
ctx.stroke();

ctx.restore();
}
}
}

LineWithCrosshair.id = "lineWithCrosshair";
LineWithCrosshair.defaults = LineController.defaults;

Chart.register(LineWithCrosshair);

return {
time: time,
chart: null,
Expand Down Expand Up @@ -71,16 +131,6 @@ const CustomChart = (
this.chart.update();
},

themeMode() {
if (theme.mode === "auto") {
return ["light", "dark"].includes(localStorage.theme)
? localStorage.theme
: "light";
}

return theme.mode;
},

loadData() {
const datasets = [];

Expand All @@ -95,7 +145,7 @@ const CustomChart = (

values.forEach((value, key) => {
let themeName = value.type === "bar" ? "grey" : theme.name;
let graphic = getInfoFromThemeName(themeName, this.themeMode());
let graphic = getInfoFromThemeName(themeName, themeMode());
let backgroundColor = graphic.backgroundColor;
if (backgroundColor.hasOwnProperty("gradient")) {
backgroundColor = makeGradient(
Expand All @@ -104,12 +154,17 @@ const CustomChart = (
);
}

let chartType = value.type || "line";
if (showCrosshair && chartType === "line") {
chartType = "lineWithCrosshair";
}

datasets.push({
fill: true,
stack: "combined",
label: value.name || "",
data: value.data || value,
type: value.type || "line",
type: chartType,
backgroundColor:
value.type === "bar"
? graphic.borderColor
Expand Down Expand Up @@ -149,17 +204,19 @@ const CustomChart = (
display: grid && key === 0,
type: "linear",
ticks: {
...getFontConfig("axis", this.themeMode()),
padding: 15,
...getFontConfig("axis", themeMode()),
padding: yPadding,
display: grid && key === 0,
suggestedMax: range.max,
callback: (value, index, data) =>
this.getCurrencyValue(value),
},
grid: {
drawTicks: false,
display: grid && key === 0,
drawBorder: false,
color: getAxisThemeConfig(this.themeMode()).y.color,
borderDash: [3, 3],
color: getAxisThemeConfig(themeMode()).y.color,
},
});
});
Expand All @@ -175,9 +232,14 @@ const CustomChart = (
}

this.$watch("time", () => this.updateChart());
window.addEventListener("resize", () =>
window.livewire.emit("updateChart")
);

window.addEventListener("resize", () => {
try {
this.chart.resize();
} catch (e) {
// Hide resize errors - they don't seem to cause any issues
}
});

const data = {
labels: labels,
Expand Down Expand Up @@ -206,13 +268,10 @@ const CustomChart = (
label: (context) =>
this.getCurrencyValue(context.raw),
labelTextColor: (context) =>
getFontConfig("tooltip", this.themeMode())
.fontColor,
getFontConfig("tooltip", themeMode()).fontColor,
},
backgroundColor: getFontConfig(
"tooltip",
this.themeMode()
).backgroundColor,
backgroundColor: getFontConfig("tooltip", themeMode())
.backgroundColor,
},
},
hover: {
Expand All @@ -232,13 +291,13 @@ const CustomChart = (
ticks: {
display: grid,
includeBounds: true,
padding: 10,
...getFontConfig("axis", this.themeMode()),
padding: xPadding,
...getFontConfig("axis", themeMode()),
},
grid: {
display: grid,
display: false,
drawBorder: false,
color: getAxisThemeConfig(this.themeMode()).x.color,
color: getAxisThemeConfig(themeMode()).x.color,
},
},
},
Expand Down
11 changes: 10 additions & 1 deletion resources/views/chart.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@
'grid' => false,
'tooltips' => false,
'theme' => collect(['name' => 'grey', 'mode' => 'light']),
'yPadding' => 15,
'xPadding' => 10,
'showCrosshair' => false,
])

<div
Expand All @@ -21,11 +24,17 @@
{{ json_encode($theme->toArray()) }},
'{{ time() }}',
'{{ $currency }}',
{{ $yPadding }},
{{ $xPadding }},
{{ $showCrosshair ? 'true' : 'false' }}
)"
wire:key="{{ $id.time() }}"
{{ $attributes->only('class') }}
>
<div wire:ignore class="relative w-full h-full">
<div
class="relative w-full h-full"
wire:ignore
>
<canvas
x-ref="{{ $id }}"
@if($canvasClass) class="{{ $canvasClass }}" @endif
Expand Down

0 comments on commit 8d05795

Please sign in to comment.