2014-01-21 145 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