简体   繁体   English

放大 AMCharts 时丢失 Timeserie

[英]Loosing a Timeserie when zooming in AMCharts

When I am zooming in the graph, the serie2 disappears...also if I zoom by picking the cursor from the right....BUT from the left the zoom is working fine !!当我放大图表时,serie2 消失了……如果我通过从右侧选择 cursor 进行缩放……但从左侧缩放工作正常!

I am expecting to see the 2 series in any cases but it seems that sometimes it's not...我希望在任何情况下都能看到 2 系列,但似乎有时不是……

See my screenshot看我的截图

Any idea why?知道为什么吗?

My component looks like this:我的组件如下所示:

import { Component, NgZone, OnDestroy, OnInit } from '@angular/core';
import * as am4core from '@amcharts/amcharts4/core';
import * as am4charts from '@amcharts/amcharts4/charts';
import am4themes_animated from '@amcharts/amcharts4/themes/animated';
import {DayAheadService} from '../../_services/day-ahead.service';
import { Subscription } from 'rxjs';

am4core.useTheme(am4themes_animated);

@Component({
  providers: [DayAheadService],
  selector: 'app-max',
  templateUrl: './maximize.component.html',
  styleUrls: ['./maximize.component.scss']
})
export class MaximizeComponent implements OnDestroy {
  private chart: am4charts.XYChart;
  private subscription: Subscription;
  clearingsSell: any = [];
  clearingsBuy: any = [];
  constructor(
    private dayAheadService: DayAheadService,
    private zone: NgZone) {}

    ngOnInit() {

    }

    ngAfterViewInit() {
    this.zone.runOutsideAngular(() => {
      let chart = am4core.create('chartdiv', am4charts.XYChart);
      chart.paddingRight = 20;
      let data1 = [];
      let data2 = [];
      this.subscription = this.dayAheadService.requestAggClearingsMada('2019-01-01', 'asset' , '2019-01-19' ).subscribe(x => {
        this.clearingsSell = x.filter(f => f.direction === 'Sell');
        this.clearingsBuy = x.filter(f => f.direction === 'Buy');
        for (let i = 1; i < this.clearingsSell.length; i++) {
          for (let j = 0; j < 24; j++) {
              data1.push({ category : 'Sell', date: new Date(2019, 0, i, j).setHours(j), value1: this.clearingsSell[i].profilesData[j].price });
          }
        }
        for (let i = 1; i < this.clearingsBuy.length; i++) {
          for (let j = 0; j < 24; j++) {
              data2.push({ category : 'Buy', date: new Date(2019, 0, i, j).setHours(j), value2: this.clearingsBuy[i].profilesData[j].price });
          }
        }
        chart.data = data1.concat(data2);
        console.log(chart.data);
        });

        chart.dateFormatter.inputDateFormat = 'YY-MM-DD HH';
        const dateAxis = chart.xAxes.push(new am4charts.DateAxis());
        dateAxis.renderer.minGridDistance = 90;
        dateAxis.startLocation = 0.5;
        dateAxis.endLocation = 0.5;
        const valueAxis = chart.yAxes.push(new am4charts.ValueAxis());
        valueAxis.tooltip.disabled = true;
        const series = chart.series.push(new am4charts.StepLineSeries());
        series.dataFields.dateX = 'date';
        series.name = 'Sell Vol.';
        series.dataFields.valueY = 'value1';
        series.tooltipText = '[#000]{valueY.value}[/]';
        series.tooltip.background.fill = am4core.color('#FFF');
        series.tooltip.getStrokeFromObject = true;
        series.tooltip.background.strokeWidth = 3;
        series.tooltip.getFillFromObject = false;
        series.fillOpacity = 0.6;
        series.strokeWidth = 2;
        series.stacked = true;
        const series2 = chart.series.push(new am4charts.StepLineSeries());
        series2.name = 'Buy Vol.';
        series2.dataFields.dateX = 'date';
        series2.dataFields.valueY = 'value2';
        series2.tooltipText = '[#000]{valueY.value}[/]';
        series2.tooltip.background.fill = am4core.color('#FFF');
        series2.tooltip.getFillFromObject = false;
        series2.tooltip.getStrokeFromObject = true;
        series2.tooltip.background.strokeWidth = 3;
        series2.sequencedInterpolation = true;
        series2.fillOpacity = 0.6;
        series2.stacked = true;
        series2.strokeWidth = 2;
        // Add scrollbar
        chart.scrollbarX = new am4charts.XYChartScrollbar();
        // Add cursor
        chart.cursor = new am4charts.XYCursor();
        chart.cursor.xAxis = dateAxis;
        chart.cursor.snapToSeries = series;
        // Add a legend
        chart.legend = new am4charts.Legend();
        chart.legend.position = 'top';
    });
  }

