Chart.js - SpiderChart - Reducing padding between legend and charts - Not Working

greetings,

I have a pet project to show charts.js - spider chart and I try to reduce spaces between legends and charts.

Based on this stackoverflow and youtube

this is my project layout

/my-app
 /frontend
  /themes
    /spiderchart
     spiderchart.js
 /src/main/java
  /SpiderChartView.java

spiderchart.js

window.initSpiderChart = function (dataJson) {
    var data = JSON.parse(dataJson);
    console.log(data); // For debugging purposes

    // Check if data is an array
    if (!Array.isArray(data)) {
        console.error('Data is not an array:', data);
        return;
    }

    var labels = data.map(item => item.label);
    var values = data.map(item => item.value);

    var container = document.getElementById('spider-chart-container');
    var canvas = document.createElement('canvas');
    canvas.id = 'spider-chart';
    container.appendChild(canvas);

    var ctx = canvas.getContext('2d');

    var myChart = new Chart(ctx, {
        type: 'radar',
        data: {
            labels: labels, datasets: [{
                label: 'Scores',
                data: values,
                backgroundColor: 'rgba(255, 99, 132, 0.2)',
                borderColor: 'rgba(255, 99, 132, 1)',
                borderWidth: 1
            }]
        },
        plugins: [{
            beforeInit: function (chart, options) {
                chart.legend.afterFit = function () {
                    this.height = this.height + 10;
                };
            }
        }],
    });
};

and my SpiderChartView.java

package ...;

import com.vaadin.flow.component.AttachEvent;
import com.vaadin.flow.component.Tag;
import com.vaadin.flow.component.Text;
import com.vaadin.flow.component.dependency.CssImport;
import com.vaadin.flow.component.dependency.JavaScript;
import com.vaadin.flow.component.dependency.JsModule;
import com.vaadin.flow.component.html.Div;
import com.vaadin.flow.component.orderedlayout.HorizontalLayout;
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
import com.vaadin.flow.router.Route;

@Route("spider-chart")
@Tag("div")
@JavaScript("https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.7.0/chart.min.js")
@JsModule("./themes/spidercharts/spiderchart.js")
@CssImport("./themes/spidercharts/spiderchart.css")
public class SpiderChartView extends Div {

    public SpiderChartView() {}

    @Override
    protected void onAttach(AttachEvent attachEvent) {
        VerticalLayout leftSection = new VerticalLayout();
        leftSection.setWidth("50%");
        leftSection.add(new Text("Name: John Doe"), new Text("Address: 123 Main St"));

        VerticalLayout rightSection = new VerticalLayout();
        rightSection.setWidth("50%");

        rightSection.add();        // Create right section for the spider chart
        Div rightSectionDiv = new Div();
        rightSectionDiv.setId("spider-chart-container"); // Set ID for the spider chart container
        rightSection.add(rightSectionDiv);

        String jsonData = getData();

        getUI().ifPresent(ui -> ui.getPage().executeJs("window.initSpiderChart($0)", jsonData));

        // Arrange left and right sections horizontally
        HorizontalLayout layout = new HorizontalLayout(leftSection, rightSectionDiv);
        layout.setWidth("100%");
        add(layout);
    }

    private String getData() {
        return "[{\"label\": \"Quality\", \"value\": 4}, " +
                   "{\"label\": \"Performance\", \"value\": 3}, " +
                   "{\"label\": \"Price\", \"value\": 5}, " +
                   "{\"label\": \"Design\", \"value\": 4}, " +
                   "{\"label\": \"Customer Support\", \"value\": 5}]";

    }

}

It seems that plugins:beforeInit() is not executed.

Someone has an idea how to solve this problem? or maybe once faced the same isssue like this?

many thanks.

You want to take a look at this answer instead: chart.js2 - Chart.js - Increase spacing between legend and chart - Stack Overflow

In short, afterFit was removed from legend.

@sissbruecker many thanks to point me it out. I changing my js script by follwing his answer . He provides in codepen.

and my view can show spider chart now.

my spider-chart.js

function createNewLegendAndAttach(chartInstance, legendOpts) {
    var legend = new Chart.NewLegend({
        ctx: chartInstance.chart.ctx,
        options: legendOpts,
        chart: chartInstance
    });

    if (chartInstance.legend) {
        Chart.layoutService.removeBox(chartInstance, chartInstance.legend);
        delete chartInstance.newLegend;
    }

    chartInstance.newLegend = legend;
    Chart.layoutService.addBox(chartInstance, legend);


}

window.initSpiderChart = function (dataJson) {
    console.log("initSpiderChart")

    var data = JSON.parse(dataJson);
    console.log("data is parsed "+data); // For debugging purposes

    // Check if data is an array
    if (!Array.isArray(data)) {
        console.error('Data is not an array:', data);
        return;
    }

    var labels = data.map(item => item.label);
    var values = data.map(item => item.value);


    Chart.NewLegend = Chart.Legend.extend({
        afterFit: function () {
            this.height = this.height + 10;
        },
    });

    console.log("CONFIRMED::Chart.NewLegend" + Chart.NewLegend)

    kampret()

    Chart.plugins.register({
        beforeInit: function (chartInstance) {
            var legendOpts = chartInstance.options.legend;

            if (legendOpts) {
                createNewLegendAndAttach(chartInstance, legendOpts);
            }
        },
        beforeUpdate: function (chartInstance) {
            var legendOpts = chartInstance.options.legend;

            if (legendOpts) {
                legendOpts = Chart.helpers.configMerge(Chart.defaults.global.legend, legendOpts);

                if (chartInstance.newLegend) {
                    chartInstance.newLegend.options = legendOpts;
                } else {
                    createNewLegendAndAttach(chartInstance, legendOpts);
                }
            } else {
                Chart.layoutService.removeBox(chartInstance, chartInstance.newLegend);
                delete chartInstance.newLegend;
            }
        },
        afterEvent: function (chartInstance, e) {
            var legend = chartInstance.newLegend;
            if (legend) {
                legend.handleEvent(e);
            }
        }
    });

    console.log('ChartsPluginsRegistered::' + Chart.plugins)

    window.chartColors = {
        red: 'rgb(255, 99, 132)',
        orange: 'rgb(255, 159, 64)',
        yellow: 'rgb(255, 205, 86)',
        green: 'rgb(75, 192, 192)',
        blue: 'rgb(54, 162, 235)',
        purple: 'rgb(153, 102, 255)',
        grey: 'rgb(231,233,237)'
    };

    console.log('windows.charcolors::registered' + window.chartColors)

    var config = {
        type: 'radar',

        data: {
            labels: labels, datasets: [{
                label: labels,
                data: values,
                backgroundColor: 'rgba(255, 99, 132, 0.2)',
                borderColor: 'rgba(255, 99, 132, 1)',
                borderWidth: 1
            }]
        },
        options: {
            responsive: true,
            legend: {
                display: true,
                labels: {
                    padding: 20
                },
            },
            tooltips: {
                enabled: false,
            }
        }
    };
    var ctx = document.getElementById("spider-chart-canvas").getContext("2d");
    window.myPie = new Chart(ctx, config);
};```


And dont forget to add html tag **canvas** in XXXView because this script acceses **a canvas** not **a div**.

many thanks.