|
|
@@ -6,7 +6,7 @@
|
|
|
ref="chart_ref"
|
|
|
:options="chartOptions"
|
|
|
:data="chartData"
|
|
|
- :plugins="[ChartDataLabels]"
|
|
|
+ :plugins="activePlugins"
|
|
|
/>
|
|
|
</div>
|
|
|
<div v-else class="no-data-container">
|
|
|
@@ -30,22 +30,22 @@ import {
|
|
|
import ChartDataLabels from "chartjs-plugin-datalabels";
|
|
|
import { base64ToJPEG } from "src/helpers/convertBase64Image";
|
|
|
|
|
|
-ChartJS.register(Title, Tooltip, Legend, BarElement, CategoryScale, LinearScale);
|
|
|
+ChartJS.register(
|
|
|
+ Title,
|
|
|
+ Tooltip,
|
|
|
+ Legend,
|
|
|
+ BarElement,
|
|
|
+ CategoryScale,
|
|
|
+ LinearScale,
|
|
|
+);
|
|
|
|
|
|
const chart_ref = ref(null);
|
|
|
|
|
|
const props = defineProps({
|
|
|
- /**
|
|
|
- * Array de labels do eixo X
|
|
|
- */
|
|
|
labels: {
|
|
|
type: Array,
|
|
|
default: () => [],
|
|
|
},
|
|
|
- /**
|
|
|
- * Array de datasets no formato:
|
|
|
- * [{ label: String, data: Number[], color: String }]
|
|
|
- */
|
|
|
datasets: {
|
|
|
type: Array,
|
|
|
default: () => [],
|
|
|
@@ -58,12 +58,10 @@ const props = defineProps({
|
|
|
type: String,
|
|
|
default: "",
|
|
|
},
|
|
|
- /** Raio das bordas das barras. Use valores altos (ex: 50) para efeito "pill". */
|
|
|
barRadius: {
|
|
|
type: Number,
|
|
|
default: 4,
|
|
|
},
|
|
|
- /** Exibe datalabels em cima de cada barra */
|
|
|
showDatalabels: {
|
|
|
type: Boolean,
|
|
|
default: false,
|
|
|
@@ -76,6 +74,21 @@ const props = defineProps({
|
|
|
type: Function,
|
|
|
default: null,
|
|
|
},
|
|
|
+ /** Espessura máxima de cada barra em px */
|
|
|
+ maxBarThickness: {
|
|
|
+ type: Number,
|
|
|
+ default: null,
|
|
|
+ },
|
|
|
+ /** Percentual da categoria ocupado pelas barras (0-1). Maior = barras mais juntas. */
|
|
|
+ categoryPercentage: {
|
|
|
+ type: Number,
|
|
|
+ default: 0.8,
|
|
|
+ },
|
|
|
+ /** Percentual do espaço da categoria ocupado pela barra (0-1). */
|
|
|
+ barPercentage: {
|
|
|
+ type: Number,
|
|
|
+ default: 0.9,
|
|
|
+ },
|
|
|
});
|
|
|
|
|
|
const onResize = () => {
|
|
|
@@ -88,6 +101,8 @@ const hasData = computed(
|
|
|
() => props.labels.length > 0 && props.datasets.length > 0,
|
|
|
);
|
|
|
|
|
|
+const activePlugins = computed(() => [ChartDataLabels]);
|
|
|
+
|
|
|
const chartData = computed(() => ({
|
|
|
labels: props.labels,
|
|
|
datasets: props.datasets.map((ds) => ({
|
|
|
@@ -98,6 +113,11 @@ const chartData = computed(() => ({
|
|
|
borderRadius: props.barRadius,
|
|
|
borderSkipped: false,
|
|
|
borderWidth: 0,
|
|
|
+ ...(props.maxBarThickness != null
|
|
|
+ ? { maxBarThickness: props.maxBarThickness }
|
|
|
+ : {}),
|
|
|
+ categoryPercentage: props.categoryPercentage,
|
|
|
+ barPercentage: props.barPercentage,
|
|
|
})),
|
|
|
}));
|
|
|
|
|
|
@@ -107,6 +127,14 @@ const gridColor = "rgba(0,0,0,0.07)";
|
|
|
const chartOptions = computed(() => ({
|
|
|
responsive: true,
|
|
|
maintainAspectRatio: false,
|
|
|
+ layout: {
|
|
|
+ padding: {
|
|
|
+ top: props.showDatalabels ? 28 : 8,
|
|
|
+ left: 12,
|
|
|
+ right: 12,
|
|
|
+ bottom: 4,
|
|
|
+ },
|
|
|
+ },
|
|
|
plugins: {
|
|
|
legend: {
|
|
|
display: false,
|