  ngOnDestroy() {
    this.subscription.unsubscribe();
    this.zone.runOutsideAngular(() => {
      if (this.chart) {
        this.chart.dispose();
      }
    });
  }
}

AmCharts expects date-based data to be grouped by date, not concatenated, otherwise you'll run into undefined behavior, such as your zooming issue. AmCharts 期望基于日期的数据按日期分组,而不是串联,否则您将遇到未定义的行为,例如缩放问题。 You'll need to rewrite your subscribe method to aggregate everything correctly:您需要重写您的 subscribe 方法以正确聚合所有内容:

clearingsSell = x.filter(f => f.direction === "Sell");
clearingsBuy = x.filter(f => f.direction === "Buy");
//store everything into an object with the date as the key
for (let i = 1; i < clearingsSell.length; i++) {
  for (let j = 0; j < 24; j++) {
    let date = new Date(2019, 0, i, j).setHours(j);
    data[date] = {
      date: date,
      value1: clearingsSell[i].profilesData[j].price
    }
  }
}
for (let i = 1; i < clearingsBuy.length; i++) {
  for (let j = 0; j < 24; j++) {
    let date = new Date(2019, 0, i, j).setHours(j);
    if (data[date] === undefined) {
      data[date] = {date: date};
    }
    data[date].value2 = clearingsBuy[i].profilesData[j].price
  }
}
//convert grouped data into array, iterating by date
chart.data = Object.keys(data).map(function(date) { 
  return data[date];
})

Note that I removed the categories as they didn't appear to be relevant to your chart setup.请注意,我删除了这些类别,因为它们似乎与您的图表设置无关。 Here's a simplified demo based off your code:这是基于您的代码的简化演示:

 let chart = am4core.create("chartdiv", am4charts.XYChart); chart.paddingRight = 20; let data = {}; let data1 = []; let data2 = []; x = getData(); //--- modified subscribe code --- clearingsSell = x.filter(f => f.direction === "Sell"); clearingsBuy = x.filter(f => f.direction === "Buy"); //store everything into an object with the date as the key for (let i = 1; i < clearingsSell.length; i++) { for (let j = 0; j < 24; j++) { let date = new Date(2019, 0, i, j).setHours(j); data[date] = { date: date, value1: clearingsSell[i].profilesData[j].price } } } for (let i = 1; i < clearingsBuy.length; i++) { for (let j = 0; j < 24; j++) { let date = new Date(2019, 0, i, j).setHours(j); if (data[date] === undefined) { data[date] = {date: date}; } data[date].value2 = clearingsBuy[i].profilesData[j].price } } //convert grouped data into array, iterating by date chart.data = Object.keys(data).map(function(date) { return data[date]; }); // --- end modified subscribe code -- chart.dateFormatter.inputDateFormat = "YY-MM-DD HH"; const dateAxis = chart.xAxes.push(new am4charts.DateAxis()); dateAxis.renderer.minGridDistance = 90; dateAxis.startLocation = 0.5; dateAxis.endLocation = 0.5; const valueAxis = chart.yAxes.push(new am4charts.ValueAxis()); valueAxis.tooltip.disabled = true; const series = chart.series.push(new am4charts.StepLineSeries()); series.dataFields.dateX = "date"; series.name = "Sell Vol."; series.dataFields.valueY = "value1"; series.tooltipText = "[#000]{valueY.value}[/]"; series.tooltip.background.fill = am4core.color("#FFF"); series.tooltip.getStrokeFromObject = true; series.tooltip.background.strokeWidth = 3; series.tooltip.getFillFromObject = false; series.fillOpacity = 0.6; series.strokeWidth = 2; series.stacked = true; const series2 = chart.series.push(new am4charts.StepLineSeries()); series2.name = "Buy Vol."; series2.dataFields.dateX = "date"; series2.dataFields.valueY = "value2"; series2.tooltipText = "[#000]{valueY.value}[/]"; series2.tooltip.background.fill = am4core.color("#FFF"); series2.tooltip.getFillFromObject = false; series2.tooltip.getStrokeFromObject = true; series2.tooltip.background.strokeWidth = 3; series2.sequencedInterpolation = true; series2.fillOpacity = 0.6; series2.stacked = true; series2.strokeWidth = 2; // Add scrollbar chart.scrollbarX = new am4charts.XYChartScrollbar(); // Add cursor chart.cursor = new am4charts.XYCursor(); chart.cursor.xAxis = dateAxis; chart.cursor.snapToSeries = series; // Add a legend chart.legend = new am4charts.Legend(); chart.legend.position = "top"; function getData() { return [ { direction: "Buy", profilesData: [ { price: 14 }, { price: 12 }, { price: 16 }, { price: 13 }, { price: 10 }, { price: 10 }, { price: 18 }, { price: 13 }, { price: 17 }, { price: 12 }, { price: 18 }, { price: 10 }, { price: 10 }, { price: 17 }, { price: 17 }, { price: 20 }, { price: 13 }, { price: 17 }, { price: 13 }, { price: 12 }, { price: 16 }, { price: 16 }, { price: 13 }, { price: 11 } ] }, { direction: "Buy", profilesData: [ { price: 14 }, { price: 15 }, { price: 13 }, { price: 14 }, { price: 18 }, { price: 10 }, { price: 10 }, { price: 18 }, { price: 17 }, { price: 15 }, { price: 17 }, { price: 19 }, { price: 12 }, { price: 20 }, { price: 11 }, { price: 16 }, { price: 17 }, { price: 15 }, { price: 13 }, { price: 10 }, { price: 18 }, { price: 10 }, { price: 19 }, { price: 14 } ] }, { direction: "Sell", profilesData: [ { price: 13 }, { price: 11 }, { price: 12 }, { price: 6 }, { price: 8 }, { price: 9 }, { price: 13 }, { price: 15 }, { price: 13 }, { price: 11 }, { price: 12 }, { price: 7 }, { price: 8 }, { price: 10 }, { price: 6 }, { price: 5 }, { price: 5 }, { price: 7 }, { price: 10 }, { price: 13 }, { price: 10 }, { price: 5 }, { price: 5 }, { price: 6 } ] }, { direction: "Sell", profilesData: [ { price: 11 }, { price: 7 }, { price: 5 }, { price: 12 }, { price: 7 }, { price: 5 }, { price: 13 }, { price: 6 }, { price: 12 }, { price: 11 }, { price: 11 }, { price: 10 }, { price: 5 }, { price: 12 }, { price: 10 }, { price: 7 }, { price: 7 }, { price: 7 }, { price: 14 }, { price: 14 }, { price: 11 }, { price: 12 }, { price: 13 }, { price: 8 } ] } ]; }
 body { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; } #chartdiv { width: 100%; height: 450px; }
 <script src="//www.amcharts.com/lib/4/core.js"></script> <script src="//www.amcharts.com/lib/4/charts.js"></script> <script src="//www.amcharts.com/lib/4/themes/animated.js"></script> <div id="chartdiv"></div>

