UNPKG

grapesjs-plugin-chartjs-bar

Version:
279 lines (271 loc) 8.6 kB
/* global Chart */ import grapesjs from "grapesjs"; import addBlocks from "./addBlocks"; import { addComponents } from "./addComponents"; import { addTraits } from "./addTraits"; export default grapesjs.plugins.add("gjs-charts", (editor, opts = {}) => { const script = function (props) { if (props.data && props.data.labels) { const datasets = []; const colors = [ "#0FC083", "#81D065", "#35ECB5", "#4FC3C7", "#A6CACB", "#EAFB86", "#F7BC24", "#EB6C99", "#8166AD", "#18A1AD", "#F1F1F1", "#87D5AE", "#85C1C8", "#4FC3C7", "#A6CACB", "#EAFB86", "#EB6C99", "#F7BC24", "#0FC083", "#8166AD", "#18A1AD", "#81D065", "#35ECB5", "#4FC3C7", "#A6CACB", "#EAFB86", "#F7BC24", "#EB6C99", "#8166AD", ]; props.data?.values?.forEach((dataSet, i) => { datasets.push({ label: dataSet.label, backgroundColor: colors, borderColor: colors, borderRadius: 20, data: dataSet.data, borderWidth: 1, borderSkipped: "start", }); }); const initLib = function () { var data = { labels: props.data.labels, datasets, }; var options = { layout: { padding: { top: 20, }, }, scales: { x: { ticks: { font: { size: 12, color: "#707070", }, padding: 10, callback: function (value, index) { // return index + 1; if (typeof this.getLabelForValue(value) === "number") return this.getLabelForValue(value); const words = this.getLabelForValue(value)?.split(" "); if (words.length > 3) return `${this.getLabelForValue(value)?.substr(0, 16)}...`; return this.getLabelForValue(value); }, }, grid: { borderColor: "#0E4449", borderWidth: 0, z: 0, drawTicks: false, display: true, color: "#ffffff", }, }, y: { grid: { drawTicks: false, drawBorder: false, display: true, color: "#ffffff", }, title: { display: false, }, ticks: { display: false, }, border: false, }, }, tooltips: { enabled: true, mode: "label", }, indexAxis: "x", elements: { bar: { borderWidth: 2, }, }, interaction: { intersect: false, mode: "nearest", }, responsive: true, maintainAspectRatio: false, plugins: { beforeInit: function (chart, options) { chart.legend.afterFit = function () { this.height = this.height + 90; }; }, legend: { position: "bottom", display: false, labels: { // font: 0, // color: 'transparent', boxWidth: 16, boxHeight: 16, usePointStyle: true, pointStyle: true, useBorderRadius: true, borderRadius: 100, generateLabels(chart) { const data = chart.data; if (data.labels.length && data.datasets.length) { const { labels: { pointStyle }, } = chart.legend.options; return data.labels.map((label, i) => { const meta = chart.getDatasetMeta(0); const style = meta.controller.getStyle(i); return { text: `${label}: ${data["datasets"][0].data[i]}`, fillStyle: style.backgroundColor, strokeStyle: style.borderColor, lineWidth: style.borderWidth, pointStyle: pointStyle, hidden: !chart.getDataVisibility(i), // Extra data used for toggling the correct item index: i, }; }); } return []; }, }, onClick(e, legendItem, legend) { legend.chart.toggleDataVisibility(legendItem.index); legend.chart.update(); }, padding: 80, }, datalabels: { display: false, color: "#000000", formatter: (value, ctx) => { let sum = 0; let dataArr = ctx.chart.data.datasets[0].data; dataArr.map((data) => { sum += Number(data); }); let percentage = ((value * 100) / sum).toFixed(1); console.log(percentage); return isNaN(value) ? "0%" : !isNaN(percentage) ? percentage.toString().split(".")[1] == 0 ? percentage.toString().split(".")[0] + "%" : percentage + "%" : "0%"; }, anchor: "end", align: "start", // offset: -20, // clamp: false, }, tooltip: { titleColor: "#fff", footerColor: "#fff", boxWidth: 0, boxHeight: 0, displayColors: false, callbacks: { footer: (data) => { const context = data[0]; const sum = context.dataset.data.reduce( (prev, curr) => prev + Number(curr), 0 ); return `Total: ${sum}`; }, label: (context) => { const sum = context.dataset.data.reduce( (prev, curr) => prev + Number(curr), 0 ); let percentage = ((context.raw * 100) / sum).toFixed(1); return `Amount: ${context.raw} (${ !isNaN(percentage) ? percentage.toString().split(".")[1] == 0 ? percentage.toString().split(".")[0] + "%" : percentage + "%" : "0%" })`; }, labelTextColor: function (context) { return "#fff"; }, }, }, }, categoryPercentage: 1, borderRadius: 15, barPercentage: 0.8, }; const element = document.getElementById(props.data.id); const canvas = element.querySelector(".chartsjs"); element && new Chart(canvas, { type: "bar", data: data, options: options, plugins: [ChartDataLabels], }); }; if (typeof someExtLib == "undefined") { const dataLabels = document.createElement("script"); dataLabels.setAttribute("type", "text/javascript"); dataLabels.src = "https://cdn.jsdelivr.net/npm/chartjs-plugin-datalabels@2.2.0"; dataLabels.onload = () => { const script = document.createElement("script"); script.onload = initLib; script.setAttribute("type", "text/javascript"); script.src = "https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.9.1/chart.min.js"; document.body.appendChild(script); }; document.body.appendChild(dataLabels); } else { initLib(); } } }; const config = { chartType: "gjs-charts-bar", chartScript: script, chartBlockName: "Bar Chart", ...opts, }; addTraits(editor, config); addBlocks(editor, config); addComponents(editor, config); });