Angular Highcharts - 如何动态克隆图表

Angular Highcharts - How to clone chart dynamically

我在本地使用以下 highcharts 依赖项:

这是我的源代码的实时 demo

我在 angular 5 应用程序中大量使用 angular-highcharts。很多时候需要扩展图表(当图表上有很多数据点可见时),为了适应这种情况,我虽然创建了一个通用组件。

这个名为 chart-widget 的组件在 bootstrap 卡片中显示图表,并带有展开图表的选项,在展开时同一图表以模式打开。这个通用组件将处理以模式打开任何图表所需的所有逻辑(可拖动和调整大小)。这样我们就不需要在每个地方都复制相同的功能。

我制作了一个通用组件,过去一切正常,但最近我们升级了我们的 repo 依赖项,因为我们使用的 highcharts 版本中存在一些其他问题,这些问题已在最新版本的 highCharts 中修复,所以我们认为最好升级到最新版本。从那时起,此功能就停止工作了。

以下逻辑用于在模式打开时克隆 chartConfig。然后将克隆的配置传递给驻留在模态内部的扩展图表。但是现在展开的图表现在总是空白。

this.expandChartConfig = new Chart(Object.assign({}, this.chartConfig.options));

其中 chartConfig 是用于呈现图表的正常配置,

expandChartConfig是传递给模式的图表对象。

升级后发现chartConfig.options 属性已经被设为私有了,所以我也试了:

this.expandChartConfig = new Chart(Object.assign({}, this.chartConfig.ref.options));

但这也没有用。

最初我对两个图表使用了相同的配置,但这导致了问题,因为当模态关闭时 highChart 也被破坏了。所以我认为在为模态内的图表打开模态时实例化一个单独的配置是最好的情况。

现在简而言之,我的问题是如何动态克隆现有图表

简而言之,我如何动态克隆现有的高图以及最好的方法是什么?

P.s。我尝试了 Whosebug 上提到的一堆方法,但其中 none 似乎有效。

我也在使用 Highcharts,当我想绘制另一个图表时,我将图表定义为可重用组件,我只是将值传递给 Input() decorattor

在这种情况下你可以使用这样的东西:

图表组件 ts

@Component ({
    selector: 'char-component'
    ...
})
export class CharComponent {
  Input() options: any; 
} 

可重用组件实现

<char-component [options]="firstObject"></char-component>
<char-component [options]="secondObject"></char-component>

要重用代码的组件

export clas Sample implements OnInit {
  ngOninit(){
     firstObject = {...} //Already defined
     secondObject = Object.assign(this.firstObject); //create a copy of this object

  }
}

注意:如果您不知道总共有多少图表,您可以使用包含 options 对象的数组并在模板中绘制,如果您需要另一个图表,只需将其推入数组即可

<char-component *ngfor="option of options" [options]="option "></char-component>

为了达到预期的效果,不幸的是,如果您之前(最初)没有定义系列数据,那么复制chart.options并传递给新的是不够的。在这种情况下,您需要获取数据(来自响应)并将其分配给新的组件变量,然后将其传递给小部件并更新您的系列。以下是操作说明:

在组件中添加新字段:

export class AppComponent {
  chartConfig: Chart;
  chartData: Object;
...

将响应分配给创建的字段:

private setChartData(chartData) {
  const options = this.chartConfig.ref.options;
  if (chartData.categories.length === 0) {
    options.lang.noData = `no data from: ${chartData.customMsgFromDate} to ${chartData.customMsgEndDate}.`;
  } else {
    options.lang.noData = 'No data to display';
  }
this.chartData = chartData;

将数据传递给小部件:

<app-chart-widget [chartConfig]="chartConfig" chartLabel="Title" [chartData]="chartData"></app-chart-widget>

将每个系列的数据添加到新的图表选项中:

onExpandChart(content): void {
  this.expandChartConfig = new Chart(this.chartConfig.ref.options);
  // Clone series data
  this.expandChartConfig.options.series.forEach((s, i) => {
    let name = s.name.toLowerCase()
    s.data = this.chartData[name]
  })

  this.modalService.open(content, { size: 'xl' as 'lg' });
  setTimeout(() => {
    this.resizeChart();
  ...

实例: https://stackblitz.com/edit/highcharts-cloning-chart-bo3tfp

亲切的问候!