如何在chart.js图形中创建间隙?

如何在chart.js图形中创建间隙?,chart.js,Chart.js,这是我需要创建的必需图形。谁能告诉我如何在y轴和x轴的第一个标签(1月份)之间创建间隙 你可以通过创建一个图表插件来实现,就像这样 Chart.plugins.register({ afterUpdate: function(chart) { var dataset = chart.config.data.datasets[0]; var offset = 27; for (var i = 0; i < dataset.data.le

这是我需要创建的必需图形。谁能告诉我如何在y轴和x轴的第一个标签(1月份)之间创建间隙


你可以通过创建一个图表插件来实现,就像这样

Chart.plugins.register({
    afterUpdate: function(chart) {
        var dataset = chart.config.data.datasets[0];
        var offset = 27;
        for (var i = 0; i < dataset.data.length; i++) {
            var model = dataset._meta[0].data[i]._model;
            model.x += offset;
            model.controlPointNextX += offset;
            model.controlPointPreviousX += offset;
        }
    }
});
Chart.plugins.register({
更新后:功能(图表){
var dataset=chart.config.data.datasets[0];
var偏移=27;
对于(var i=0;i
ᴅᴇᴍᴏ

//注册插件
Chart.plugins.register({
更新后:功能(图表){
var dataset=chart.config.data.datasets[0];
var offset=27;//设置最适合
对于(var i=0;i

您可以通过指定刻度的最小值和最大值来创建间隙

在你的例子中,你有X作为时间尺度Y作为线性尺度。因此,每个都有自己的附加选项

如果确定数据的最小值和最大值,则可以向比例范围添加偏移。例如[min-123,max+123],考虑到偏移量为123

我创建了一个使用Chart.js的角度组件。角度分量,因为这似乎是要求。在编辑问题之前,还放置了
angular
标记。如果不需要角度组件,那么在
createChart()
中可以找到重要的逻辑,并且大多数代码与
Chart.js
相关,与角度相关的代码很少

请注意,以下代码是用
TypeScript
编写的,因为这是编写Angular应用程序的推荐方法

依赖关系

      xAxes: [{
        type: 'time',
        position: 'bottom',
        gridLines: {
          display: false
        },
        time: {
          displayFormats: {
            month: 'MMM'
          },
          unit: 'month',
          min: timeXMin,
          max: timeXMax
        },
        ticks: {
          callback: (value, index, values) => {
            const date = values[index];
            console.log(date.diff(xMin, 'months'));
            return date.diff(xMin, 'days') <= 0 || date.diff(xMax, 'days') >= 0 ? null : value;
          }
        }
      }],
      yAxes: [{
        type: 'linear',
        position: 'left',
        gridLines: {
          borderDash: [10, 10],
          zeroLineWidth: 0
        },
        ticks: {
          min: 0,
          fixedStepSize: 200,
          callback: (value) => value === 0 ? null : value
        }
      }]
const ctx = this.canvas.nativeElement.getContext('2d');

// create background linear gradient (top-to-bottom)
const backgroundGradient = ctx.createLinearGradient(this.width / 2, 0, this.width / 2, this.height);
backgroundGradient.addColorStop(0, '#5ebb95');
backgroundGradient.addColorStop(1, 'rgba(255, 255, 255, 0)');

// create default settings that can be used to style the dataset
const defaultDataSetSettings = {
  backgroundColor: backgroundGradient,
  borderColor: '#5ebb95',
  borderWidth: 1,
  pointBackgroundColor: '#5ebb95',
  tension: 0,
  pointBorderWidth: 7,
  pointHoverBorderWidth: 10
};

const data = {
  datasets: this.dataSets.map(dataSet => Object.assign({}, defaultDataSetSettings, dataSet))
};
  • Graph.js:npm安装——保存chart.js
  • Graph.js typings:typings安装--save--global dt~chartjs
  • 时刻:npm安装--保存时刻
图表数据模型

图表数据集建模如下:

export interface GraphDataSet {
  label: string;
  data: { x: any, y: any }[];
}
其中
label
是描述此数据集的标签

数据
是描述x轴和y轴位置的x-y对数组

请注意,一个图表可以有多个数据集。此模型对应于一个数据集。因此,图表组件将接收一组数据集模型

组件

import {AfterViewChecked, Component, ElementRef, Input, OnInit, ViewChild} from '@angular/core';
import 'chart.js';
import Chart from 'chart.js';
import {GraphDataSet} from './GraphDataSet';
import * as moment from 'moment';

@Component({
  selector: 'graph-line',
  template: `<canvas #canvas [width]="width" [height]="height"></canvas>`
})
export class GraphLineComponent implements OnInit, AfterViewChecked {

  private _canvas: ElementRef;
  private _dataSets: GraphDataSet[];
  private _chart: Chart;

  @Input()
  width: number;

  @Input()
  height: number;

  @Input()
  public dataSets: GraphDataSet[];

  @ViewChild('canvas')
  public canvas: ElementRef;

  constructor() {
  }

  ngOnInit() {
  }

  ngAfterViewChecked(): void {
    if (this.canvas !== this._canvas || this.dataSets !== this._dataSets) {
      this._canvas = this.canvas;
      this._dataSets = this.dataSets;
      setTimeout(() => this.createChart(), 0);
    }
  }

  private createChart() {

    const ctx = this.canvas.nativeElement.getContext('2d');

    // create background linear gradient (top-to-bottom)
    const backgroundGradient = ctx.createLinearGradient(this.width / 2, 0, this.width / 2, this.height);
    backgroundGradient.addColorStop(0, '#5ebb95');
    backgroundGradient.addColorStop(1, 'rgba(255, 255, 255, 0)');

    // create default settings that can be used to style the dataset
    const defaultDataSetSettings = {
      backgroundColor: backgroundGradient,
      borderColor: '#5ebb95',
      borderWidth: 1,
      pointBackgroundColor: '#5ebb95',
      tension: 0,
      pointBorderWidth: 7,
      pointHoverBorderWidth: 10
    };

    const data = {
      datasets: this.dataSets.map(dataSet => Object.assign({}, defaultDataSetSettings, dataSet))
    };

    const xMin = this.getXMin(this.dataSets);
    const xMax = this.getXMax(this.dataSets);
    const timeXMin = xMin.subtract(1, 'months');
    const timeXMax = xMax.add(1, 'months');

    this._chart = new Chart(ctx, {
      type: 'line',
      data: data,
      options: {
        responsive: false,
        tooltips: {
          callbacks: {
            title: (item, chartData) => item.map(i => chartData.datasets[i.datasetIndex].label),
            label: (item, chartData) => item.yLabel + ' on ' + moment(item.xLabel).format('LL')
          }
        },
        scales: {
          xAxes: [{
            type: 'time',
            position: 'bottom',
            gridLines: {
              display: false
            },
            time: {
              displayFormats: {
                month: 'MMM'
              },
              unit: 'month',
              min: timeXMin,
              max: timeXMax
            },
            ticks: {
              callback: (value, index, values) => {
                const date = values[index];
                console.log(date.diff(xMin, 'months'));
                return date.diff(xMin, 'days') <= 0 || date.diff(xMax, 'days') >= 0 ? null : value;
              }
            }
          }],
          yAxes: [{
            type: 'linear',
            position: 'left',
            gridLines: {
              borderDash: [10, 10],
              zeroLineWidth: 0
            },
            ticks: {
              min: 0,
              fixedStepSize: 200,
              callback: (value) => value === 0 ? null : value
            }
          }]
        }
      }
    });
  }

  private getXMin(dataSets: GraphDataSet[]) {
    let min: Date = null;

    dataSets.forEach(dataSet => {
      dataSet.data.forEach(data => {
        if (!min || data.x < min) {
          min = data.x;
        }
      });
    });

    return moment(min);
  }

  private getXMax(dataSets: GraphDataSet[]) {
    let max: Date = null;

    dataSets.forEach(dataSet => {
      dataSet.data.forEach(data => {
        if (!max || data.x > max) {
          max = data.x;
        }
      });
    });

    return moment(max);
  }
}
解释 解释::X轴

      xAxes: [{
        type: 'time',
        position: 'bottom',
        gridLines: {
          display: false
        },
        time: {
          displayFormats: {
            month: 'MMM'
          },
          unit: 'month',
          min: timeXMin,
          max: timeXMax
        },
        ticks: {
          callback: (value, index, values) => {
            const date = values[index];
            console.log(date.diff(xMin, 'months'));
            return date.diff(xMin, 'days') <= 0 || date.diff(xMax, 'days') >= 0 ? null : value;
          }
        }
      }],
      yAxes: [{
        type: 'linear',
        position: 'left',
        gridLines: {
          borderDash: [10, 10],
          zeroLineWidth: 0
        },
        ticks: {
          min: 0,
          fixedStepSize: 200,
          callback: (value) => value === 0 ? null : value
        }
      }]
const ctx = this.canvas.nativeElement.getContext('2d');

// create background linear gradient (top-to-bottom)
const backgroundGradient = ctx.createLinearGradient(this.width / 2, 0, this.width / 2, this.height);
backgroundGradient.addColorStop(0, '#5ebb95');
backgroundGradient.addColorStop(1, 'rgba(255, 255, 255, 0)');

// create default settings that can be used to style the dataset
const defaultDataSetSettings = {
  backgroundColor: backgroundGradient,
  borderColor: '#5ebb95',
  borderWidth: 1,
  pointBackgroundColor: '#5ebb95',
  tension: 0,
  pointBorderWidth: 7,
  pointHoverBorderWidth: 10
};

const data = {
  datasets: this.dataSets.map(dataSet => Object.assign({}, defaultDataSetSettings, dataSet))
};
这是一个线性刻度

网格线。borderDash
为线性刻度上的每个刻度创建虚线

ticks.min:0
指定刻度从零开始

ticks.fixedStepSize:200
指定每个刻度刻度的步长为200

ticks.callback
删除0值的标签

说明::组件生命周期

<graph-line [dataSets]="dataSets" [width]="500" [height]="300"></graph-line>
组件具有
宽度
高度
输入,以设置
的大小,这是其模板内的唯一元素

另一个输入是
dataSets
,它是传递到
Chart.js
的实际数据

组件具有
ngAfterViewChecked()
hook,这意味着可以检查更改,如任何输入已更改或
元素因某种原因已更改。如果我们看到一些输入已更改,那么我们将创建如下图表
setTimeout(()=>this.createChart(),0)<之所以使用code>setTimeout()
,是因为此时我们无法更改任何参数,而且为了安全起见,处理是在单独的调用堆栈上完成的

解释::数据

this.dataSets = [
  {
    label: 'My Monthly Report',
    data: [
      {x: Date.parse('2017-01-10'), y: 500},
      {x: Date.parse('2017-02-15'), y: 700},
      {x: Date.parse('2017-03-10'), y: 600},
      {x: Date.parse('2017-04-20'), y: 590},
      {x: Date.parse('2017-05-30'), y: 610},
      {x: Date.parse('2017-06-25'), y: 800}
    ]
  }
];
this.dataSets = [
  {
    label: 'My Monthly Report',
    data: [
      {x: Date.parse('2017-01-10'), y: 500},
      {x: Date.parse('2017-02-15'), y: 700},
      {x: Date.parse('2017-03-10'), y: 600},
      {x: Date.parse('2017-04-20'), y: 590},
      {x: Date.parse('2017-05-30'), y: 610},
      {x: Date.parse('2017-06-25'), y: 800}
    ]
  }
];
因为
X
线性刻度
Y
时间刻度
,所以数据的格式为
{X,Y}
x
是日期类型,
y
是数字
x
y
属性由
Chart.js
识别,并分别分配给
x
y
比例

解释::数据集设置

      xAxes: [{
        type: 'time',
        position: 'bottom',
        gridLines: {
          display: false
        },
        time: {
          displayFormats: {
            month: 'MMM'
          },
          unit: 'month',
          min: timeXMin,
          max: timeXMax
        },
        ticks: {
          callback: (value, index, values) => {
            const date = values[index];
            console.log(date.diff(xMin, 'months'));
            return date.diff(xMin, 'days') <= 0 || date.diff(xMax, 'days') >= 0 ? null : value;
          }
        }
      }],
      yAxes: [{
        type: 'linear',
        position: 'left',
        gridLines: {
          borderDash: [10, 10],
          zeroLineWidth: 0
        },
        ticks: {
          min: 0,
          fixedStepSize: 200,
          callback: (value) => value === 0 ? null : value
        }
      }]
const ctx = this.canvas.nativeElement.getContext('2d');

// create background linear gradient (top-to-bottom)
const backgroundGradient = ctx.createLinearGradient(this.width / 2, 0, this.width / 2, this.height);
backgroundGradient.addColorStop(0, '#5ebb95');
backgroundGradient.addColorStop(1, 'rgba(255, 255, 255, 0)');

// create default settings that can be used to style the dataset
const defaultDataSetSettings = {
  backgroundColor: backgroundGradient,
  borderColor: '#5ebb95',
  borderWidth: 1,
  pointBackgroundColor: '#5ebb95',
  tension: 0,
  pointBorderWidth: 7,
  pointHoverBorderWidth: 10
};

const data = {
  datasets: this.dataSets.map(dataSet => Object.assign({}, defaultDataSetSettings, dataSet))
};
此代码的目的是创建可与数据集关联的默认设置。默认数据集设置使用用户定义的设置进行扩展,如
datasets:this.datasets.map(dataSet=>Object.assign({},defaultDataSetSettings,dataSet))

在设计中,
backgroundColor
是渐变色,因此使用画布上下文
ctx.createLinearGradient(…)
创建从上到下的渐变色