图表 js - v 4 如何更改图表图例的顺序

Chart js - v 4 How can I change the order of chart legend

提问人:jy p 提问时间:11/15/2023 最后编辑:jy p 更新时间:11/17/2023 访问量:46

问:

图例是使用 html 图例插件创建的,该插件的显示方式与绘制图表的顺序不同

  1. 有没有办法更改图例顺序以匹配数据顺序?

  2. 我想将标签形状更改为线条。

我希望它与下面相同。在此处输入图像描述

const getOrCreateLegendList = (chart, id) => {
              const legendContainer = document.getElementById(id);
              let listContainer = legendContainer.querySelector('ul');

              if (!listContainer) {
                listContainer = document.createElement('ul');
                listContainer.style.display = 'flex';
                listContainer.style.flexDirection = 'row';
                listContainer.style.margin = 0;
                listContainer.style.padding = 0;

                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,idx)=> {
                  const li = document.createElement('li');
                  li.style.alignItems = 'center';
                  li.style.cursor = 'pointer';
                  li.style.display = 'flex';
                  li.style.flexDirection = 'row';
                  li.style.marginLeft = '10px';

                  li.onclick = () => {
                    //let {type} = chart.config;
                    let {type} = chart.config.data.datasets[idx];
                    console.log('items: ', items);
                    console.log('item: ', item);
                    console.log('this: ', $(this));
                    console.log('type11: ', type);
                    console.log('config11: ', chart.config);
                    if (type === 'pie' || type === 'doughnut') {
                      // Pie and doughnut charts only have a single dataset and visibility is per item
                      chart.toggleDataVisibility(item.index);
                    } else {
                      chart.setDatasetVisibility(item.datasetIndex, !chart.isDatasetVisible(item.datasetIndex));
                    }
                    chart.update();
                  };

                  // Color box
                  //let {type} = chart.config;
                  let {type} = chart.config.data.datasets[idx];
                  let height = type==='line'? '5px':'20px';
                  console.log('type22: ', type);
                  console.log('config22: ', chart.config);
                  const boxSpan = document.createElement('span');
                  boxSpan.style.background = item.fillStyle;
                  boxSpan.style.borderColor = item.strokeStyle;
                  boxSpan.style.borderWidth = item.lineWidth + 'px';
                  boxSpan.style.display = 'inline-block';
                  boxSpan.style.flexShrink = 0;
                  boxSpan.style.height = height;
                  boxSpan.style.marginRight = '10px';
                  boxSpan.style.width = '20px';

                  // Text
                  const textContainer = document.createElement('p');
                  textContainer.style.color = item.fontColor;
                  textContainer.style.margin = 0;
                  textContainer.style.padding = 0;
                  textContainer.style.textDecoration = item.hidden ? 'line-through' : '';

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

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

const data = [
            { year: 2010, count: 10, count2:Math.floor(Math.random()*100), count3:Math.floor(Math.random()*100), count4:Math.floor(Math.random()*100) },
            { year: 2011, count: 20, count2:Math.floor(Math.random()*100), count3:Math.floor(Math.random()*100), count4:Math.floor(Math.random()*100) },
            { year: 2012, count: 15, count2:Math.floor(Math.random()*100), count3:Math.floor(Math.random()*100), count4:Math.floor(Math.random()*100) },
            { year: 2013, count: 25, count2:Math.floor(Math.random()*100), count3:Math.floor(Math.random()*100), count4:Math.floor(Math.random()*100) },
            { year: 2014, count: 22, count2:Math.floor(Math.random()*100), count3:Math.floor(Math.random()*100), count4:Math.floor(Math.random()*100) },
            { year: 2015, count: 30, count2:Math.floor(Math.random()*100), count3:Math.floor(Math.random()*100), count4:Math.floor(Math.random()*100) },
            { year: 2016, count: 28, count2:Math.floor(Math.random()*100), count3:Math.floor(Math.random()*100), count4:Math.floor(Math.random()*100) },
          ];
        
        var ctx = document.getElementById("canvas");
        var myChart =  new Chart(
                ctx,
                {
                 //type: 'bar',
                  options: {
                      animation: true,
                      responsive: true,
                      elements: {
                          bar: {
                              borderWidth: 2,
                          }
                      },
                      plugins: {
                        /* legend: {
                          display: true, 
                          position: 'bottom' //'right' 
                        }, */
                        htmlLegend: {
                            // ID of the container to put the legend in
                            containerID: 'legend-container',
                        },
                        legend: {
                            display: false,
                            //reverse: true,
                        },
                        tooltip: {
                          enabled: true,
                          //usePointStyle: true,
                        }
                      },
                      scales: {
                          x: {
                              title: {
                                  display: true,
                                  text: 'date'
                              }
                          },
                          y: {
                              title: {
                                  display: true,
                                  text: 'count'
                              }
                          }
                      },
                   }, // end options
                  plugins: [htmlLegendPlugin], 
                  data: {
                    labels: data.map(row => row.year),
                    datasets: [
                      {
                        type: 'bar',
                        label: 'bar1',  
                        data: data.map(row => row.count),
                        // this dataset is drawn below  
                        order: 1
                      },
                      {
                        type: 'bar',
                        label: 'bar2',  
                        data: data.map(row => row.count2),
                        order: 1
                      },
                      {
                        type: 'bar',  
                        label: 'bar3',  
                        data: data.map(row => row.count3),
                        order: 1
                      },
                      {
                        type: 'bar', 
                        label: 'bar4',  
                        data: data.map(row => row.count4),
                        order: 1
                      },
                      {
                        type: 'line',
                        label: 'line1', 
                        pointStyle:'line',
                        data: data.map(row => row.count),
                        // this dataset is drawn on top
                        order: 0
                      },
                      {
                        type: 'line',
                        label: 'line2', 
                        pointStyle:'line',
                        data: data.map(row => row.count2),
                        order: 0        
                      }
                    ]
                  }// end datasets
                }
              );

我尝试使用 LegendCallback 创建和排序图例,但 4.4 版没有 generateLegend() 函数,所以我正在寻找另一种方法。

JavaScript 图表.js 图例

评论


答: 暂无答案