Skip to content

Commit

Permalink
Merge pull request #9042 from maxlang/maxlang/ui-fix-background-tab-g…
Browse files Browse the repository at this point in the history
…raphs

ui: fix bug where tab with graphs would crash after regaining focus
  • Loading branch information
maxlang authored Sep 2, 2016
2 parents 5a8038e + 759b030 commit 1f7bf16
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 45 deletions.
63 changes: 41 additions & 22 deletions ui/app/components/linegraph.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -94,38 +94,57 @@ export class LineGraph extends React.Component<LineGraphProps, {}> {
}

drawChart() {
let metrics = this.metrics(this.props);
let axis = this.axis(this.props);
if (!axis) {
return;
}
// If the document is not visible (e.g. if the window is minimized) we don't
// attempt to redraw the chart. Redrawing the chart uses
// requestAnimationFrame, which isn't called when the tab is in the
// background, and is then apparently queued up and called en masse when the
// tab re-enters the foreground. This check prevents the issue in #8896
// where switching to a tab with the graphs page open that had been in the
// background caused the UI to run out of memory and either lag or crash.
// NOTE: This might not work on Android:
// http://caniuse.com/#feat=pagevisibility
if (!document.hidden) {
let metrics = this.metrics(this.props);
let axis = this.axis(this.props);
if (!axis) {
return;
}

this.chart.showLegend(_.isBoolean(this.props.legend) ? this.props.legend :
metrics.length > 1 && metrics.length <= MAX_LEGEND_SERIES);
let formattedData: any[] = [];
this.chart.showLegend(_.isBoolean(this.props.legend) ? this.props.legend :
metrics.length > 1 && metrics.length <= MAX_LEGEND_SERIES);
let formattedData: any[] = [];

if (this.props.data) {
let processed = ProcessDataPoints(metrics, axis, this.props.data);
formattedData = processed.formattedData;
let {yAxisDomain, xAxisDomain } = processed;
if (this.props.data) {
let processed = ProcessDataPoints(metrics, axis, this.props.data);
formattedData = processed.formattedData;
let {yAxisDomain, xAxisDomain } = processed;

this.chart.yDomain(yAxisDomain.domain());
this.chart.yDomain(yAxisDomain.domain());

// always set the tick values to the lowest axis value, the highest axis
// value, and one value in between
this.chart.yAxis.tickValues(yAxisDomain.ticks());
this.chart.xAxis.tickValues(xAxisDomain.ticks((n) => new Date(NanoToMilli(n))));
}
// always set the tick values to the lowest axis value, the highest axis
// value, and one value in between
this.chart.yAxis.tickValues(yAxisDomain.ticks());
this.chart.xAxis.tickValues(xAxisDomain.ticks((n) => new Date(NanoToMilli(n))));
}

d3.select(this.svgEl)
.datum(formattedData)
.transition().duration(500)
.call(this.chart);
d3.select(this.svgEl)
.datum(formattedData)
.transition().duration(500)
.call(this.chart);
}
}

componentDidMount() {
this.initChart();
this.drawChart();
// NOTE: This might not work on Android:
// http://caniuse.com/#feat=pagevisibility
// TODO (maxlang): Check if this element is visible based on scroll state.
document.addEventListener("visibilitychange", this.drawChart);
}

componentWillUnmount() {
document.removeEventListener("visibilitychange", this.drawChart);
}

componentDidUpdate() {
Expand Down
63 changes: 41 additions & 22 deletions ui/app/components/stackedgraph.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -99,38 +99,57 @@ export class StackedAreaGraph extends React.Component<StackedAreaGraphProps, {}>
}

drawChart() {
let metrics = this.metrics(this.props);
let axis = this.axis(this.props);
if (!axis) {
return;
}
// If the document is not visible (e.g. if the window is minimized) we don't
// attempt to redraw the chart. Redrawing the chart uses
// requestAnimationFrame, which isn't called when the tab is in the
// background, and is then apparently queued up and called en masse when the
// tab re-enters the foreground. This check prevents the issue in #8896
// where switching to a tab with the graphs page open that had been in the
// background caused the UI to run out of memory and either lag or crash.
// NOTE: This might not work on Android:
// http://caniuse.com/#feat=pagevisibility
if (!document.hidden) {
let metrics = this.metrics(this.props);
let axis = this.axis(this.props);
if (!axis) {
return;
}

this.chart.showLegend(_.isBoolean(this.props.legend) ? this.props.legend :
metrics.length > 1 && metrics.length <= MAX_LEGEND_SERIES);
let formattedData: any[] = [];
this.chart.showLegend(_.isBoolean(this.props.legend) ? this.props.legend :
metrics.length > 1 && metrics.length <= MAX_LEGEND_SERIES);
let formattedData: any[] = [];

if (this.props.data) {
let processed = ProcessDataPoints(metrics, axis, this.props.data);
formattedData = processed.formattedData;
let {yAxisDomain, xAxisDomain } = processed;
if (this.props.data) {
let processed = ProcessDataPoints(metrics, axis, this.props.data);
formattedData = processed.formattedData;
let {yAxisDomain, xAxisDomain } = processed;

this.chart.yDomain(yAxisDomain.domain());
this.chart.yDomain(yAxisDomain.domain());

// always set the tick values to the lowest axis value, the highest axis
// value, and one value in between
this.chart.yAxis.tickValues(yAxisDomain.ticks());
this.chart.xAxis.tickValues(xAxisDomain.ticks((n) => new Date(NanoToMilli(n))));
}
// always set the tick values to the lowest axis value, the highest axis
// value, and one value in between
this.chart.yAxis.tickValues(yAxisDomain.ticks());
this.chart.xAxis.tickValues(xAxisDomain.ticks((n) => new Date(NanoToMilli(n))));
}

d3.select(this.svgEl)
.datum(formattedData)
.transition().duration(500)
.call(this.chart);
d3.select(this.svgEl)
.datum(formattedData)
.transition().duration(500)
.call(this.chart);
}
}

componentDidMount() {
this.initChart();
this.drawChart();
// NOTE: This might not work on Android:
// http://caniuse.com/#feat=pagevisibility
// TODO (maxlang): Check if this element is visible based on scroll state.
document.addEventListener("visibilitychange", this.drawChart);
}

componentWillUnmount() {
document.removeEventListener("visibilitychange", this.drawChart);
}

componentDidUpdate() {
Expand Down
2 changes: 1 addition & 1 deletion ui/embedded.go

Large diffs are not rendered by default.

0 comments on commit 1f7bf16

Please sign in to comment.