Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/403.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 角度图JS-根据点和x27具有不同填充颜色的折线图;范围_Javascript_Angularjs_Chart.js_Angular Chart - Fatal编程技术网

Javascript 角度图JS-根据点和x27具有不同填充颜色的折线图;范围

Javascript 角度图JS-根据点和x27具有不同填充颜色的折线图;范围,javascript,angularjs,chart.js,angular-chart,Javascript,Angularjs,Chart.js,Angular Chart,我在我的网站上使用Angular Chart js来显示一些类型的图形,其中一种是折线图 我希望折线图是彩色填充的,但根据y轴的值使用不同的颜色。如图所示: 我尝试在图形的“数据”数组中使用不同的数据数组,第一个数组包含所有值,第二个数组包含除绿色(右侧)外的所有值,第三个数组是相同的数组,直到紫色范围等,然后每个数据集都有自己的颜色,但最终我得到了一个根据最后一个数据集颜色的单一颜色的图形 我错过了什么?有没有办法做到这一点 谢谢。很遗憾,使用当前的chart.js配置选项无法实现这一点。原

我在我的网站上使用Angular Chart js来显示一些类型的图形,其中一种是折线图

我希望折线图是彩色填充的,但根据y轴的值使用不同的颜色。如图所示:

我尝试在图形的“数据”数组中使用不同的数据数组,第一个数组包含所有值,第二个数组包含除绿色(右侧)外的所有值,第三个数组是相同的数组,直到紫色范围等,然后每个数据集都有自己的颜色,但最终我得到了一个根据最后一个数据集颜色的单一颜色的图形

我错过了什么?有没有办法做到这一点


谢谢。

很遗憾,使用当前的chart.js配置选项无法实现这一点。原因是因为折线图
backgroundColor
选项(控制折线图填充颜色的选项)只接受一个值

在深入研究当前的chart.js 2.5源代码后,我发现可以扩展line元素的
draw()
方法,并强制chart.js使用画布线性渐变来填充(而不仅仅是单一颜色)。通过一点数学运算,我们可以将每个点的x位置转换为线性渐变色停止位置并构建渐变

通过此增强功能,您现在可以将一组颜色传递到折线图
backgroundColor
选项,以实现不同颜色的填充区域。下面是一个结果图表的示例

下面是实际操作方法(底部有一个工作示例)

首先,我们必须扩展
Chart.elements.Line
并覆盖它的
draw()
方法,以便我们可以基于每个点的位置构建线性渐变,将其用作直线填充,然后绘制直线

// save the original line element so we can still call it's 
// draw method after we build the linear gradient
var origLineElement = Chart.elements.Line;

// define a new line draw method so that we can build a linear gradient
// based on the position of each point
Chart.elements.Line = Chart.Element.extend({
  draw: function() {
    var vm = this._view;
    var backgroundColors = this._chart.controller.data.datasets[this._datasetIndex].backgroundColor;
    var points = this._children;
    var ctx = this._chart.ctx;
    var minX = points[0]._model.x;
    var maxX = points[points.length - 1]._model.x;
    var linearGradient = ctx.createLinearGradient(minX, 0, maxX, 0);

    // iterate over each point to build the gradient
    points.forEach(function(point, i) {
      // `addColorStop` expects a number between 0 and 1, so we
      // have to normalize the x position of each point between 0 and 1
      // and round to make sure the positioning isn't too percise 
      // (otherwise it won't line up with the point position)
      var colorStopPosition = roundNumber((point._model.x - minX) / (maxX - minX), 2);

      // special case for the first color stop
      if (i === 0) {
        linearGradient.addColorStop(0, backgroundColors[i]);
      } else {
        // only add a color stop if the color is different
        if (backgroundColors[i] !== backgroundColors[i-1]) {
          // add a color stop for the prev color and for the new color at the same location
          // this gives a solid color gradient instead of a gradient that fades to the next color
          linearGradient.addColorStop(colorStopPosition, backgroundColors[i - 1]);
          linearGradient.addColorStop(colorStopPosition, backgroundColors[i]);
        }
      }
    });

    // save the linear gradient in background color property
    // since this is what is used for ctx.fillStyle when the fill is rendered
    vm.backgroundColor = linearGradient;

    // now draw the lines (using the original draw method)
    origLineElement.prototype.draw.apply(this);
  }               
});
然后,我们还必须扩展折线图,以确保图表使用的线元素是我们在上面扩展的元素(因为此属性在加载时已设置)

