Nun, ich habe keine gute Lösung gefunden, aber ich habe eine gefunden.
Also im Grunde, wie ich auf der Frage beschrieben wollte ich ein Balkendiagramm erstellen, aber ich wollte auch, dass das Diagramm verschiedene Farben entlang der Zeit haben würde ...
Hier ist, wie ich dieses Problem gelöst.
Zuerst erstelle ich und Array von Farben, und berechnen Sie den Prozentsatz der Zeit, die eine Farbe sichtbar wäre. Und dann habe ich es in einer Reihe von Farben, die so genannten „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});
};
Dann erweitere ich die Chart.controllers.line
und die activityGradientArray verwenden, um einen Gradienten auf die chart.chart.ctx
anzuwenden, mit 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;
}
});
};
Hier ist, wo ich den Datensatz definieren:
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,
}]
}
};
Und schließlich, wo ich das Diagramm mit allen ab initialisieren ove Methoden:
$(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();
});
};
Auch dies ist keine ideale Lösung. Es dauert ein bisschen mehr Verarbeitung, als ich erwartet hätte, aber es funktioniert, zumindest hat es für mich getan ...
Wenn jemand eine bessere Lösung hätte, teilen Sie es bitte