最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Persisting flot legend label checkbox on un-check - Stack Overflow

programmeradmin2浏览0评论

I have a scenario where I want to toggle series based on checkbox selection. I have added the checkbox to the legend using labelFormatting in legend option like:

     var otherOptions = {
                           legend: {
                                     container: legend,
                                     labelFormatter: function (label, series) {
                                        var cb = '<input type="checkbox" name="' + label + '" checked="checked" id="id' + label + '"> ' + label;
                                        return cb;
                                     }
                            },
                         };  

And I have added the click event for the legend so that I can manipulate the series based on checked items. It all works fine except when I uncheck a label in legend, on re-draw it removes that series line from the legend as well. So for ex., below is the before and after image:

Before

After

Notice that in after image "USA" checkbox is missing. Is there any way I can still show the unchecked "USA" checkbox in legend?

I looked at the suggestion here: flot graph, use legend to turn on/off series

But the only problem is that I don't want to have legend AND checkbox legend separate. The question on the given link was answered 1+ year ago so I thought I am gonna take a chance and ask the question again in case someone knows a way to do this.

Please let me know.

Thanks!

I have a scenario where I want to toggle series based on checkbox selection. I have added the checkbox to the legend using labelFormatting in legend option like:

     var otherOptions = {
                           legend: {
                                     container: legend,
                                     labelFormatter: function (label, series) {
                                        var cb = '<input type="checkbox" name="' + label + '" checked="checked" id="id' + label + '"> ' + label;
                                        return cb;
                                     }
                            },
                         };  

And I have added the click event for the legend so that I can manipulate the series based on checked items. It all works fine except when I uncheck a label in legend, on re-draw it removes that series line from the legend as well. So for ex., below is the before and after image:

Before

After

Notice that in after image "USA" checkbox is missing. Is there any way I can still show the unchecked "USA" checkbox in legend?

I looked at the suggestion here: flot graph, use legend to turn on/off series

But the only problem is that I don't want to have legend AND checkbox legend separate. The question on the given link was answered 1+ year ago so I thought I am gonna take a chance and ask the question again in case someone knows a way to do this.

Please let me know.

Thanks!

Share Improve this question edited Jun 20, 2020 at 9:12 CommunityBot 11 silver badge asked Apr 5, 2012 at 0:40 test123test123 14.2k10 gold badges30 silver badges34 bronze badges 0
Add a ment  | 

3 Answers 3

Reset to default 6

Instead of removing the series all together if the checkbox is unchecked, add it with empty data.

Something like this:

function plotByChoice(doAll)
{
  $('#legend .legendCB').each(
   function(){
     if (this.checked)
     {         
       data.push(datasets[someLabel]);
     }
     else
     {
       data.push({label: someLabel, data: []})
     }        
   }
 );

 // plot call etc...
}  

Working fiddle is here.

For anyone looking for a clean solution AND for Chart.js v3 :

This is unfortunately not possible for Chart.js v3 as legends are generated with text (no HTML can be appended to the legend itself, unfortunately).

We have to use generateLabels function to render the legend labels.

I suggest using the pointStyle option to render an image (checkbox, actually), instead of a rectangle by default, so we can rerender automatically everytime the user checks or not the legend (it's dynamic, ofc, and we don't have to do something plicated programmatically).

So, first, generate the 2 images, corresponding to the checkboxes (I'm using FontAwesome icons that I've generated in PNG from SVG files) :

let checkboxYes = new Image(14, 14);
checkboxYes.src = '/static/img/check_yes.png';
let checkboxNo = new Image(14, 14);
checkboxNo.src = '/static/img/check_no.png';

Then, we can use it in the Chart.js options:

legend: {
    labels: {
        usePointStyle: true,
        generateLabels: function(chart) {
            labels = Chart.defaults.plugins.legend.labels.generateLabels(chart);
            for (var key in labels) {
                labels[key].pointStyle = labels[key].hidden ? checkboxNo : checkboxYes
            }
            return labels;
          }
    }
},

Explanations

  • I'm setting usePointStyle to true so that I can customize the point style later
  • Chart.defaults.plugins.legend.labels.generateLabels(chart) kind of pre generate the labels for me (and store it into labels), so it's like a function override!
  • Then for each label, I'm changing its pointStyle to the checkbox image depending on the hidden parameter (if the user checked the box)
  • Finally, return the labels

It's perhaps not the best solution, but works amazingly well for me:

Click here to see the animated result in GIF :)

i did it in the same manner but when i click on legends all of the legends get disappear , even i updated the onclick function as well it is not working for me

labels: { usePointStyle: true,

          // eslint-disable-next-line object-shorthand
          generateLabels: (chart) => {
            let labels = Chart.defaults.plugins.legend.labels.generateLabels(chart);
        
            labels = labels.map((label) => ({
              ...label,
              pointStyle: label.hidden ? checkboxNo : checkboxYes,
              font: {
                size: 14,
                family: 'Montserrat',
                weight: 600,
              },
              color: label.hidden ? '#999' : '#323C46',
              margin: {
                top: 5,
                bottom: 5,
                left: 10,
                right: 10,
              },
              // Handle click event to toggle visibility of the clicked legend item
              onClick: (e, legendItem, legend) => {
                console.log(legendItem)
                const index = legendItem.datasetIndex;
                const meta = chart.getDatasetMeta(index);
                meta.hidden = meta.hidden === null ? !chart.data.datasets[index].hidden : null;
                chart.update();
              },
            }));
        
            return labels;
          },
        },

and i am not able apply any style as well.

发布评论

评论列表(0)

  1. 暂无评论