完成此操作后,我们现在可以将一组颜色传递到折线图
backgroundColor
属性(而不仅仅是单个值)以控制线条填充

下面是一个例子,演示了所有讨论过的内容

注意事项:

  • 这种方法可能会在将来的chart.js版本中出现,因为我们正在处理内部问题
  • 我不熟悉,因此无法提供有关如何将上述chart.js更改集成到angular指令中的见解

不幸的是,使用当前的chart.js配置选项无法实现这一点。原因是因为折线图
backgroundColor
选项(控制折线图填充颜色的选项)只接受一个值

在深入研究当前的chart.js 2.5源代码后,我发现可以扩展line元素的
draw()
方法,并强制chart.js使用画布线性渐变来填充(而不仅仅是单一颜色)。通过一点数学运算,我们可以将每个点的x位置转换为线性渐变色停止位置并构建渐变

通过此增强功能,您现在可以将一组颜色传递到折线图
backgroundColor
选项,以实现不同颜色的填充区域。下面是一个结果图表的示例

下面是实际操作方法(底部有一个工作示例)

首先,我们必须扩展
Chart.elements.Line
并覆盖它的
draw()
方法,以便我们可以基于每个点的位置构建线性渐变,将其用作直线填充,然后绘制直线

// save the original line element so we can still call it's 
// draw method after we build the linear gradient
var origLineElement = Chart.elements.Line;

// define a new line draw method so that we can build a linear gradient
// based on the position of each point
Chart.elements.Line = Chart.Element.extend({
  draw: function() {
    var vm = this._view;
    var backgroundColors = this._chart.controller.data.datasets[this._datasetIndex].backgroundColor;
    var points = this._children;
    var ctx = this._chart.ctx;
    var minX = points[0]._model.x;
    var maxX = points[points.length - 1]._model.x;
    var linearGradient = ctx.createLinearGradient(minX, 0, maxX, 0);

    // iterate over each point to build the gradient
    points.forEach(function(point, i) {
      // `addColorStop` expects a number between 0 and 1, so we
      // have to normalize the x position of each point between 0 and 1
      // and round to make sure the positioning isn't too percise 
      // (otherwise it won't line up with the point position)
      var colorStopPosition = roundNumber((point._model.x - minX) / (maxX - minX), 2);

      // special case for the first color stop
      if (i === 0) {
        linearGradient.addColorStop(0, backgroundColors[i]);
      } else {
        // only add a color stop if the color is different
        if (backgroundColors[i] !== backgroundColors[i-1]) {
          // add a color stop for the prev color and for the new color at the same location
          // this gives a solid color gradient instead of a gradient that fades to the next color
          linearGradient.addColorStop(colorStopPosition, backgroundColors[i - 1]);
          linearGradient.addColorStop(colorStopPosition, backgroundColors[i]);
        }
      }
    });

    // save the linear gradient in background color property
    // since this is what is used for ctx.fillStyle when the fill is rendered
    vm.backgroundColor = linearGradient;

    // now draw the lines (using the original draw method)
    origLineElement.prototype.draw.apply(this);
  }               
});
然后,我们还必须扩展折线图,以确保图表使用的线元素是我们在上面扩展的元素(因为此属性在加载时已设置)

完成此操作后,我们现在可以将一组颜色传递到折线图
backgroundColor
属性(而不仅仅是单个值)以控制线条填充

下面是一个例子,演示了所有讨论过的内容

