首页 文章

Angular Highcharts - 如何动态克隆图表

提问于
浏览
0

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

  • "angular-highcharts":"latest"

  • "highcharts":"latest"

  • "@types/highcharts":"latest"

这是我的源码的实时demo

我在角度5应用程序中广泛使用角度高图 . 很多时候需要扩展图表(当图表上有很多数据点可见时),以适应这种情况我创建一个通用组件 .

这个名为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也被销毁 . 因此,我想在模式内打开模态时实例化一个单独的配置是最好的情况 .

所以现在用简单的话说我的问题是 how can I clone an existing chart, dynamically .

  • 此功能在许多地方都是必需的,因此我无法在每个地方维护单独的图表对象 .

  • 此外,图表上还有很多操作,例如setData,setCategories,addSeries,removeSeries,update e.t.c.这就是为什么不建议在每次操作时维护副本并更新它们 . 此外,这些操作将由父组件执行,因此ChartWidgetComponent在执行时无法识别此类更改 .

那么简而言之,我如何动态克隆现有的高图,还有最好的方法?

附:我尝试了一些在stackOverflow上提到的方法,但它们似乎都没有工作 .

2 回答

  • 0

    我也使用Highcharts,我已经将图表定义为可重用的组件,而我想要绘制另一个图表我只是通过 Input() decorattor传递值

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

    Chart Component ts

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

    Reusable Component implementation

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

    Component to Reusecode

    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>
    
  • 1

    为了达到预期的效果,遗憾的是,如果您之前(最初)没有定义系列数据,则复制 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();
      ...
    

    Live example: https://stackblitz.com/edit/highcharts-cloning-chart-bo3tfp

    亲切的问候!

相关问题