2

I am developing app in Angular 8 and displaying 'scatter' plot using angular-plotly.js. For data in x,y I am getting data from rest api. And I am able to plot graph using the data from rest api. On frontend I have a two dropdown from where user can select option and send those options value to backend and in response I get new data back to frontend. Till this point everything works fine, but the issue I am facing is that my plot is not getting updated with new data. Frontend still showing the initial plot not the new plot with different data value.

My Html code:

Here is my two dropdown from where user select options and based on this options from backend through restapi I receive data points to plot my graph. And when user changes any option from dropdown and submit new choice to backend I again receive new data point and I need to remove my old plot and display new plot based on new dataset.

<form (ngSubmit)="segmentSelection()" #ff="ngForm">
            <div id="userSelection" ngModelGroup="userData" #userData="ngModelGroup">
          <mat-form-field>
            <mat-label>Choose Segment Key</mat-label>
            <mat-select id="selectme" ngModel name="segmentKey">
              <mat-option *ngFor="let segment of segKeys" [value]="segment">
                {{segment}}
              </mat-option>
            </mat-select>
          </mat-form-field>

          <mat-form-field style="margin-left: 30px;">
            <mat-label>Choose Target Variable</mat-label>
            <mat-select id="myselect" ngModel name="target_variable">
              <mat-option *ngFor="let msg of mymessage" [value]="msg">
                {{msg}}
              </mat-option>
            </mat-select>
          </mat-form-field>
          <button type="submit" class="btn btn-success btn-color" (click)="plotDiv()" style="margin-left: 20px;">Submit</button>
        </div>
        </form>

<plotly-plot [data]="graph.data" [layout]="graph.layout"></plotly-plot>

My component.ts code:

myhistoricPlot = []
myhistoricDate = []

segmentSelection(){
  this.plotselection.segmentKey = this.segmentData.value.userData.segmentKey;
  this.plotselection.target_variable = this.segmentData.value.userData.target_variable;
  console.log(this.segmentData);
  fetch("http://localhost:5000/data-decomposition", {
    method: "POST",
    headers: {
      "Content-Type": "application/json"
    },body: JSON.stringify({
      segmentKey: this.segmentData.value.userData.segmentKey,
      target_variable: this.segmentData.value.userData.target_variable
    })
  }).then(res => res.json()
    // console.log(res);
    // console.log('hello saheb')
    // console.log(res.json())

  ).then(myjson => {

    myjson['Data'].forEach(element =>{
      this.myhistoricPlot.push(element)
    })
    myjson['Date'].forEach(element =>{
      this.myhistoricDate.push(element)
    })
    // console.log(this.myhistoricPlot)})
    // this.myhistoricDate = myjson['Date'];
    // this.myhistoricPlot = myjson['Data'];
    console.log(this.myhistoricDate);
    console.log(this.myhistoricPlot);
    console.log(myjson)
    this.myhistoricPlot = [];
    this.myhistoricDate = [];
    })
}

public graph = {
    data: [
        { x: this.myhistoricDate, y: this.myhistoricPlot, type: 'scatter', mode: 'lines+points', marker: {color: 'black'} },

    ],
    layout: {width: 1200, height: 600, title: 'Historical Actuals Plot'}
}; 

****Note: myhistoricDate, myhistoricPlot are the two list with some numerical values, in which I am receiving data from restapi.

Thank you....your help on this issue would be highly appreciated

4 Answers 4

2

Object and arrays are bound by reference, so Angular won't detect a change to graph.data until its reference is changed. I usually use a helper method to ensure that happens.

segmentSelection() {
  ...
  .then(myjson => this.setData(myjson.Date, myjson.Data));
}

setData(x, y) {
  this.data[0].x = x;
  this.data[1].y = y;
  this.data = { ...this.data };
}
Sign up to request clarification or add additional context in comments.

1 Comment

thanks a lot for pointing that angular won't detect change unless the reference is changed.
1

As mentioned by Trevor Karjanis it does not work because typescript is call by reference. So as long as you don't reasign your graph to a new object Angular won't detect the change as the reference is still the same in your code. However you could also just reasign the graph object like so:

    .then(myjson => {

    myjson['Data'].forEach(element =>{
      this.myhistoricPlot.push(element)
    })
    myjson['Date'].forEach(element =>{
      this.myhistoricDate.push(element)
    })
    // console.log(this.myhistoricPlot)})
    this.myhistoricDate = myjson['Date'];
    this.myhistoricPlot = myjson['Data'];
    this.graph = {
    data: [
        { x: this.myhistoricDate, y: this.myhistoricPlot, type: 'scatter', mode: 'lines+points', marker: {color: 'black'} },

    ],
    layout: {width: 1200, height: 600, title: 'Historical Actuals Plot'}
}; 
})

Comments

0

Try to add ChangeDetectionStrategy:

import { ChangeDetectionStrategy, ChangeDetectorRef } from '@angular/core';

@Component({
  selector: '...',
  templateUrl: '...',
  styleUrls: ['...'],
  changeDetection: ChangeDetectionStrategy.OnPush
})

export MyComponent implements OnInit {

constructor(private _cd: ChangeDetectorRef) {}

...
).then(myjson => {

    myjson['Data'].forEach(element =>{
      this.myhistoricPlot.push(element)
    })
    myjson['Date'].forEach(element =>{
      this.myhistoricDate.push(element)
    })
    // console.log(this.myhistoricPlot)})
    // this.myhistoricDate = myjson['Date'];
    // this.myhistoricPlot = myjson['Data'];
    console.log(this.myhistoricDate);
    console.log(this.myhistoricPlot);
    console.log(myjson)

    this._cd.detectChanges();
    ...
    })

Comments

0

Use this.myhistoricDate.splice(0) and this.myhistoricPlot.splice(0) instead of this.myhistoricDate & this.myhistoricPlot. This will create a new array and angular will recognize it as a change which will lead to updating the plot.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.