Your dates need to be in ascending order for it to work with a DateAxis.您的日期需要按升序排列才能与 DateAxis 一起使用。 Your dates are descending, which can lead into issues like the scrollbar breaking.您的日期正在递减,这可能会导致滚动条断裂等问题。 Just call reverse() on your array:只需在您的数组上调用 reverse() :

component.ts组件.ts

let data = [
    {
        "value": 27.75,
        "date": new Date(2019, 0, 31)
    },
    {
        "value": 27.77,
        "date": new Date(2019, 0, 30)
    },
    {
        "value":  27.79,
        "date": new Date(2019, 0, 29)
    },
    {
        "value": 27.81,
        "date": new Date(2019, 0, 28)
    },
    {
        "value": 27.78,
        "date": new Date(2019, 0, 27)
    }
].reverse();

let chart = am4core.create("chart", am4charts.XYChart);
chart.data = data;
let xAxis = chart.xAxes.push(new am4charts.DateAxis());
let yAxis = chart.yAxes.push(new am4charts.ValueAxis())

xAxis.dataFields.category = "date";
xAxis.title.text = "Date";

let series = chart.series.push(new am4charts.LineSeries())
let bullet = series.bullets.push(new am4charts.CircleBullet())
series.dataFields.dateX = "date";
series.dataFields.valueY = "value";
series.tooltipText = "{valueY}"
chart.cursor = new am4charts.XYCursor();
series.name = "Value";
series.strokeWidth = 2;
chart.scrollbarX = new am4core.Scrollbar();

component.css组件.css

div {
  width: 100%;
  height: 300px;
}

component.html组件.html

<script src="https://www.amcharts.com/lib/4/core.js"></script>
<script src="https://www.amcharts.com/lib/4/charts.js"></script>
<div id="chart"></div>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM