375 lines
10 KiB
JavaScript
375 lines
10 KiB
JavaScript
import React, { useRef, useState } from "react";
|
|
import Chart from "chart.js/auto";
|
|
|
|
import Card, { CardHeader } from "./Card";
|
|
import { createPopper } from "@popperjs/core";
|
|
|
|
export function ChartTooltip({ tooltipData, ...props }) {
|
|
return (
|
|
<>
|
|
<p className="font-bold">{tooltipData.title}</p>
|
|
{tooltipData.body.map((item, index) => (
|
|
<div key={item.lines} className="flex items-center justify-center">
|
|
<span className="w-3 h-3 rounded-full" style={{ backgroundColor: tooltipData.labelColors[index].borderColor }} />
|
|
<p className="px-2 text-sm">{item.before + item.lines + item.after}</p>
|
|
</div>
|
|
))
|
|
}
|
|
</>
|
|
)
|
|
}
|
|
|
|
const setOpacity = (hex, alpha) => `${hex}${Math.floor(alpha * 255).toString(16).padStart(2, 0)}`;
|
|
|
|
function generateGetBoundingClientRect(x = 0, y = 0) { return () => ({ width: 0, height: 0, top: y, right: x, bottom: y, left: x }); }
|
|
|
|
function GetPlacement(tooltipModel) {
|
|
switch (tooltipModel.xAlign) {
|
|
case "right":
|
|
return "left";
|
|
case "left":
|
|
return "right";
|
|
}
|
|
switch (tooltipModel.yAlign) {
|
|
case "top":
|
|
return "bottom";
|
|
case "bottom":
|
|
return "top";
|
|
}
|
|
}
|
|
|
|
export default function NejChart(props) {
|
|
let [tooltipData, setTooltipData] = useState(null)
|
|
let canvasRef = useRef(null);
|
|
let popperElement = useRef(null);
|
|
|
|
let tooltipPositionEl = {
|
|
getBoundingClientRect: generateGetBoundingClientRect(100, 100),
|
|
contextElement: canvasRef.current
|
|
};
|
|
|
|
React.useEffect(() => {
|
|
var ctx = canvasRef.current.getContext("2d");
|
|
|
|
let popper = createPopper(tooltipPositionEl, popperElement.current, { placement: "bottom" });
|
|
|
|
let accentCol = getComputedStyle(document.body).getPropertyValue("--accent-dark");
|
|
let accent2Col = getComputedStyle(document.body).getPropertyValue("--accent2");
|
|
let accent3Col = getComputedStyle(document.body).getPropertyValue("--accent3");
|
|
let accent4Col = getComputedStyle(document.body).getPropertyValue("--accent4");
|
|
let accent5Col = getComputedStyle(document.body).getPropertyValue("--accent5");
|
|
let accent6Col = "rgb(180,0,0)"//getComputedStyle(document.body).getPropertyValue("--accent6");
|
|
|
|
let bgTrianry = getComputedStyle(document.body).getPropertyValue("--trinary");
|
|
let primary = getComputedStyle(document.body).getPropertyValue("--primary-text");
|
|
let secondary = getComputedStyle(document.body).getPropertyValue("--secondary-text");
|
|
|
|
console.log(Chart.defaults);
|
|
Chart.defaults.global = {
|
|
...Chart.defaults.global,
|
|
maintainAspectRatio: false,
|
|
responsive: true,
|
|
defaultColor: [accentCol, accent2Col, accent3Col, accent4Col, accent5Col, accent6Col],
|
|
legend: {
|
|
...Chart.defaults.global?.legend,
|
|
labels: {
|
|
...Chart.defaults.global?.legend?.labels,
|
|
fontColor: secondary,
|
|
usePointStyle: true
|
|
},
|
|
},
|
|
tooltips: {
|
|
...Chart.defaults.global?.tooltips,
|
|
backgroundColor: bgTrianry,
|
|
enabled: false,
|
|
custom: (tooltipModel) => {
|
|
// if chart is not defined, return early
|
|
if (!canvasRef.current) {
|
|
return;
|
|
}
|
|
// hide the tooltip when chartjs determines you've hovered out
|
|
if (tooltipModel.opacity === 0) {
|
|
setTooltipData(null);
|
|
return;
|
|
}
|
|
|
|
let position = canvasRef.current.getBoundingClientRect();
|
|
let left = position.left + tooltipModel.caretX;
|
|
let top = position.top + tooltipModel.caretY;
|
|
|
|
tooltipPositionEl.getBoundingClientRect = generateGetBoundingClientRect(left, top);
|
|
popper.setOptions({ placement: GetPlacement(tooltipModel) });
|
|
|
|
setTooltipData(tooltipModel);
|
|
},
|
|
},
|
|
}
|
|
Chart.defaults.scale = {
|
|
...Chart.defaults.scale,
|
|
ticks: {
|
|
...Chart.defaults.scale.ticks,
|
|
fontColor: secondary,
|
|
},
|
|
gridLines: {
|
|
...Chart.defaults.scale.gridLines,
|
|
drawBorder: false,
|
|
color: setOpacity(primary, 0.1),
|
|
zeroLineColor: "rgba(0, 0, 0, 0)",
|
|
/*
|
|
zeroLineBorderDash: [2],
|
|
zeroLineBorderDashOffset: [2],
|
|
*/
|
|
},
|
|
}
|
|
|
|
console.log(Chart.defaults);
|
|
console.log(props.config);
|
|
let chart = new Chart(ctx, props.config);
|
|
return () => {
|
|
chart.destroy();
|
|
}
|
|
}, []);
|
|
return (
|
|
<>
|
|
<canvas ref={canvasRef} />
|
|
<div ref={popperElement} className={(tooltipData ? "block " : "hidden ") + " pointer-events-none text-primary bg-trinary rounded-xl px-2 py-1"}>
|
|
{tooltipData ? <ChartTooltip tooltipData={tooltipData} /> : null}
|
|
</div>
|
|
</>
|
|
);
|
|
}
|
|
|
|
export function ExLineChart() {
|
|
|
|
let accentCol = getComputedStyle(document.body).getPropertyValue("--accent");
|
|
let bgTrianry = getComputedStyle(document.body).getPropertyValue("--trinary");
|
|
let primary = getComputedStyle(document.body).getPropertyValue("--primary-text");
|
|
let secondary = getComputedStyle(document.body).getPropertyValue("--secondary-text");
|
|
|
|
var config = {
|
|
type: "line",
|
|
data: {
|
|
labels: [
|
|
"January",
|
|
"February",
|
|
"March",
|
|
"April",
|
|
"May",
|
|
"June",
|
|
"July",
|
|
],
|
|
datasets: [
|
|
{
|
|
label: new Date().getFullYear(),
|
|
backgroundColor: accentCol,
|
|
borderColor: accentCol,
|
|
data: [65, 78, 66, 44, 56, 67, 75],
|
|
fill: true,
|
|
hoverBackgroundColor: accentCol,
|
|
hoverBorderColor: accentCol,
|
|
backgroundColor: setOpacity(accentCol, 0.1),
|
|
},
|
|
{
|
|
label: new Date().getFullYear() - 1,
|
|
backgroundColor: primary,
|
|
borderColor: primary,
|
|
data: [40, 68, 86, 74, 56, 60, 87],
|
|
fill: true,
|
|
hoverBackgroundColor: primary,
|
|
hoverBorderColor: primary,
|
|
backgroundColor: setOpacity(primary, 0.1),
|
|
},
|
|
],
|
|
},
|
|
options: {
|
|
legend: {
|
|
display: false,
|
|
},
|
|
tooltips: {
|
|
mode: "index",
|
|
intersect: false,
|
|
},
|
|
scales: {
|
|
xAxes: [
|
|
{
|
|
display: true,
|
|
scaleLabel: {
|
|
display: false,
|
|
},
|
|
gridLines: {
|
|
display: false,
|
|
},
|
|
},
|
|
],
|
|
yAxes: [
|
|
{
|
|
ticks: {
|
|
stepSize: 25
|
|
},
|
|
display: true,
|
|
scaleLabel: {
|
|
display: false,
|
|
},
|
|
gridLines: {
|
|
zeroLineBorderDash: [2],
|
|
zeroLineBorderDashOffset: [2],
|
|
},
|
|
},
|
|
],
|
|
},
|
|
}
|
|
};
|
|
return (
|
|
<Card>
|
|
<CardHeader desc="Sales"></CardHeader>
|
|
<div className="p-4 flex-auto">
|
|
<NejChart config={config} />
|
|
</div>
|
|
</Card >
|
|
)
|
|
}
|
|
|
|
|
|
export function ExBarChart() {
|
|
|
|
let accentCol = getComputedStyle(document.body).getPropertyValue("--accent");
|
|
let bgTrianry = getComputedStyle(document.body).getPropertyValue("--trinary");
|
|
let primary = getComputedStyle(document.body).getPropertyValue("--primary-text");
|
|
let secondary = getComputedStyle(document.body).getPropertyValue("--secondary-text");
|
|
|
|
var config = {
|
|
type: "bar",
|
|
data: {
|
|
labels: [
|
|
"January",
|
|
"February",
|
|
"March",
|
|
"April",
|
|
"May",
|
|
"June",
|
|
"July",
|
|
],
|
|
datasets: [
|
|
{
|
|
label: new Date().getFullYear(),
|
|
backgroundColor: accentCol,
|
|
borderColor: accentCol,
|
|
data: [65, 78, 66, 44, 56, 67, 75],
|
|
fill: false,
|
|
hoverBackgroundColor: accentCol,
|
|
hoverBorderColor: accentCol,
|
|
},
|
|
{
|
|
label: new Date().getFullYear() - 1,
|
|
backgroundColor: primary,
|
|
borderColor: primary,
|
|
data: [40, 68, 86, 74, 56, 60, 87],
|
|
fill: false,
|
|
hoverBackgroundColor: primary,
|
|
hoverBorderColor: primary,
|
|
},
|
|
],
|
|
},
|
|
options: {
|
|
legend: {
|
|
display: false,
|
|
},
|
|
scales: {
|
|
xAxes: [
|
|
{
|
|
display: true,
|
|
scaleLabel: {
|
|
display: false,
|
|
},
|
|
gridLines: {
|
|
display: false,
|
|
},
|
|
},
|
|
],
|
|
yAxes: [
|
|
{
|
|
ticks: {
|
|
stepSize: 25
|
|
},
|
|
display: true,
|
|
scaleLabel: {
|
|
display: false,
|
|
},
|
|
gridLines: {
|
|
zeroLineBorderDash: [2],
|
|
zeroLineBorderDashOffset: [2],
|
|
},
|
|
},
|
|
],
|
|
},
|
|
}
|
|
};
|
|
return (
|
|
<Card>
|
|
<CardHeader desc="Sales"></CardHeader>
|
|
<div className="p-4 flex-auto">
|
|
{/* Chart */}
|
|
<div className="relative h-350-px">
|
|
<NejChart config={config} />
|
|
</div>
|
|
</div>
|
|
</Card >
|
|
)
|
|
}
|
|
|
|
|
|
export function ExPieChart() {
|
|
|
|
let accentCol = getComputedStyle(document.body).getPropertyValue("--accent-dark");
|
|
let accent2Col = getComputedStyle(document.body).getPropertyValue("--accent2");
|
|
let accent3Col = getComputedStyle(document.body).getPropertyValue("--accent3");
|
|
let accent4Col = getComputedStyle(document.body).getPropertyValue("--accent4");
|
|
let accent5Col = getComputedStyle(document.body).getPropertyValue("--accent5");
|
|
let accent6Col = "rgb(180,0,0)"//getComputedStyle(document.body).getPropertyValue("--accent6");
|
|
|
|
var config = {
|
|
type: "pie",
|
|
data: {
|
|
labels: [
|
|
"Nejcraft",
|
|
"Honzapat",
|
|
"Kubacip",
|
|
"Viktorf1",
|
|
"Regi",
|
|
"Euler",
|
|
],
|
|
datasets: [
|
|
{
|
|
label: new Date().getFullYear(),
|
|
data: [50, 10, 10, 10, 10, 10],
|
|
fill: true,
|
|
borderColor: [accentCol, accent2Col, accent3Col, accent4Col, accent5Col, accent6Col],
|
|
hoverBorderColor: [accentCol, accent2Col, accent3Col, accent4Col, accent5Col, accent6Col],
|
|
hoverBackgroundColor: [accentCol, accent2Col, accent3Col, accent4Col, accent5Col, accent6Col],
|
|
backgroundColor: [accentCol, accent2Col, accent3Col, accent4Col, accent5Col, accent6Col],
|
|
},
|
|
],
|
|
},
|
|
options: {
|
|
legend: {
|
|
labels: {
|
|
usePointStyle: true
|
|
},
|
|
onClick: null,
|
|
align: "end",
|
|
position: "bottom",
|
|
},
|
|
}
|
|
}
|
|
return (
|
|
<Card>
|
|
<CardHeader desc="Sales"></CardHeader>
|
|
<div className="p-4 flex-auto">
|
|
{/* Chart */}
|
|
<div className="relative h-350-px">
|
|
<NejChart config={config} />
|
|
</div>
|
|
</div>
|
|
</Card >
|
|
)
|
|
} |