2014-01-21 47 views
0

**注:INTRANET基於項目Highcharts - 當數據是動態分配的顏色爲特定值

我工作的項目利用HighCharts生成餅圖。此餅圖的數據是通過使用REST API查詢SharePoint列表動態創建的。我們共有9個圖表以這種方式創建,其中8個圖表應用了篩選器,以將結果縮小到特定組而不是整體。問題是切片的顏色不一致,因爲每次查詢數據並將其組裝到我們的dataArray中時,值的順序都不相同。我們想要嘗試的是爲每個數據點值分配一個顏色,以便顏色保持一致。

例如:

Resource = #123ABC 
Lost Resource = #456DEF 
User Error = #789GHI 

我們會再通過我們的DataArray中需要循環,並應用這些值來餡餅切片,如果它在數據集中的存在。我們的數據是,例如:

[Resource, 81.6],[Lost Resource, 1.0],[User Error, 0.01] 

此外,我們的數據是動態的,所以我們的實際系列的代碼是:

series: [{ 
      type: 'pie', 
      name: chartTitle, 
      data: countArray, 
     }] 

下面是我們正在使用的全碼:

Utility.js文件(將數據處理爲countArray)

"use strict"; 

var EngagementChartBuilder = window.EngagementChartBuilder || {}; 

EngagementChartBuilder.Utilities = function() { 
var buildCategoryCounts = function (countArray, dataArray) { 
    if (countArray == undefined) { 
     countArray = []; 
    } 

    for (var i = 0; i < dataArray.length; i++) { 
     var currValue = parseInt(dataArray[i].hours); 
     var currName = dataArray[i].reason; 
     var found = false; 
     for (var j = 0; j < countArray.length; j++) { 
      if (countArray[j][0] == currName) { 
       found = true; 
       var newCount = countArray[j][1]; 
       countArray[j][1] = newCount + currValue; 
      } 
     } 
     if (!found) { 
      countArray.push([currName, currValue]); 
     } 
    } 

    return countArray; 
}, 

loadPieChart = function (countArray, colorArray, divId, chartTitle) { 
    //Build Pie Chart 
    Highcharts.setOptions({ 
    }) 
    $(divId).highcharts({ 
     chart: { 
      plotBackgroundColor: null, 
      plotBorderWidth: null, 
      plotShadow: false, 
      backgroundColor:'rgba(255, 255, 255, 0.1)' 
     }, 
     credits: { 
      enabled: false 
     }, 
     colors: colorArray, 

     legend: { 
      layout: 'horizontal', 
     }, 
     title: { 
      text: chartTitle 
     }, 
     tooltip: { 
      pointFormat: '<b>{point.y} hours</b>', 
      percentageDecimals: 0 
     }, 
     plotOptions: { 
      pie: { 
       allowPointSelect: true, 
       cursor: 'pointer', 
       dataLabels: { 
        enabled: true, 
        color: '#000000', 
        connectorColor: '#000000', 
        format: '<b>{point.name}</b> {point.percentage:.1f} %' 
       }, 
       showInLegend: true 
      } 
     }, 
     series: [{ 
      type: 'pie', 
      name: chartTitle, 
      data: countArray, 
     }] 
    }); 
} 

ViewModel.js REST QUERY

if (!Array.prototype.filter) { 
Array.prototype.filter = function (fun /*, thisp */) { 
    "use strict"; 

    if (this == null) 
     throw new TypeError(); 

    var t = Object(this); 
    var len = t.length >>> 0; 
    if (typeof fun != "function") 
     throw new TypeError(); 

    var res = []; 
    var thisp = arguments[1]; 
    for (var i = 0; i < len; i++) { 
     if (i in t) { 
      var val = t[i]; // in case fun mutates this 
      if (fun.call(thisp, val, i, t)) 
       res.push(val); 
     } 
    } 

    return res; 
}; 
} 

"use strict"; 

var EngagementChartBuilder = window.EngagementChartBuilder || {}; 

EngagementChartBuilder.EngagementsPieChart_COR = function() { 
var load = function() { 
    $.when(
     //Empire Engagements List 
     EngagementChartBuilder.RESTQuery.execute("QA_TimeMgtPerRelease", "$select=*,ProjectRelease/CALCReportGroup,Reason_x0020_Type,CalculatedSubtotal&$filter=(((Reason_x0020_Type%20ne%20'Weekend%20Hours')%20and%20(Reason_x0020_Type%20ne%20'After%20Hours'))%20and%20(ProjectRelease/CALCReportGroup%20eq%20'COR'))&$top=2000") 
    ).done(
     function (engagements1) { 
      var dataArray = []; 
      var countArray = []; 

      //Get data from Empire Engagements List 
      var results = engagements1.d.results; 
      var filtered = []; 
      for (var i = 0; i < results.length; i++) { 
       if (results[i].ProjectRelease/CALCReportGroup == 'COR') { 
        filtered.push(results[i]); 
       } 
      } 
      for (var i = 0; i < filtered.length; i++) { 
       var reason = filtered[i].Reason_x0020_Type; 
       var hours = filtered[i].CalculatedSubtotal; 
       dataArray[i] = { 'hours': hours, 'reason': reason }; 
      } 

      countArray = EngagementChartBuilder.Utilities.buildCategoryCounts(countArray, dataArray); 

      //Build Chart 
      EngagementChartBuilder.Utilities.loadPieChart CountArray, "#engagementPieChart_COR", "Testing Time vs. Time Lost (COR)"); 
     } 
    ).fail(
     function (engagements1) { 
      $("#engagementPieChart_COR").html("<strong>An error has occurred.</strong>"); 
     } 
    ); 
}; 

return { 
    load: load 
} 
}();  

回答

0

代替使用陣列點,使用對象作爲點,簡單的改變的:

countArray.push([currName, currValue]); 

到:

countArray.push({ name: currName, y: currValue, color: 'red' }); 

和第二更改:

var newCount = countArray[j][1]; 
countArray[j][1] = newCount + currValue; 

到:

var newCount = countArray[j].y; 
countArray[j].y = newCount + currValue; 
+0

好吧,我知道在你的理由。那麼我的問題是,我將如何定義一個顏色到一個特定的名稱?所以基本上如果currName = Resource,那麼它應該總是x顏色。如果currName = User Error,那麼它應該始終是z顏色。 – TFKai

+0

只需創建一個全局映射:'var colorMap = {'User Error':'red','Resource':'green'}',然後使用'countArray.push({name:currName,y:currValue,color:colorMap [currName]});' – Mark

+0

我試圖實現這個,但它並不強制每個currName的顏色一致。沒有什麼實際改變。 – TFKai