在chartjs或ng2-charts中更改悬停和工具提示的样式

时间:2017-09-12 08:13:21

标签: chart.js ng2-charts

有没有办法改变悬停的样式以及使用chartjs或ng2-charts的工具提示?我想隐藏悬停点,只有当我将鼠标悬停在它们上时才会显示它们,并将指示符作为行。这是我想要构建的确切图表模型:

https://interactive-bitcoin-price-chart-foxkmkynmg.now.sh/

提前感谢您的提示。

编辑:我按照GRUNT的说明将此图表选项应用到我的Angular应用程序中,只要我悬停,整个图表就会显示工具提示,但行跟踪指示符不是。这是我的代码:

插件-hoverline.ts:

export class PluginHoverline {
   posX: null;
   isMouseOut:boolean = false;

   drawLine(chart, posX) {
      const ctx = chart.ctx,
         x_axis = chart.scales['x-axis-0'],
         y_axis = chart.scales['y-axis-0'],
         x = posX,
         topY = y_axis.top,
         bottomY = y_axis.bottom;
      if (posX < x_axis.left || posX > x_axis.right) return;
      // draw line
      ctx.save();
      ctx.beginPath();
      ctx.moveTo(x, topY);
      ctx.lineTo(x, bottomY);
      ctx.lineWidth = chart.options.lineOnHover.lineWidth;
      ctx.strokeStyle = chart.options.lineOnHover.lineColor;
      ctx.stroke();
      ctx.restore();
   };

   beforeInit(chart) {
      chart.options.events.push('mouseover');
   };

   afterEvent(chart, event) {
      if (!chart.options.lineOnHover || !chart.options.lineOnHover.enabled) return;
      if (event.type !== 'mousemove' && event.type !== 'mouseover') {
         if (event.type === 'mouseout') this.isMouseOut = true;
         chart.clear();
         chart.draw();
         return;
      }
      this.posX = event.x;
      this.isMouseOut = false;
      chart.clear();
      chart.draw();
      this.drawLine(chart, this.posX);

      var metaData = chart.getDatasetMeta(0).data,
         radius = chart.data.datasets[0].pointHoverRadius,
         posX = metaData.map(e => e._model.x);
      posX.forEach(function(pos, posIndex) {
         if (this.posX < pos + radius && this.posX > pos - radius) {
            chart.updateHoverStyle([metaData[posIndex]], null, true);
            chart.tooltip._active = [metaData[posIndex]];
         } else chart.updateHoverStyle([metaData[posIndex]], null, false);
      }.bind(this));
      chart.tooltip.update();
   };

   afterDatasetsDraw(chart, ease) {
      if (!this.posX) return;
      if (!this.isMouseOut) this.drawLine(chart, this.posX);
   };
}

banner.component.ts :(图表组件)

import { Component, OnInit } from '@angular/core';
import { HistoricalBpiService } from '../../services/historical-bpi.service';
import { PluginHoverline } from './plugin-hoverline';

@Component({
  selector: 'app-banner',
  templateUrl: './banner.component.html',
  styleUrls: ['./banner.component.scss']
})
export class BannerComponent implements OnInit {

  private dataUrl: string = 'historical/close.json';

  constructor(
    private historicalBpiService:HistoricalBpiService
  ) {}

  // lineChart
  public lineChartData:any = [
    { data:[], label: 'Bitcoin price' }
  ];

  public lineChartLabels:Array<any> = [];

