` into which the plot is rendered. |
+| `[className]` | `string` | `undefined` | applied to the `
` into which the plot is rendered |
+| `[style]` | `Object` | `{position: 'relative', display: 'inline-block'}` | used to style the `
` into which the plot is rendered |
+| `[debug]` | `Boolean` | `false` | Assign the graph div to `window.gd` for debugging |
+| `[useResizeHandler]` | `Boolean` | `false` | When true, adds a call to `Plotly.Plot.resize()` as a `window.resize` event handler |
**Note**: To make a plot responsive, i.e. to fill its containing element and resize when the window is resized, use `style` or `className` to set the dimensions of the element (i.e. using `width: 100%; height: 100%` or some similar values) and set `useResizeHandler` to `true` while setting `layout.autosize` to `true` and leaving `layout.height` and `layout.width` undefined. This will implement the behaviour documented here: https://plot.ly/javascript/responsive-fluid-layout/
diff --git a/package-lock.json b/package-lock.json
index f746564..6dd8593 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,6 +1,6 @@
{
"name": "angular-plotly.js",
- "version": "1.4.2",
+ "version": "1.5.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
diff --git a/package.json b/package.json
index e90b1f3..42d01d9 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "angular-plotly.js",
- "version": "1.4.2",
+ "version": "1.5.0",
"license": "MIT",
"main": "index.ts",
"scripts": {
diff --git a/src/app/demo/bar-plots/bar-plots.component.html b/src/app/demo/bar-plots/bar-plots.component.html
index 0f70e05..facd758 100644
--- a/src/app/demo/bar-plots/bar-plots.component.html
+++ b/src/app/demo/bar-plots/bar-plots.component.html
@@ -1,5 +1,5 @@
-
+
diff --git a/src/app/demo/bar-plots/bar-plots.component.ts b/src/app/demo/bar-plots/bar-plots.component.ts
index e60d2ef..bfa2520 100644
--- a/src/app/demo/bar-plots/bar-plots.component.ts
+++ b/src/app/demo/bar-plots/bar-plots.component.ts
@@ -63,4 +63,8 @@ export class BarPlotComponent {
}
};
+ public onPlotlyClick(event: Event) {
+ console.log('Sim sim sim', event);
+ }
+
}
diff --git a/src/app/demo/demo.component.html b/src/app/demo/demo.component.html
index 9e09805..794db6e 100644
--- a/src/app/demo/demo.component.html
+++ b/src/app/demo/demo.component.html
@@ -16,6 +16,7 @@
Angular Plotly
Frames
Timeout Update
Huge Memory Usage
+
Slow Example
diff --git a/src/app/demo/demo.module.ts b/src/app/demo/demo.module.ts
index dc8e476..80d2349 100644
--- a/src/app/demo/demo.module.ts
+++ b/src/app/demo/demo.module.ts
@@ -22,6 +22,7 @@ import { MemoryLeakComponent } from './memory-leak/memory-leak.component';
import { FramesComponent } from './frames/frames.component';
import { TimeoutUpdateComponent } from './timeout-update/timeout-update.component';
import { HugeMemoryUsageComponent } from './huge-memory-usage/huge-memory-usage.component';
+import { SlowExampleComponent } from './slow-example/slow-example.component';
const demoRoutes: Routes = [
@@ -35,13 +36,14 @@ const demoRoutes: Routes = [
{ path: 'frames', component: FramesComponent, data: { title: 'Frames' } },
{ path: 'timeout-update', component: TimeoutUpdateComponent, data: { title: 'Timeout Update' } },
{ path: 'huge-memory-usage', component: HugeMemoryUsageComponent, data: { title: 'Huge Memory Usage' } },
+ { path: 'slow-example', component: SlowExampleComponent, data: { title: 'Slow example' } },
{ path: '', redirectTo: '/home', pathMatch: 'full' },
];
// PlotlyModule.plotlyjs = PlotlyJS;
-PlotlyViaCDNModule.plotlyVersion = '1.5.0';
+PlotlyViaCDNModule.plotlyVersion = '1.49.4';
// PlotlyViaCDNModule.plotlyBundle = 'cartesian';
@NgModule({
@@ -65,6 +67,7 @@ PlotlyViaCDNModule.plotlyVersion = '1.5.0';
FramesComponent,
TimeoutUpdateComponent,
HugeMemoryUsageComponent,
+ SlowExampleComponent,
],
exports: [DemoComponent],
})
diff --git a/src/app/demo/frames/frames.component.html b/src/app/demo/frames/frames.component.html
index 01e6656..f631864 100644
--- a/src/app/demo/frames/frames.component.html
+++ b/src/app/demo/frames/frames.component.html
@@ -1,5 +1,6 @@
-
+
Example got from: https://plot.ly/javascript/gapminder-example/
diff --git a/src/app/demo/slow-example/slow-example.component.html b/src/app/demo/slow-example/slow-example.component.html
new file mode 100644
index 0000000..0d81b87
--- /dev/null
+++ b/src/app/demo/slow-example/slow-example.component.html
@@ -0,0 +1,29 @@
+
+
+
+
+
+ [updateOnLayoutChange]="false"
+
+
+ [updateOnDataChange]="false"
+
+
+ [updateOnlyWithRevision]="false"
+
+
+
+
+
+
+
+ [updateOnLayoutChange]="true"
+
+
+ [updateOnDataChange]="true"
+
+
+ [updateOnlyWithRevision]="true"
+
+
+
diff --git a/src/app/demo/slow-example/slow-example.component.scss b/src/app/demo/slow-example/slow-example.component.scss
new file mode 100644
index 0000000..1d10f26
--- /dev/null
+++ b/src/app/demo/slow-example/slow-example.component.scss
@@ -0,0 +1,12 @@
+
+
+.row {
+ display: flex;
+}
+
+.col {
+ flex: 1;
+ align-self: center;
+ justify-content: center;
+ text-align: center;
+}
diff --git a/src/app/demo/slow-example/slow-example.component.ts b/src/app/demo/slow-example/slow-example.component.ts
new file mode 100644
index 0000000..92270c3
--- /dev/null
+++ b/src/app/demo/slow-example/slow-example.component.ts
@@ -0,0 +1,52 @@
+import { Component, OnInit } from '@angular/core';
+
+@Component({
+ selector: 'plotly-slow-example',
+ templateUrl: './slow-example.component.html',
+ styleUrls: ['./slow-example.component.scss'],
+})
+export class SlowExampleComponent implements OnInit {
+ data: any;
+ layout: any;
+
+ ngOnInit() {
+ this.layout = { showlegend: false };
+ this.data = this.getData();
+ }
+
+ getData() {
+ const startValue = 0;
+ const stopValue = 100000;
+ const pointNum = 10000;
+ const traceNum = 10;
+ const currValue = startValue;
+ const step = (stopValue - startValue) / (pointNum - 1);
+
+ const data = [];
+
+ for (let j = 0; j < traceNum; j++) {
+ const X = [];
+ const Y = [];
+ for (let i = 0; i < pointNum; i++) {
+ X.push(currValue + step * i);
+ Y.push(this.gaussianRand() * 8 + j * 5);
+ }
+ data.push({
+ type: 'scattergl',
+ mode: 'line',
+ x: X,
+ y: Y
+ });
+ }
+
+ return data;
+ }
+
+ gaussianRand() {
+ let rand = 0;
+ for (let i = 0; i < 6; i += 1) {
+ rand += Math.random();
+ }
+ return rand / 6 - 0.5;
+ }
+}
diff --git a/src/app/shared/plot/plot.component.spec.ts b/src/app/shared/plot/plot.component.spec.ts
index 6fa16f1..e430708 100644
--- a/src/app/shared/plot/plot.component.spec.ts
+++ b/src/app/shared/plot/plot.component.spec.ts
@@ -73,25 +73,21 @@ describe('PlotComponent', () => {
it('should update the graph when the data changes', (done) => {
spyOn(component, 'updatePlot');
component.data = [{ y: [10, 15, 13, 17], type: 'box' }];
- expect(component.datarevision).toEqual(0);
+
component.createPlot().then(() => {
component.ngDoCheck();
expect(component.updatePlot).not.toHaveBeenCalled();
- expect(component.datarevision).toEqual(0);
component.data = [{ y: [11, 15, 13, 17], type: 'box' }];
component.ngDoCheck();
expect(component.updatePlot).toHaveBeenCalled();
- expect(component.datarevision).toEqual(1);
component.ngDoCheck();
expect(component.updatePlot).toHaveBeenCalledTimes(1);
- expect(component.datarevision).toEqual(1);
component.data[0].y[0] = 12;
component.ngDoCheck();
expect(component.updatePlot).toHaveBeenCalledTimes(2);
- expect(component.datarevision).toEqual(2);
done();
});
});
@@ -107,6 +103,9 @@ describe('PlotComponent', () => {
component.ngDoCheck();
expect(component.updatePlot).toHaveBeenCalled();
+ component.ngDoCheck();
+ expect(component.updatePlot).toHaveBeenCalledTimes(1);
+
component.layout.title = 'title three ';
component.ngDoCheck();
expect(component.updatePlot).toHaveBeenCalledTimes(2);
diff --git a/src/app/shared/plot/plot.component.ts b/src/app/shared/plot/plot.component.ts
index aa6586e..d684246 100644
--- a/src/app/shared/plot/plot.component.ts
+++ b/src/app/shared/plot/plot.component.ts
@@ -33,7 +33,6 @@ export class PlotComponent implements OnInit, OnChanges, OnDestroy, DoCheck {
public resizeHandler?: (instance: Plotly.PlotlyHTMLElement) => void;
public layoutDiffer: KeyValueDiffer
;
public dataDiffer: IterableDiffer;
- public datarevision: number = 0;
@ViewChild('plot', {static: true}) plotEl: ElementRef;
@@ -49,6 +48,10 @@ export class PlotComponent implements OnInit, OnChanges, OnDestroy, DoCheck {
@Input() debug: boolean = false;
@Input() useResizeHandler: boolean = false;
+ @Input() updateOnLayoutChange = true;
+ @Input() updateOnDataChange = true;
+ @Input() updateOnlyWithRevision = false;
+
@Output() initialized = new EventEmitter();
@Output() update = new EventEmitter();
@Output() purge = new EventEmitter();
@@ -141,32 +144,39 @@ export class PlotComponent implements OnInit, OnChanges, OnDestroy, DoCheck {
}
ngDoCheck() {
+ if (this.updateOnlyWithRevision) {
+ return false;
+ }
+
let shouldUpdate = false;
- if (this.layoutDiffer) {
- const layoutHasDiff = this.layoutDiffer.diff(this.layout);
- if (layoutHasDiff) {
- shouldUpdate = true;
+ if (this.updateOnLayoutChange) {
+ if (this.layoutDiffer) {
+ const layoutHasDiff = this.layoutDiffer.diff(this.layout);
+ if (layoutHasDiff) {
+ shouldUpdate = true;
+ }
+ } else if (this.layout) {
+ this.layoutDiffer = this.keyValueDiffers.find(this.layout).create();
+ } else {
+ this.layoutDiffer = undefined;
}
- } else if (this.layout) {
- this.layoutDiffer = this.keyValueDiffers.find(this.layout).create();
- } else {
- this.layoutDiffer = undefined;
}
- if (this.dataDiffer) {
- const dataHasDiff = this.dataDiffer.diff(this.data);
- if (dataHasDiff) {
- shouldUpdate = true;
+ if (this.updateOnDataChange) {
+ if (this.dataDiffer) {
+ const dataHasDiff = this.dataDiffer.diff(this.data);
+ if (dataHasDiff) {
+ shouldUpdate = true;
+ }
+ } else if (Array.isArray(this.data)) {
+ this.dataDiffer = this.iterableDiffers.find(this.data).create(this.dataDifferTrackBy);
+ } else {
+ this.dataDiffer = undefined;
}
- } else if (Array.isArray(this.data)) {
- this.dataDiffer = this.iterableDiffers.find(this.data).create(this.dataDifferTrackBy);
- } else {
- this.dataDiffer = undefined;
}
if (shouldUpdate && this.plotlyInstance) {
- this.datarevision += 1;
this.updatePlot();
}
}
@@ -227,10 +237,7 @@ export class PlotComponent implements OnInit, OnChanges, OnDestroy, DoCheck {
throw error;
}
- const layout = {
- ...{datarevision: this.datarevision},
- ...this.layout,
- };
+ const layout = {...this.layout};
return this.plotly.update(this.plotlyInstance, this.data, layout, this.config, this.frames).then(() => {
const figure = this.createFigure();