<div clsss="graph">
  <div id="legend-container" class="canvas-legend"></div>
  <canvas id="chart-sample"></canvas>
</div>
.canvas-legend {
  position: absolute;
  top: 27px;
  left: 50px;

  &__list {
    display: flex;
    flex-direction: column;
    margin: 0px;
    padding: .5em;
    border: 1px solid #eee;
    background-color: #FFE0B2;
  }

  &__item {
    align-items: center;
    display: flex;
    flex-direction: row;
    margin: 0;
    padding: 0;
  }

  &__box {
    display: inline-block;
    height: 20px;
    margin-right: 10px;
    width: 20px;
  }

  &__label {
    font-size: 14px;
    margin: 0px;
    padding: 0px;
    line-height: 1;
  }
}
View Compiled
const getOrCreateLegendList = ( chart, id ) => {
    const legendContainer = document.getElementById( id );
    let listContainer = legendContainer.querySelector( 'ul' );

    if (!listContainer) {
      listContainer = document.createElement( 'ul' );
      listContainer.classList.add( 'canvas-legend__list' );

      legendContainer.appendChild(listContainer);
    }

    return listContainer;
};

const htmlLegendPlugin = {
    id: 'htmlLegend',
    afterUpdate( chart, args, options ) {
        const ul = getOrCreateLegendList( chart, options.containerID );

        // Remove old legend items
        while (ul.firstChild) {
            ul.firstChild.remove();
        }

        // Reuse the built-in legendItems generator
        const items = chart.options.plugins.legend.labels.generateLabels( chart );

        items.forEach(item => {
            const li = document.createElement('li');
            li.classList.add( 'canvas-legend__item' );

            // Color box
            const boxSpan = document.createElement('span');
            boxSpan.style.background = item.fillStyle;
            boxSpan.style.borderColor = item.strokeStyle;
            boxSpan.style.borderWidth = item.lineWidth + 'px';
            boxSpan.classList.add( 'canvas-legend__box' );

            // Text
            const textContainer = document.createElement('p');
            textContainer.style.color = item.fontColor;
            textContainer.classList.add( 'canvas-legend__label' );

            const text = document.createTextNode(item.text);
            textContainer.appendChild(text);

            li.appendChild(boxSpan);
            li.appendChild(textContainer);
            ul.appendChild(li);
        });
    }
};

const myChart = new Chart(
  document.getElementById( 'chart-sample' ),
  {
    type: 'bar',
    data: {
      labels: [
        '1月',
        '2月',
        '3月',
        '4月',
        '5月',
        '6月'
      ],
      datasets: [
        {
          label: '売上',
          data: [
            10,
            50,
            100,
            120,
            150,
            200
          ],
          backgroundColor: '#E91E63'
        }
      ]
    },
    options: {
      plugins: {
        htmlLegend: {
            containerID: 'legend-container',
        },
        legend: {
          display: false
        },
      }
    },
    plugins: [
        htmlLegendPlugin,
    ],
  }
);

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

  1. https://cdn.jsdelivr.net/npm/chart.js@3.7.0/dist/chart.min.js
  2. https://cdn.jsdelivr.net/npm/chartjs-plugin-datalabels@2.0.0