dashboard produksi & ganti warna chart

This commit is contained in:
2026-10-13 15:55:18 +07:00
parent aef27704f2
commit 80f0056efe
19 changed files with 994 additions and 334 deletions
@@ -6,7 +6,7 @@
.chart-group-header-toggle {
cursor: pointer;
background-color: rgba(var(--bs-primary-rgb, 115, 103, 240), 0.08);
border-inline-start: 4px solid var(--bs-primary, #7367f0);
border-inline-start: 4px solid var(--bs-primary, #9D8EF0);
box-shadow: none;
transition: background-color 0.2s ease;
}
@@ -649,18 +649,18 @@
<div class="col-12">
<div class="card chart-group-header-toggle" role="button" tabindex="0"
data-bs-toggle="collapse" data-bs-target="#demografi-charts"
aria-expanded="true" aria-controls="demografi-charts" aria-label="Sembunyikan chart">
aria-expanded="false" aria-controls="demografi-charts" aria-label="Tampilkan chart">
<div class="card-body d-flex justify-content-between align-items-center gap-3">
<div>
<h5>Profil Demografi</h5>
<p class="text-body-secondary mb-0">Komposisi petani berdasarkan gender, kelompok umur, dan pendidikan.</p>
</div>
<span class="btn btn-icon btn-label-secondary btn-sm chart-group-icon-toggle" aria-hidden="true">
<i class="icon-base ti tabler-chevron-up"></i>
<i class="icon-base ti tabler-chevron-down"></i>
</span>
</div>
</div>
<div class="collapse show chart-group-panel" id="demografi-charts">
<div class="collapse chart-group-panel" id="demografi-charts">
<div class="row g-6 pt-4">
<div class="col-12 col-md-6 col-xl-4">
<div class="card h-100">
@@ -729,18 +729,18 @@
<div class="col-12">
<div class="card chart-group-header-toggle" role="button" tabindex="0"
data-bs-toggle="collapse" data-bs-target="#rumah-tangga-charts"
aria-expanded="true" aria-controls="rumah-tangga-charts" aria-label="Sembunyikan chart">
aria-expanded="false" aria-controls="rumah-tangga-charts" aria-label="Tampilkan chart">
<div class="card-body d-flex justify-content-between align-items-center gap-3">
<div>
<h5>Sosial Ekonomi</h5>
<p class="text-body-secondary mb-0">Tanggungan keluarga, penghasilan usaha tani, dan keanggotaan kelompok tani.</p>
</div>
<span class="btn btn-icon btn-label-secondary btn-sm chart-group-icon-toggle" aria-hidden="true">
<i class="icon-base ti tabler-chevron-up"></i>
<i class="icon-base ti tabler-chevron-down"></i>
</span>
</div>
</div>
<div class="collapse show chart-group-panel" id="rumah-tangga-charts">
<div class="collapse chart-group-panel" id="rumah-tangga-charts">
<div class="row g-6 pt-4">
<div class="col-12 col-md-6 col-xl-4">
<div class="card h-100">
@@ -816,18 +816,18 @@
<div class="col-12">
<div class="card chart-group-header-toggle" role="button" tabindex="0"
data-bs-toggle="collapse" data-bs-target="#usaha-tani-charts"
aria-expanded="true" aria-controls="usaha-tani-charts" aria-label="Sembunyikan chart">
aria-expanded="false" aria-controls="usaha-tani-charts" aria-label="Tampilkan chart">
<div class="card-body d-flex justify-content-between align-items-center gap-3">
<div>
<h5>Profil Lahan</h5>
<p class="text-body-secondary mb-0">Karakteristik lahan usaha tani berdasarkan komoditas utama, luas lahan garapan, dan status kepemilikan lahan.</p>
</div>
<span class="btn btn-icon btn-label-secondary btn-sm chart-group-icon-toggle" aria-hidden="true">
<i class="icon-base ti tabler-chevron-up"></i>
<i class="icon-base ti tabler-chevron-down"></i>
</span>
</div>
</div>
<div class="collapse show chart-group-panel" id="usaha-tani-charts">
<div class="collapse chart-group-panel" id="usaha-tani-charts">
<div class="row g-6 pt-4">
<div class="col-12 col-md-6 col-xl-4">
<div class="card h-100">
@@ -1096,18 +1096,18 @@
<div class="py-4">
<div class="card chart-group-header-toggle" role="button" tabindex="0"
data-bs-toggle="collapse" data-bs-target="#indeks-segmentasi-charts"
aria-expanded="true" aria-controls="indeks-segmentasi-charts" aria-label="Sembunyikan chart">
aria-expanded="false" aria-controls="indeks-segmentasi-charts" aria-label="Tampilkan chart">
<div class="card-body d-flex justify-content-between align-items-center gap-3">
<div>
<h5>Indeks Petani</h5>
<p class="text-body-secondary mb-0">Komposisi petani menurut tingkat kesiapan adopsi, secara keseluruhan dan pada setiap komoditas.</p>
</div>
<span class="btn btn-icon btn-label-secondary btn-sm chart-group-icon-toggle" aria-hidden="true">
<i class="icon-base ti tabler-chevron-up"></i>
<i class="icon-base ti tabler-chevron-down"></i>
</span>
</div>
</div>
<div class="collapse show chart-group-panel" id="indeks-segmentasi-charts">
<div class="collapse chart-group-panel" id="indeks-segmentasi-charts">
<div class="row g-6 py-4">
<div class="col-lg-6 col-sm-12">
<div class="card card-border-shadow-primary h-100">
@@ -1169,18 +1169,18 @@
<div class="py-4">
<div class="card chart-group-header-toggle" role="button" tabindex="0"
data-bs-toggle="collapse" data-bs-target="#indeks-kesiapan-charts"
aria-expanded="true" aria-controls="indeks-kesiapan-charts" aria-label="Sembunyikan chart">
aria-expanded="false" aria-controls="indeks-kesiapan-charts" aria-label="Tampilkan chart">
<div class="card-body d-flex justify-content-between align-items-center gap-3">
<div>
<h5>Dimensi dan Komponen Kesiapan Adopsi</h5>
<p class="text-body-secondary mb-0">Perbandingan skor dimensi dan komponen kesiapan adopsi petani.</p>
</div>
<span class="btn btn-icon btn-label-secondary btn-sm chart-group-icon-toggle" aria-hidden="true">
<i class="icon-base ti tabler-chevron-up"></i>
<i class="icon-base ti tabler-chevron-down"></i>
</span>
</div>
</div>
<div class="collapse show chart-group-panel" id="indeks-kesiapan-charts">
<div class="collapse chart-group-panel" id="indeks-kesiapan-charts">
<div class="row g-6 py-4">
<div class="col-lg-6 col-sm-12">
<div class="card card-border-shadow-info h-100">
@@ -1219,18 +1219,18 @@
<div class="py-4">
<div class="card chart-group-header-toggle" role="button" tabindex="0"
data-bs-toggle="collapse" data-bs-target="#indeks-wilayah-charts"
aria-expanded="true" aria-controls="indeks-wilayah-charts" aria-label="Sembunyikan chart">
aria-expanded="false" aria-controls="indeks-wilayah-charts" aria-label="Tampilkan chart">
<div class="card-body d-flex justify-content-between align-items-center gap-3">
<div>
<h5>Sebaran wilayah petani</h5>
<p class="text-body-secondary mb-0">Peta dan komposisi segmen kesiapan adopsi petani per desa/kelurahan.</p>
</div>
<span class="btn btn-icon btn-label-secondary btn-sm chart-group-icon-toggle" aria-hidden="true">
<i class="icon-base ti tabler-chevron-up"></i>
<i class="icon-base ti tabler-chevron-down"></i>
</span>
</div>
</div>
<div class="collapse show chart-group-panel" id="indeks-wilayah-charts">
<div class="collapse chart-group-panel" id="indeks-wilayah-charts">
<div class="row g-6 py-4">
<div class="col-lg-12 col-sm-12">
<div class="card card-border-shadow-danger h-100">
@@ -1366,6 +1366,32 @@ document.addEventListener('DOMContentLoaded', function () {
const headingColor = config.colors.headingColor;
const legendColor = config.colors.bodyColor;
const fontFamily = config.fontFamily;
const pastelChart = config.chartColors || {};
const pastelSeries = pastelChart.series || ['#9D8EF0', '#6FD68F', '#FFB46F', '#5FC7D6', '#F47C86', '#9EA6B0', '#65D8BD', '#63C7E0'];
const pastelSemantic = pastelChart.semantic || {};
const pastelText = pastelChart.text || {};
function hexToRgba(hex, alpha) {
const value = String(hex || '').replace('#', '');
if (!/^[0-9a-fA-F]{6}$/.test(value)) {
return hex;
}
const red = parseInt(value.slice(0, 2), 16);
const green = parseInt(value.slice(2, 4), 16);
const blue = parseInt(value.slice(4, 6), 16);
return `rgba(${red}, ${green}, ${blue}, ${alpha})`;
}
function softBadgeStyle(backgroundColor, textColor) {
const borderColor = hexToRgba(backgroundColor, 0.36);
return [
`background-color:${hexToRgba(backgroundColor, 0.22)} !important`,
`border:1px solid ${borderColor}`,
`color:${textColor} !important`,
'font-weight:600'
].join(';');
}
const farmerDataUrl = @json(route('dashboard.demografi-petani.data'));
const farmerProfileUrl = @json(url('/dashboard/profil/petani'));
@@ -1500,8 +1526,8 @@ document.addEventListener('DOMContentLoaded', function () {
tbody.innerHTML = rows.map((petani, index) => {
const rowNumber = ((result.pagination.current_page - 1) * result.pagination.per_page) + index + 1;
const genderBadge = Number(petani.jenis_kelamin) === 1
? `<span class="badge bg-label-info">Laki-laki</span>`
: `<span class="badge" style="background-color:#ffe8f1 !important; color:#ff5598 !important;">Perempuan</span>`;
? `<span class="badge" style="${softBadgeStyle(pastelSemantic.info || '#5FC7D6', pastelText.info || '#00BAD1')}">Laki-laki</span>`
: `<span class="badge" style="${softBadgeStyle(pastelSemantic.danger || '#F47C86', pastelText.danger || '#FF4C51')}">Perempuan</span>`;
const umur = (petani.umur !== null && petani.umur !== undefined) ? `${petani.umur} tahun` : '-';
return `
@@ -1706,7 +1732,7 @@ document.addEventListener('DOMContentLoaded', function () {
},
labels: ['Laki-laki', 'Perempuan'],
series: [lakiLaki, perempuan],
colors: [config.colors.info, '#ff5598'],
colors: [pastelSemantic.info || '#5FC7D6', pastelSemantic.pink || '#F47C86'],
stroke: { width: 0 },
dataLabels: {
enabled: true,
@@ -1815,12 +1841,11 @@ document.addEventListener('DOMContentLoaded', function () {
data: ageGroupData
}
],
colors: ['#c7c2f9', '#9d94f4', '#7367f0', '#5048a8', '#2e2960'],
colors: [pastelSemantic.primary || '#9D8EF0'],
plotOptions: {
bar: {
borderRadius: 4,
columnWidth: '45%',
distributed: true,
dataLabels: { position: 'top' }
}
},
@@ -1875,7 +1900,7 @@ document.addEventListener('DOMContentLoaded', function () {
const label = w.globals.labels[dataPointIndex];
const percentage = totalAgeGroup > 0 ? (Number(value) / totalAgeGroup) * 100 : 0;
return `
<div style="background:${w.config.colors[dataPointIndex % w.config.colors.length]}; color:#fff; padding:8px 12px; border-radius:5px; font-size:13px; font-weight:500; font-family:${fontFamily}; box-shadow:0 4px 12px rgba(0,0,0,.15);">
<div style="background:${w.config.colors[dataPointIndex % w.config.colors.length]}; color:${headingColor}; padding:8px 12px; border-radius:5px; font-size:13px; font-weight:500; font-family:${fontFamily}; box-shadow:0 4px 12px rgba(0,0,0,.15);">
${label} tahun: <strong>${value} petani (${percentage.toFixed(1)}%)</strong>
</div>
`;
@@ -1918,10 +1943,9 @@ document.addEventListener('DOMContentLoaded', function () {
}
},
series: [{ name: 'Petani', data: educationData }],
colors: ['#e9f9f0', '#a9e8c5', '#68d79a', '#28c76f', '#1c8b4d', '#104f2c'],
colors: [pastelSemantic.success || '#6FD68F'],
plotOptions: {
bar: {
distributed: true,
horizontal: true,
borderRadius: 4,
barHeight: '55%',
@@ -1975,7 +1999,7 @@ document.addEventListener('DOMContentLoaded', function () {
const label = w.globals.labels[dataPointIndex];
const percentage = totalPendidikan > 0 ? ((value / totalPendidikan) * 100).toFixed(1) : '0.0';
return `
<div style="background:${w.config.colors[dataPointIndex % w.config.colors.length]}; color:#fff; padding:8px 12px; border-radius:5px; font-size:13px; font-weight:500; font-family:${fontFamily}; box-shadow:0 4px 12px rgba(0,0,0,.15);">
<div style="background:${w.config.colors[dataPointIndex % w.config.colors.length]}; color:${headingColor}; padding:8px 12px; border-radius:5px; font-size:13px; font-weight:500; font-family:${fontFamily}; box-shadow:0 4px 12px rgba(0,0,0,.15);">
${label}: <strong>${value} petani (${percentage}%)</strong>
</div>
`;
@@ -2017,10 +2041,9 @@ document.addEventListener('DOMContentLoaded', function () {
}
},
series: [{ name: 'Petani', data: dependentData }],
colors: ['#ffb7b9', '#ff4c51', '#b23538', '#661e20'],
colors: [pastelSemantic.danger || '#F47C86'],
plotOptions: {
bar: {
distributed: true,
horizontal: true,
borderRadius: 4,
barHeight: '50%',
@@ -2074,7 +2097,7 @@ document.addEventListener('DOMContentLoaded', function () {
const label = w.globals.labels[dataPointIndex];
const percentage = totalDependentsFarmers > 0 ? ((value / totalDependentsFarmers) * 100).toFixed(1) : '0.0';
return `
<div style="background:${w.config.colors[dataPointIndex % w.config.colors.length]}; color:#fff; padding:8px 12px; border-radius:5px; font-size:13px; font-weight:500; font-family:${fontFamily}; box-shadow:0 4px 12px rgba(0,0,0,.15);">
<div style="background:${w.config.colors[dataPointIndex % w.config.colors.length]}; color:${headingColor}; padding:8px 12px; border-radius:5px; font-size:13px; font-weight:500; font-family:${fontFamily}; box-shadow:0 4px 12px rgba(0,0,0,.15);">
${label}: <strong>${value} petani (${percentage}%)</strong>
</div>
`;
@@ -2116,7 +2139,7 @@ document.addEventListener('DOMContentLoaded', function () {
},
labels: ['Terdaftar', 'Tidak Terdaftar', 'Belum Terisi'],
series: farmerGroupData,
colors: [config.colors.success, config.colors.warning, config.colors.secondary],
colors: [pastelSemantic.success || '#6FD68F', pastelSemantic.warning || '#FFB46F', pastelSemantic.secondary || '#9EA6B0'],
stroke: { width: 0 },
dataLabels: {
enabled: true,
@@ -2215,12 +2238,12 @@ document.addEventListener('DOMContentLoaded', function () {
labels: commodityLabels,
series: commoditySeries.map(Number),
colors: [
config.colors.primary,
config.colors.warning,
config.colors.success,
config.colors.info,
config.colors.danger,
config.colors.secondary
pastelSemantic.primary || '#9D8EF0',
pastelSemantic.warning || '#FFB46F',
pastelSemantic.success || '#6FD68F',
pastelSemantic.info || '#5FC7D6',
pastelSemantic.danger || '#F47C86',
pastelSemantic.secondary || '#9EA6B0'
],
stroke: { width: 0 },
dataLabels: {
@@ -2270,7 +2293,7 @@ document.addEventListener('DOMContentLoaded', function () {
const percentage = totalCommodityFarmers > 0 ? ((value / totalCommodityFarmers) * 100).toFixed(1) : '0.0';
const color = w.globals.colors[seriesIndex];
return `
<div style="background:${color}; color:#fff; padding:8px 12px; border-radius:5px; font-size:13px; font-weight:500; font-family:${fontFamily}; box-shadow:0 4px 12px rgba(0,0,0,.15);">
<div style="background:${color}; color:${headingColor}; padding:8px 12px; border-radius:5px; font-size:13px; font-weight:500; font-family:${fontFamily}; box-shadow:0 4px 12px rgba(0,0,0,.15);">
${label}: <strong>${value} petani (${percentage}%)</strong>
</div>
`;
@@ -2335,10 +2358,9 @@ document.addEventListener('DOMContentLoaded', function () {
}
},
series: [{ name: 'Petani', data: landAreaData }],
colors: ['#ffbb7b', '#ff9f43', '#b26f2e', '#663f1a'],
colors: [pastelSemantic.warning || '#FFB46F'],
plotOptions: {
bar: {
distributed: true,
horizontal: true,
borderRadius: 4,
barHeight: '50%',
@@ -2392,7 +2414,7 @@ document.addEventListener('DOMContentLoaded', function () {
const label = w.globals.labels[dataPointIndex];
const percentage = totalLandFarmers > 0 ? ((value / totalLandFarmers) * 100).toFixed(1) : '0.0';
return `
<div style="background:${w.config.colors[dataPointIndex % w.config.colors.length]}; color:#fff; padding:8px 12px; border-radius:5px; font-size:13px; font-weight:500; font-family:${fontFamily}; box-shadow:0 4px 12px rgba(0,0,0,.15);">
<div style="background:${w.config.colors[dataPointIndex % w.config.colors.length]}; color:${headingColor}; padding:8px 12px; border-radius:5px; font-size:13px; font-weight:500; font-family:${fontFamily}; box-shadow:0 4px 12px rgba(0,0,0,.15);">
${label}: <strong>${value} petani (${percentage}%)</strong>
</div>
`;
@@ -2431,10 +2453,10 @@ document.addEventListener('DOMContentLoaded', function () {
labels: landOwnershipStatusLabels,
series: landOwnershipStatusSeries,
colors: [
config.colors.success,
config.colors.warning,
config.colors.info,
config.colors.secondary
pastelSemantic.success || '#6FD68F',
pastelSemantic.warning || '#FFB46F',
pastelSemantic.info || '#5FC7D6',
pastelSemantic.secondary || '#9EA6B0'
],
stroke: { width: 0 },
dataLabels: {
@@ -2538,10 +2560,9 @@ document.addEventListener('DOMContentLoaded', function () {
}
},
series: [{ name: 'Petani', data: incomeData }],
colors: ['#99e3ec', '#4ccede', '#00bad1', '#008292', '#004a53'],
colors: [pastelSemantic.info || '#5FC7D6'],
plotOptions: {
bar: {
distributed: true,
horizontal: true,
borderRadius: 4,
barHeight: '50%',
@@ -2595,7 +2616,7 @@ document.addEventListener('DOMContentLoaded', function () {
const label = w.globals.labels[dataPointIndex];
const percentage = totalIncomeFarmers > 0 ? ((value / totalIncomeFarmers) * 100).toFixed(1) : '0.0';
return `
<div style="background:${w.config.colors[dataPointIndex % w.config.colors.length]}; color:#fff; padding:8px 12px; border-radius:5px; font-size:13px; font-weight:500; font-family:${fontFamily}; box-shadow:0 4px 12px rgba(0,0,0,.15);">
<div style="background:${w.config.colors[dataPointIndex % w.config.colors.length]}; color:${headingColor}; padding:8px 12px; border-radius:5px; font-size:13px; font-weight:500; font-family:${fontFamily}; box-shadow:0 4px 12px rgba(0,0,0,.15);">
${label}: <strong>${value} petani (${percentage}%)</strong>
</div>
`;
@@ -2832,6 +2853,10 @@ document.addEventListener('DOMContentLoaded', function () {
<script>
$(document).ready(function () {
const segments = @json($segments);
const segmentPalette = segments.map(function (segment, index) {
return config.chartColors?.semantic?.[segment.color] || config.chartColors?.series?.[index % config.chartColors.series.length] || '#9EA6B0';
});
const segmentTextColors = config.chartColors?.text || {};
// Chart Segmentasi Petani
var chartSegmentasiPetani;
@@ -2871,7 +2896,7 @@ document.addEventListener('DOMContentLoaded', function () {
}
},
labels: @json(collect($segments)->pluck('name')->values()),
colors: @json($colors),
colors: segmentPalette,
plotOptions: {
pie: {
borderRadius: 12,
@@ -2925,16 +2950,17 @@ document.addEventListener('DOMContentLoaded', function () {
const total = response.series[index] ?? 0;
const persen = response.persentase[index] ?? 0;
const segmentColor = segmentTextColors[segment.color] || config.colors[segment.color] || segmentPalette[index] || '#808390';
html += `
<tr>
<td>
<div class="d-flex justify-content-start align-items-center gap-2">
<div class="flex-shrink-0">
<i class="icon-base ti ${segment.icon} icon-lg text-${segment.color}"></i>
<i class="icon-base ti ${segment.icon} icon-lg" style="color:${segmentColor};"></i>
</div>
<span class="text-${segment.color}">
<span style="color:${segmentColor};">
${segment.name}
</span>
</div>
@@ -2971,9 +2997,12 @@ document.addEventListener('DOMContentLoaded', function () {
</script>
<script>
$(document).ready(function () {
const segmentPalette = (@json($segments)).map(function (segment, index) {
return config.chartColors?.semantic?.[segment.color] || config.chartColors?.series?.[index % config.chartColors.series.length] || '#9EA6B0';
});
var optionsSegmentasiPetaniByKomoditas = {
series: [],
colors: @json($colors),
colors: segmentPalette,
chart: {
type: 'bar',
@@ -3157,7 +3186,7 @@ document.addEventListener('DOMContentLoaded', function () {
plotOptions: { radar: { polygons: { strokeColors: borderColor, connectorColors: borderColor } } },
stroke: { width: 2 },
legend: { show: false },
colors: [config.colors.primary],
colors: [config.chartColors?.semantic?.primary || '#9D8EF0'],
fill: { opacity: 0.12 },
markers: {
size: 5, strokeWidth: 2, strokeColors: config.colors.cardColor, hover: { sizeOffset: 2 },
@@ -3208,7 +3237,14 @@ document.addEventListener('DOMContentLoaded', function () {
</script>
<script>
$(document).ready(function () {
var palette = [config.colors.success, config.colors.primary, config.colors.warning, config.colors.info, config.colors.danger, config.colors.secondary];
var palette = [
config.chartColors?.semantic?.success || '#6FD68F',
config.chartColors?.semantic?.primary || '#9D8EF0',
config.chartColors?.semantic?.warning || '#FFB46F',
config.chartColors?.semantic?.info || '#5FC7D6',
config.chartColors?.semantic?.danger || '#F47C86',
config.chartColors?.semantic?.secondary || '#9EA6B0'
];
[
{ id: 'dimensi', key: 'radarDimensi', url: "{{ route('dashboard.indeks-petani.dimensi') }}", title: "Dimensi Kesiapan Adopsi", labels: ["Sistem & Praktik Budidaya","Sosial Ekonomi Rumah Tangga","Rantai Nilai & Akses Pasar"], categories: [["Sistem & Praktik","Budidaya"],["Sosial Ekonomi","Rumah Tangga"],["Rantai Nilai &","Akses Pasar"]] },
{ id: 'komponen', key: 'radarKomponen', url: "{{ route('dashboard.indeks-petani.komponen') }}", title: "Komponen Kesiapan Adopsi", labels: ["Motivasi & Kapasitas Adopsi","Kondisi Ekonomi Rumah Tangga","Praktik Budidaya & GAP","Keterlibatan Kelembagaan","Akses & Kebebasan Keuangan","Rantai Nilai & Akses Pasar"], categories: [["Motivasi & Kapasitas","Adopsi"],["Kondisi Ekonomi","Rumah Tangga"],["Praktik Budidaya","& GAP"],["Keterlibatan","Kelembagaan"],["Akses & Kebebasan","Keuangan"],["Rantai Nilai &","Akses Pasar"]] }
@@ -3282,7 +3318,7 @@ document.addEventListener('DOMContentLoaded', function () {
const warnaSegmen = {
@foreach($segments as $segment)
"{{ $segment['name'] }}": "var(--bs-{{ $segment['color'] }})",
"{{ $segment['name'] }}": config.chartColors?.semantic?.["{{ $segment['color'] }}"] || '#9EA6B0',
@endforeach
};
@@ -3340,7 +3376,7 @@ document.addEventListener('DOMContentLoaded', function () {
color: '#666',
weight: 1,
fillColor:
warnaSegmen[desa.segmentasi?.segmen] || '#ccc',
warnaSegmen[desa.segmentasi?.segmen] || '#9EA6B0',
fillOpacity: 0.7
});
@@ -3389,6 +3425,7 @@ document.addEventListener('DOMContentLoaded', function () {
</script>
<script>
$(document).ready(function () {
const segmentTextColors = config.chartColors?.text || {};
var tableDesa = $('#table-desa').DataTable({
"paging": true,
"pageLength": 5,
@@ -3429,7 +3466,8 @@ document.addEventListener('DOMContentLoaded', function () {
var count = Number(data && data.count) || 0;
if (type !== 'display') return count;
var percentage = Number(data && data.percentage || 0).toLocaleString('id-ID', { maximumFractionDigits: 2 });
return '<span class="fw-semibold text-' + (data && data.color || 'secondary') + '">' + count.toLocaleString('id-ID') +
var segmentColor = segmentTextColors[data && data.color || 'secondary'] || '#808390';
return '<span class="fw-semibold" style="color:' + segmentColor + ';">' + count.toLocaleString('id-ID') +
'</span> <span class="text-body-secondary small">(' + percentage + '%)</span>';
}
};
@@ -3439,6 +3477,36 @@ document.addEventListener('DOMContentLoaded', function () {
</script>
<script>
$(document).ready(function () {
const indexSegmentColorKeys = {
@foreach($segments as $segment)
"{{ $segment['name'] }}": "{{ $segment['color'] }}",
@endforeach
};
const indexSegmentColors = {
@foreach($segments as $segment)
"{{ $segment['name'] }}": config.chartColors?.semantic?.["{{ $segment['color'] }}"] || '#9EA6B0',
@endforeach
};
const indexSegmentTextColors = config.chartColors?.text || {};
function indexHexToRgba(hex, alpha) {
const value = String(hex || '').replace('#', '');
if (!/^[0-9a-fA-F]{6}$/.test(value)) {
return hex;
}
const red = parseInt(value.slice(0, 2), 16);
const green = parseInt(value.slice(2, 4), 16);
const blue = parseInt(value.slice(4, 6), 16);
return `rgba(${red}, ${green}, ${blue}, ${alpha})`;
}
function indexSegmentBadgeStyle(backgroundColor, textColor) {
return [
`background-color:${indexHexToRgba(backgroundColor, 0.22)} !important`,
`border:1px solid ${indexHexToRgba(backgroundColor, 0.36)}`,
`color:${textColor} !important`,
'font-weight:600'
].join(';');
}
var tablePetani = $('#table-petani').DataTable({
dom: 'rt<"card-footer d-flex flex-wrap justify-content-between align-items-center gap-3"ip>',
pagingType: 'full_numbers',
@@ -3540,9 +3608,12 @@ document.addEventListener('DOMContentLoaded', function () {
if (!data.skor || !data.segmen) {
return '';
}
const segmentKey = indexSegmentColorKeys[data.segmen] || data.color || 'secondary';
const segmentColor = indexSegmentColors[data.segmen] || config.chartColors?.semantic?.[segmentKey] || '#9EA6B0';
const segmentTextColor = indexSegmentTextColors[segmentKey] || '#808390';
return `
<span class="badge bg-${data.color ?? 'secondary'}">
<span class="badge" style="${indexSegmentBadgeStyle(segmentColor, segmentTextColor)}">
${data.segmen}
</span>
`;