Chart.js更改图例切换行为

时间:2017-03-02 12:26:16

标签: javascript jquery chart.js

我有一张来自chart.js的雷达图表。目前,它加载了所有可行的数据,并且支持图例通过单击图例标签来表现,该标签可以切换与图例相关联的数据。我希望能够点击图例标签,然后切换所有其他关闭并可能引入“全部”选项?这是否适用于chart.js?

以下是我的图表现在的样子:

var chartata = { 
labels: [ 
"Strategic Development and Ownership", 
"Driving change through others", 
"Exec Disposition", 
"Commercial Acumen", 
"Develops High Performance Teams", 
"Innovation and risk taking", 
"Global Leadership", 
"Industry Leader" 
]}; 

var ctx = $("#allRadarData"); 

var config = { 
    type: 'radar', 
    data: chartata,     
    animationEasing: 'linear',
        options: {           
         legend: {
            fontSize: 10,
            display: true,
            itemWidth: 150,
            position: 'bottom',
            fullWidth: true,
            labels: {
                fontColor: 'rgb(0,0,0)',
                boxWidth: 10,
                padding: 20
            },
        },
         tooltips: {
            enabled: true
        },
        scale: {
            ticks: {
                fontSize: 15,
                beginAtZero: true,
                stepSize: 1,
                max: 5
            }
        } 

    },
}, 

LineGraph = new Chart(ctx, config); 

var colorArray = [

    ["#f44336", false],
    ["#E91E63", false],
    ["#9C27B0", false],
    ["#673AB7", false],
    ['#3F51B5', false],
    ["#607D8B", false]
];


for (var i in data) { 
    tmpscore=[]; 
    tmpscore.push(data[i].score1); 
    tmpscore.push(data[i].score2); 
    tmpscore.push(data[i].score3); 
    tmpscore.push(data[i].score4); 
    tmpscore.push(data[i].score5); 
    tmpscore.push(data[i].score6); 
    tmpscore.push(data[i].score7); 
    tmpscore.push(data[i].score8); 

    var color, done = false;
    while (!done) {
        var test = colorArray[parseInt(Math.random() * 10)];
        if (!test[1]) {
            color = test[0];
            colorArray[colorArray.indexOf(test)][1] = true;
            done = !done;
        }
    }


newDataset = { 
    label: data[i].firstName+' '+data[i].lastName, 
     borderColor: color,
    backgroundColor: "rgba(0,0,0,0)", 
    data: tmpscore, 
}; 

config.data.datasets.push(newDataset); 

} 

LineGraph.update(); 
},  
}); 

});

2 个答案:

答案 0 :(得分:12)

要反转图例标签点击的行为方式,您可以使用图例onClick选项来实现新的点击逻辑。下面是一个示例,它将为您提供所需的行为。请注意,在此实现中,如果您单击已隐藏的标签,它将取消隐藏它,并隐藏所有其他标签。

function(e, legendItem) {
  var index = legendItem.datasetIndex;
  var ci = this.chart;
  var alreadyHidden = (ci.getDatasetMeta(index).hidden === null) ? false : ci.getDatasetMeta(index).hidden;

  ci.data.datasets.forEach(function(e, i) {
    var meta = ci.getDatasetMeta(i);

    if (i !== index) {
      if (!alreadyHidden) {
        meta.hidden = meta.hidden === null ? !meta.hidden : null;
      } else if (meta.hidden === null) {
        meta.hidden = true;
      }
    } else if (i === index) {
      meta.hidden = null;
    }
  });

  ci.update();
};

这也是working example

但是,如果您想要一个更复杂的逻辑,当至少有一个其他标签当前可见时,该逻辑将取消隐藏当前隐藏的标签,那么您可以使用以下实现。