  public lineChartOptions:any = {
    responsive: true,
    maintainAspectRatio: false,
    layout: {
      padding: 0
    },
    lineOnHover: {
     enabled: true,
     lineColor: '#bbb',
     lineWidth: 1
   },
    scales: {
      yAxes: [{
        display: true,
        scaleLabel: {
          display: false,
          labelString: 'USD'
        },
        ticks: {
          display: false
        },
        gridLines: {
          display: true,
          tickMarkLength: 0
        }
      }],
      xAxes: [{
        ticks: {
          display: false
        },
        gridLines: {
          display: false,
          tickMarkLength: 0
        }
      }]
    },
    elements: {
      point: {
        radius: 3
      },
      line: {
        tension: 0.4, // 0 disables bezier curves
      }
    },
    hover: {
      mode: 'nearest',
      intersect: false
    },
    tooltips: {
      mode: 'nearest',
      intersect: false,
      backgroundColor: 'rgb(95,22,21)',
      callbacks: {
        label: function (tooltipItems, data) {
          return data.datasets[tooltipItems.datasetIndex].label + ' : ' + '$' + tooltipItems.yLabel.toLocaleString();
        },
        labelColor: function(tooltipItem, chart) {
          var dataset = chart.config.data.datasets[tooltipItem.datasetIndex];
          return {
            backgroundColor : dataset.backgroundColor
          }
        }
      }
    }
  };
  public lineChartColors:Array<any> = [
    {
      backgroundColor: 'rgba(199,32,48,0.8',
      borderColor: 'rgb(95,22,21);',
      pointBackgroundColor: 'rgba(218,208,163,0.8)',
      pointHoverBackgroundColor: 'rgba(218,208,163,0.8)',
      pointHoverBorderColor: 'rgb(218,208,163)',
      pointHoverRadius: 6,
      steppedLine: false

    }
  ];
  public lineChartLegend:boolean = false;
  public lineChartType:string = 'line';


  // events
  public chartClicked(e:any):void {
    console.log(e);
  }

  public chartHovered(e:any):void {
    console.log(e);
  }

  ngOnInit(){
    this.historicalBpiService.getBpiData(this.dataUrl)
      .subscribe(
        res => {
          //this.lineChartData = Object.keys(res.bpi).map(function (key) { return res.bpi[key];});
          this.lineChartData[0].data = Object.values(res.bpi);
          this.lineChartLabels = Object.keys(res.bpi);
          //console.log(this.lineChartData,this.lineChartLabels);
        }
      )
  }
}

模板:

<div class="chart">
      <canvas baseChart height="360px"
        [datasets]="lineChartData"
        [labels]="lineChartLabels"
        [options]="lineChartOptions"
        [colors]="lineChartColors"
        [legend]="lineChartLegend"
        [chartType]="lineChartType"
        (chartHover)="chartHovered($event)"
        (chartClick)="chartClicked($event)"></canvas>
    </div>

2 个答案:

答案 0 :(得分:1)

不幸的是,目前还没有内置功能。但是,您可以使用this图表插件(一旦为自己的目的而创建)来实现您的目标。

要使用该插件,请在图表选项配置中设置以下选项:

lineOnHover: {
   enabled: true,
   lineColor: '#bbb',
   lineWidth: 1
}

另外,请确保为数据集设置以下属性:

pointRadius: 0,
pointHoverRadius: 5,
pointHoverBackgroundColor: 'white'

请参阅 - live demo

答案 1 :(得分:0)

此答案是建立在GRUNT's answer above之上,以便能够显示其多线图:


只需更改以下内容(在他提供的here代码段中):

posX.forEach(function(pos, posIndex) {
  if (this.posX < pos + radius && this.posX > pos - radius) {
    chart.updateHoverStyle([metaData[posIndex]], null, true);
    chart.tooltip._active = [metaData[posIndex]];
  } else chart.updateHoverStyle([metaData[posIndex]], null, false);
}.bind(this));

收件人:

posX.forEach(function(pos, posIndex) {
  var metaDatum = []
  if (this.posX < pos + radius && this.posX > pos - radius) {
    chart.data.datasets.forEach((dataset, ind) => {
      metaDatum.push(chart.getDatasetMeta(ind).data[posIndex]);
    })

    chart.updateHoverStyle(metaDatum, null, true);
    chart.tooltip._active = metaDatum;
  } else {
    metaDatum.push(metaData[posIndex]);
    chart.updateHoverStyle(metaDatum, null, false);
  }
}.bind(this));