음, 좋은 해결책을 찾지 못했지만 발견했습니다. 내가 질문에 설명 된대로
그래서 기본적으로, 나는 막대 차트를 만들고 싶었 그러나 나는 또한 차트
여기 내가 이것을 해결하는 방법은 ... 시간에 따라 서로 다른 색상을 가지고 것을 원했다.
먼저 색상을 만들고 배열하고 색상을 볼 수있는 시간의 백분율을 계산합니다. 그리고 나는 여기 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 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
을 확장하고 chart.chart.ctx
에 그라디언트를 적용 할 activityGradientArray을 사용하여 "activityGradientArray"라는 색상의 배열 안에 넣어 여기에 데이터 세트를 정의하는 곳이 있습니다 :
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,
}]
}
};
그리고 마지막으로 모든 차트를 방법 :
$(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();
});
};
다시 말하지만 이상적인 해결책은 아닙니다. 예상했던 것보다 약간의 처리가 필요하지만 적어도 저에게는 효과적이었습니다 ...
더 좋은 해결책이 있다면 누구나