2017-03-02 28 views
1

我有一個來自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(); 
}, 
}); 

}); 

回答

3

爲了扭轉圖例標籤點擊的行爲,你可以使用傳說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之添加一個「全部」標籤(你會必須修改上述onClick邏輯來處理這個想法

但是,我認爲一個更好的解決方案是在chart.js畫布之外實現自己的鏈接或按鈕,以顯示/隱藏所有數據集。 Chart.js radar sample page來看看它們如何將按鈕與圖表動作綁定在一起。

+0

首先感謝您解釋得很好的答案。我可以看到你明白我的需求。我需要從這個例子中唯一需要的是,當您選擇一個標籤時,它將刪除所有其他標籤並僅顯示所選標籤,如果您繼續點擊另一個標籤,則會添加該標籤,而不是刪除原始點擊的標籤並將其替換與新的點擊。我唱唱chart.js是相當新的,所以它有點混亂。 – PhpDude

+0

啊,好的......我不確定你想怎麼處理這個問題。稍後當我到達計算機時,我會更新我的答案。 – jordanwillis

+0

阿布里爾謝謝。你可以在上面顯示我的代碼嗎? – PhpDude