注意事项:

  • 这种方法可能会在将来的chart.js版本中出现,因为我们正在处理内部问题
  • 我不熟悉,因此无法提供有关如何将上述chart.js更改集成到angular指令中的见解

如果您想在angular2和ng2图表中使用此功能,可能有一种“黑客”较少的方法来实现此功能,但这就是我能够应用Jordan代码使其工作的方式:

  • 将ng2图表对chart.js的依赖性从2.7.x降级到2.5。
    -从项目目录:npm install chart。js@2.5--保存
  • 在节点_模块/chart.js/src/charts内: -在Chart.line函数之后,将Jordan的代码添加到Chart.line.js(导出内部)
  • 重建Chart.js/dist: -运行npm安装
  • 大口喘气
  • 如果您从socket.io代码中得到错误,那么您需要将这些依赖项升级到socket.io的更新版本,我相信Karma可能有一个旧版本的socket.io,您可以升级到2.0

  • 不管怎么说,这对我很有效。它还没有完全测试过,而且肯定是一个“黑客”,但我不想学习Chart.js2.7来找出Jordan的代码为什么不能与它一起工作。这绝对是更“合适”的方法。我想它应该集成为一个“插件”

    如果您想在angular2和ng2图表上使用此功能,可能有一种“黑客”较少的方法,但我就是这样应用Jordan的代码使其工作的:

  • 将ng2图表对chart.js的依赖性从2.7.x降级到2.5。
    -从项目目录:npm install ch
        // save the original line element so we can still call it's 
        // draw method after we build the linear gradient
        var origLineElement = Chart.elements.Line;
    
        // define a new line draw method so that we can build a linear gradient
        // based on the position of each point
        Chart.elements.Line = Chart.Element.extend({
          draw: function() {
            var vm = this._view;
            var backgroundColors = this._chart.controller.data.datasets[this._datasetIndex].backgroundColor;
            var points = this._children;
            var ctx = this._chart.ctx;
            var minX = points[0]._model.x;
            var maxX = points[points.length - 1]._model.x;
            var linearGradient = ctx.createLinearGradient(minX, 0, maxX, 0);
    
        // if not a single color
        if( typeof backgroundColors != 'string' ){          
          // but is array of colors
          if( typeof backgroundColors[0] === 'string' ) { 
            // iterate over each point to build the gradient 
            points.forEach(function(point, i) { // start original code
              // `addColorStop` expects a number between 0 and 1, so we
              // have to normalize the x position of each point between 0 and 1
              // and round to make sure the positioning isn't too percise 
              // (otherwise it won't line up with the point position)
              var colorStopPosition = self.roundNumber((point._model.x - minX) / (maxX - minX), 2);
              // special case for the first color stop
              if (i === 0) {
                linearGradient.addColorStop(0, backgroundColors[i]);
              } else {
                // only add a color stop if the color is different
                if ( backgroundColors[i] !== backgroundColors[i-1]) {
                  // add a color stop for the prev color and for the new color at the same location
                  // this gives a solid color gradient instead of a gradient that fades to the next color
                  linearGradient.addColorStop(colorStopPosition, backgroundColors[i - 1]);
                  linearGradient.addColorStop(colorStopPosition, backgroundColors[i]);
                }
              }
            });  // end original code
          }  // end  of if for color array
          // must be a gradient fence position list
          else {
            // loop thru the fence positions
            backgroundColors.forEach(function(fencePosition){
                var colorStopPosition = self.roundNumber(fencePosition.offset / points.length, 2);
                linearGradient.addColorStop(colorStopPosition,fencePosition.color)
            });
          }  // end of block for handling color space edges
    
        // save the linear gradient in background color property
        // since this is what is used for ctx.fillStyle when the fill is rendered
        vm.backgroundColor = linearGradient;
    
        }  // end of if for just one color 
    
        // now draw the lines (using the original draw method)
        origLineElement.prototype.draw.apply(this);
      }