From 24725e3df144d10ae3e8d3ef43f78e76feb00f3c Mon Sep 17 00:00:00 2001 From: SyaharaniSalsabilla Date: Fri, 16 Oct 2026 10:29:42 +0700 Subject: [PATCH] update chart dashboard --- public/assets/js/config.js | 23 ++++++ .../dashboard/indikator-pertanian.blade.php | 8 +- .../dashboard/karakteristik-petani.blade.php | 80 +++++++------------ .../views/dashboard/produktivitas.blade.php | 14 ++-- 4 files changed, 68 insertions(+), 57 deletions(-) diff --git a/public/assets/js/config.js b/public/assets/js/config.js index 128fc68..a968156 100644 --- a/public/assets/js/config.js +++ b/public/assets/js/config.js @@ -81,6 +81,29 @@ window.config = { enableMenuLocalStorage: true // Enable menu state with local storage support }; +// Choose the label color with the higher contrast against each chart slice. +window.config.chartTextColor = function (color) { + let hex = String(color || '').trim().replace(/^#/, ''); + if (/^[0-9a-f]{3}$/i.test(hex)) { + hex = hex.split('').map(value => value + value).join(''); + } + if (!/^[0-9a-f]{6}$/i.test(hex)) return '#212529'; + + const luminance = function (value) { + const channels = value.match(/../g).map(channel => { + const srgb = parseInt(channel, 16) / 255; + return srgb <= 0.04045 ? srgb / 12.92 : Math.pow((srgb + 0.055) / 1.055, 2.4); + }); + return channels[0] * 0.2126 + channels[1] * 0.7152 + channels[2] * 0.0722; + }; + const background = luminance(hex); + const dark = luminance('212529'); + const darkContrast = (Math.max(background, dark) + 0.05) / (Math.min(background, dark) + 0.05); + const lightContrast = 1.05 / (background + 0.05); + + return darkContrast >= lightContrast ? '#212529' : '#ffffff'; +}; + window.assetsPath = document.documentElement.getAttribute('data-assets-path'); window.templateName = document.documentElement.getAttribute('data-template'); diff --git a/resources/views/dashboard/indikator-pertanian.blade.php b/resources/views/dashboard/indikator-pertanian.blade.php index b4b9b78..e440541 100644 --- a/resources/views/dashboard/indikator-pertanian.blade.php +++ b/resources/views/dashboard/indikator-pertanian.blade.php @@ -2011,7 +2011,11 @@ series: data.series, colors: colors, stroke: { width: 0 }, - dataLabels: { enabled: false }, + dataLabels: { + enabled: false, + style: { colors: colors.map(config.chartTextColor) }, + dropShadow: { enabled: false }, + }, legend: { show: true, position: 'bottom', @@ -2051,7 +2055,7 @@
+
${label}: ${value} petani (${percentage}%)
`; @@ -2433,6 +2418,12 @@ document.addEventListener('DOMContentLoaded', function () { const landOwnershipStatusSeries = (@json($data['status_kepemilikan_lahan']['series'] ?? [])).map(Number); const totalLandOwnershipStatusFarmers = landOwnershipStatusSeries.reduce((total, value) => total + value, 0); + const landOwnershipStatusColors = [ + pastelSemantic.success || '#6FD68F', + pastelSemantic.warning || '#FFB46F', + pastelSemantic.info || '#5FC7D6', + pastelSemantic.secondary || '#9EA6B0' + ]; const landOwnershipStatusChartConfig = { chart: { height: 365, @@ -2452,12 +2443,7 @@ document.addEventListener('DOMContentLoaded', function () { }, labels: landOwnershipStatusLabels, series: landOwnershipStatusSeries, - colors: [ - pastelSemantic.success || '#6FD68F', - pastelSemantic.warning || '#FFB46F', - pastelSemantic.info || '#5FC7D6', - pastelSemantic.secondary || '#9EA6B0' - ], + colors: landOwnershipStatusColors, stroke: { width: 0 }, dataLabels: { enabled: true, @@ -2473,15 +2459,9 @@ document.addEventListener('DOMContentLoaded', function () { fontSize: '13px', fontFamily: fontFamily, fontWeight: 600, - colors: ['#fff'] + colors: landOwnershipStatusColors.map(config.chartTextColor) }, - dropShadow: { - enabled: true, - top: 1, - left: 1, - blur: 2, - opacity: 0.45 - } + dropShadow: { enabled: false } }, legend: { show: true, @@ -2918,6 +2898,8 @@ document.addEventListener('DOMContentLoaded', function () { }, dataLabels: { enabled: false, + style: { colors: segmentPalette.map(config.chartTextColor) }, + dropShadow: { enabled: false }, }, legend: { show: false, diff --git a/resources/views/dashboard/produktivitas.blade.php b/resources/views/dashboard/produktivitas.blade.php index 9d1266b..e33ee01 100644 --- a/resources/views/dashboard/produktivitas.blade.php +++ b/resources/views/dashboard/produktivitas.blade.php @@ -1251,13 +1251,13 @@ document.addEventListener('DOMContentLoaded', function () { }, 0); } - function produksiChartTooltip(color, label, value, unit = '', total = null, digits = 0) { + function produksiChartTooltip(color, label, value, unit = '', total = null, digits = 0, textColor = headingColor) { const numericValue = Number(value || 0); const unitText = unit ? ` ${escapeHtml(unit)}` : ''; const percentageText = total === null ? '' : ` (${chartPercentage(numericValue, total)}%)`; return ` -
+
${escapeHtml(label)}: ${formatNumber(numericValue, digits)}${unitText}${percentageText}
`; @@ -1636,6 +1636,7 @@ document.addEventListener('DOMContentLoaded', function () { stroke: { width: 0 }, dataLabels: { enabled: true, + dropShadow: { enabled: false }, formatter: function (value) { return value.toFixed(0) + '%'; }, @@ -1643,7 +1644,7 @@ document.addEventListener('DOMContentLoaded', function () { fontSize: '13px', fontFamily: fontFamily, fontWeight: 600, - colors: ['#fff'], + colors: chartColors.map(config.chartTextColor), }, }, legend: { @@ -1665,7 +1666,7 @@ document.addEventListener('DOMContentLoaded', function () { const label = w.globals.labels[seriesIndex] || 'Data'; const color = w.globals.colors?.[seriesIndex] || chartColors[seriesIndex % chartColors.length] || '#9D8EF0'; - return produksiChartTooltip(color, label, value, options.unit || 'data', total); + return produksiChartTooltip(color, label, value, options.unit || 'data', total, 0, config.chartTextColor(color)); }, }, plotOptions: { @@ -1742,6 +1743,7 @@ document.addEventListener('DOMContentLoaded', function () { legend: { show: false }, dataLabels: { enabled: true, + dropShadow: { enabled: false }, formatter: function (value) { return value >= 8 ? value.toFixed(0) + '%' : ''; }, @@ -1749,7 +1751,7 @@ document.addEventListener('DOMContentLoaded', function () { fontSize: '11px', fontFamily: fontFamily, fontWeight: 600, - colors: ['#fff'], + colors: colors.map(config.chartTextColor), }, }, tooltip: { @@ -1758,7 +1760,7 @@ document.addEventListener('DOMContentLoaded', function () { const label = w.globals.labels[seriesIndex] || 'Data'; const color = w.globals.colors?.[seriesIndex] || colors[seriesIndex % colors.length] || '#9D8EF0'; - return produksiChartTooltip(color, label, value, options.unit || 'data', total); + return produksiChartTooltip(color, label, value, options.unit || 'data', total, 0, config.chartTextColor(color)); }, }, plotOptions: { pie: { expandOnClick: true } },