function(e, legendItem) {
  var index = legendItem.datasetIndex;
  var ci = this.chart;
  var alreadyHidden = (ci.getDatasetMeta(index).hidden === null) ? false : ci.getDatasetMeta(index).hidden;       
  var anyOthersAlreadyHidden = false;
  var allOthersHidden = true;

  // figure out the current state of the labels
  ci.data.datasets.forEach(function(e, i) {
    var meta = ci.getDatasetMeta(i);

    if (i !== index) {
      if (meta.hidden) {
        anyOthersAlreadyHidden = true;
      } else {
        allOthersHidden = false;
      }
    }
  });

  // if the label we clicked is already hidden 
  // then we now want to unhide (with any others already unhidden)
  if (alreadyHidden) {
    ci.getDatasetMeta(index).hidden = null;
  } else { 
    // otherwise, lets figure out how to toggle visibility based upon the current state
    ci.data.datasets.forEach(function(e, i) {
      var meta = ci.getDatasetMeta(i);

      if (i !== index) {
        // handles logic when we click on visible hidden label and there is currently at least
        // one other label that is visible and at least one other label already hidden
        // (we want to keep those already hidden still hidden)
        if (anyOthersAlreadyHidden && !allOthersHidden) {
          meta.hidden = true;
        } else {
          // toggle visibility
          meta.hidden = meta.hidden === null ? !meta.hidden : null;
        }
      } else {
        meta.hidden = null;
      }
    });
  }

  ci.update();
}

以下是此替代实施的working example

要在特定代码中使用此功能,只需使用onClick属性将其放入图表的图例配置中。

var config = { 
  type: 'radar', 
  data: chartata,   
  animationEasing: 'linear',
    options: {       
     legend: {
      fontSize: 10,
      display: true,
      itemWidth: 150,
      position: 'bottom',
      fullWidth: true,
      labels: {
        fontColor: 'rgb(0,0,0)',
        boxWidth: 10,
        padding: 20
      },
      onClick: function(e, legendItem) {
        var index = legendItem.datasetIndex;
        var ci = this.chart;
        var alreadyHidden = (ci.getDatasetMeta(index).hidden === null) ? false : ci.getDatasetMeta(index).hidden;

        ci.data.datasets.forEach(function(e, i) {
          var meta = ci.getDatasetMeta(i);

          if (i !== index) {
            if (!alreadyHidden) {
              meta.hidden = meta.hidden === null ? !meta.hidden : null;
            } else if (meta.hidden === null) {
              meta.hidden = true;
            }
          } else if (i === index) {
            meta.hidden = null;
          }
        });

        ci.update();
      },
    },
     tooltips: {
      enabled: true
    },
    scale: {
      ticks: {
        fontSize: 15,
        beginAtZero: true,
        stepSize: 1,
        max: 5
      }
    }
  },
}, 

目前尚不清楚你想要什么样的行为'所有'选项,但可能能够使用legend.labels.generateLabels选项来欺骗Chart.js添加一个' all' label(你必须修改上面的onClick逻辑来处理这个想法。

但是,我认为更好的解决方案是在chart.js画布之外实现自己的链接或按钮,以显示/隐藏所有数据集。查看Chart.js radar sample page,了解它们如何将按钮与图表操作绑定在一起。

答案 1 :(得分:2)

请为饼图尝试此代码以获取单个数据集,以切换chart.js饼图的行为。

onClick:function(e, legendItem){
                var index = legendItem.index;
                var ci = this.chart;
                var meta = ci.getDatasetMeta(0);
                var CurrentalreadyHidden = (meta.data[index].hidden==null) ? false : (meta.data[index].hidden);
                var allShown=true;
                $.each(meta.data,function(ind0,val0){
                    if(meta.data[ind0].hidden){
                        allShown=false;
                        return false; 
                    }else{
                        allShown=true;
                    }
                });
                if(allShown){
                    $.each(meta.data,function(ind,val){
                        if(meta.data[ind]._index===index){
                            meta.data[ind].hidden=false;
                        }else{
                            meta.data[ind].hidden=true;
                        }
                    });
                }else{
                    if(CurrentalreadyHidden){
                        $.each(meta.data,function(ind,val){
                            if(meta.data[ind]._index===index){
                                meta.data[ind].hidden=false;
                            }else{
                                meta.data[ind].hidden=true;
                            }
                        });
                    }else{
                        $.each(meta.data,function(ind,val){
                            meta.data[ind].hidden=false;
                        }); 
                     }
                 }
                ci.update();

            }