那麼,我沒有找到一個很好的解決方案,但我找到了一個。
所以基本上,我對這個問題描述我想創造一個柱狀圖,但我也希望該圖表將有不同的顏色沿着時間......
以下是我解決了這個。
首先我創建並排列顏色,並計算顏色可見的時間百分比。然後我把它的顏色數組,被稱爲「activityGradientArray」
var generateFilteredActivityGradientArray = function(){
var filteredActivityColorWithSpaces = $scope.filteredActivityColorWithSpaces;
//define ratio length
var ratioActivity = (1.0)/filteredActivityColorWithSpaces.length;
var newRatio = 0.0;
var oldRatio = 0.0;
var ratioCounter = 0.0;
var oldColor = "";
var newColor = "";
var colorScheme = [];
for (var i = 0; i < filteredActivityColorWithSpaces.length; i++) {
newColor = filteredActivityColorWithSpaces[i].color;
if (oldColor != newColor) {
colorScheme.push({ratio: ratioCounter, color: newColor});
oldColor = newColor;
oldRatio = newRatio;
}
ratioCounter = ratioCounter + ratioActivity;
}
$scope.activityGradientArray = [];
for (var i = 1; i < colorScheme.length; i++) {
$scope.activityGradientArray.push({ratio: colorScheme[i-1].ratio, color: colorScheme[i-1].color});
$scope.activityGradientArray.push({ratio: colorScheme[i].ratio, color: colorScheme[i-1].color});
}
var lastPosition = colorScheme.length-1;
$scope.activityGradientArray.push({ratio: colorScheme[lastPosition].ratio, color: colorScheme[lastPosition].color});
$scope.activityGradientArray.push({ratio: 1, color: colorScheme[lastPosition].color});
};
然後我延長Chart.controllers.line
,並使用activityGradientArray的梯度應用到chart.chart.ctx
內,使用addColorStop
var chartControllersLine = function(){
return Chart.controllers.line.extend({
update: function() {
if(($scope.filteredChart.temperature.isNull()) && ($scope.filteredChart.activity.isNull())) {
return;
}
// get the min and max values
var minY = Math.min.apply(null, this.chart.data.datasets[$scope.CHART_DATASET_TEMPERATURE].data);
var maxY = Math.max.apply(null, this.chart.data.datasets[$scope.CHART_DATASET_TEMPERATURE].data);
$scope.minYValue = minY;
var yScale = this.getScaleForId(this.getDataset().yAxisID);
var xAxis = this.chart.scales['x-axis-0'];
if((undefined == yScale) || (undefined == xAxis)){
return;
}
var ctx = this.chart.chart.ctx;
// figure out the pixels for these and the value 0
var top = yScale.getPixelForValue(maxY)+5; //add
var bottom = yScale.getPixelForValue(minY)+5;
var left = xAxis.chart.chartArea.left;
var right = xAxis.chart.chartArea.right;
var minimumPixelPosition;
var maximumPixelPosition;
var minimumMarginPixelPosition;
var maximumMarginPixelPosition;
if(($scope.homeConfig.rangeChartMin > minY)){
minimumPixelPosition = yScale.getPixelForValue($scope.homeConfig.rangeChartMin);
} else {
minimumPixelPosition = yScale.getPixelForValue(minY);
}
if(($scope.homeConfig.rangeChartMax < maxY)) {
maximumPixelPosition = yScale.getPixelForValue($scope.homeConfig.rangeChartMax);
} else {
maximumPixelPosition = yScale.getPixelForValue(maxY);
}
var isAllOutside = false;
if((($scope.homeConfig.rangeChartMax > maxY) && ($scope.homeConfig.rangeChartMin > maxY)) ||
(($scope.homeConfig.rangeChartMax < minY) && ($scope.homeConfig.rangeChartMin < minY))) {
isAllOutside = true;
}
var ratioMinimumTemperature = Math.abs(Math.min((minimumPixelPosition - top)/(bottom - top), 1));
var ratioMaximumTemperature = Math.abs(Math.min((maximumPixelPosition - top)/(bottom - top), 1));
var ratioMinimumMarginTemperature = Math.abs(Math.min(((minimumPixelPosition+5) - top)/(bottom - top), 1));
var ratioMaximumMarginTemperature = Math.abs(Math.min(((maximumPixelPosition+5) - top)/(bottom - top), 1));
if(ratioMinimumTemperature < 0)
ratioMinimumTemperature = 0;
if(ratioMinimumTemperature > 1)
ratioMinimumTemperature = 1;
if(ratioMaximumTemperature < 0)
ratioMaximumTemperature = 0;
if(ratioMaximumTemperature > 1)
ratioMaximumTemperature = 1;
if(!$scope.filteredChart.activity.isNull()) {
var gradientActivity = ctx.createLinearGradient(left, 0, right, 0);
for(var i = 0; i<$scope.activityGradientArray.length; i++){
gradientActivity.addColorStop($scope.activityGradientArray[i].ratio, $scope.activityGradientArray[i].color);
}
this.chart.data.datasets[$scope.CHART_DATASET_ACTIVITY].borderColor = gradientActivity;
}
var auxApply = Chart.controllers.line.prototype.update.apply(this, arguments);
return auxApply;
}
});
};
這裏的是我定義數據集的地方:
var lineChartData = function() {
return {
xAxisID: "x-axis-0",
labels: angular.isDefined($scope.filteredChart.labels) ? $scope.filteredChart.labels : [],
datasets: [
{
yAxisID: "y-axis-activity",
label: "Activity",
fill: false,
data: angular.isDefined($scope.filteredChart.activity) ? $scope.filteredChart.activity : [],
borderWidth: 20,
pointRadius: 0,
borderColor: $scope.lineActivityColors,
borderCapStyle: 'butt',
borderDash: [],
borderDashOffset: 0.0,
borderJoinStyle: 'miter',
pointBorderWidth: 0,
pointHoverRadius: 5,
pointHitRadius: 10,
}]
}
};
最後,在我初始化所有ab的圖表Ove方法:
$(document).ready(function() {
var ctx = resetHomeChart();
if(null == ctx)
return;
$scope.pointTemperatureColors = [];
$scope.lineActivityColors = [];
Chart.defaults.NegativeTransparentLine = Chart.helpers.clone(Chart.defaults.line);
Chart.controllers.NegativeTransparentLine = chartControllersLine();
$scope.lineChart = new Chart(ctx, {
data: lineChartData(),
type: 'NegativeTransparentLine',
pointDotRadius: 10,
bezierCurve: false,
scaleShowVerticalLines: false,
scaleGridLineColor: "black",
options: options()
});
var maxTemperature = Math.max.apply(Math, $scope.lineChart.data.datasets[$scope.CHART_DATASET_TEMPERATURE].data.map(function(o) {
return o == null ? -Infinity : o;
}));
var minTemperature = Math.min.apply(Math, $scope.lineChart.data.datasets[$scope.CHART_DATASET_TEMPERATURE].data.map(function(o) {
return o == null ? Infinity : o;
}));
if((Infinity == maxTemperature || -Infinity == maxTemperature) && (Infinity == minTemperature || -Infinity == minTemperature)){
maxTemperature = 0;
minTemperature = 0;
}
var yScaleMaxValue = maxTemperature + 2;
var yScaleMinValue = minTemperature - 4;
$scope.lineChart.options.scales.yAxes[0].ticks.max = Math.floor(yScaleMaxValue);
$scope.lineChart.options.scales.yAxes[1].ticks.max = Math.floor(yScaleMaxValue);
$scope.lineChart.options.scales.yAxes[0].ticks.min = Math.round(yScaleMinValue);
$scope.lineChart.options.scales.yAxes[1].ticks.min = Math.round(yScaleMinValue);
//adjust bar position on the chart
for (var i = 0; i < $scope.lineChart.data.datasets[$scope.CHART_DATASET_ACTIVITY].data.length; i++) {
if(null != $scope.lineChart.data.datasets[$scope.CHART_DATASET_ACTIVITY].data[i]) {
$scope.lineChart.data.datasets[$scope.CHART_DATASET_ACTIVITY].data[i] = yScaleMinValue + 2;
}
}
$scope.lineChart.update();
});
};
再次,這不是一個理想的解決方案。它需要更多的處理比我所期望的,但它的工作原理,但它確實對我來說,至少...
如果有人有更好的解決方案,請分享