open-nomad/ui/app/components/line-chart.js

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

395 lines
10 KiB
JavaScript
Raw Normal View History

/**
* Copyright (c) HashiCorp, Inc.
* SPDX-License-Identifier: MPL-2.0
*/
import Component from '@glimmer/component';
import { tracked } from '@glimmer/tracking';
import { action } from '@ember/object';
Upgrade Ember and friends 3.28 (#12215) * chore: upgrade forward compatible packages * chore: v3.20.2...v3.24.0 * chore: silence string prototype extension deprecation * refact: don't test clicking disabled button job-list Recent test-helper upgrades will guard against clicking disabled buttons as this is not something that real users can do. We need to change our tests accordingly. * fix: await async test helper `expectError` We have to await this async test function otherwise the test's rendering context will be torn down before we run assertions against it. * fix: don't try to click disabled two-step-button Recent test-helper updates prohibit clicking disabled buttons. We need to adapt the tests accordingly. * fix: recommendation-accordion Use up-to-date semantics for handling list-accordion closing in recommendation-accordion. * fixes toggling recommendation-accordion toggle. * fix: simple-unless linting error application.hbs There's no reason to use unless here - we can use if instead. * fix: no-quoteless-attributes recommendation accordion * fix: no-quoteless-attributes recommendation-chart * fix: allow `unless` - global-header.hbs This is a valid use of unless in our opinion. * fix: allow unless in job-diff This is not a great use for unless but we don't want to change this behavior atm. * fix: no-attrs-in-components list-pager There is no need to use this.attrs in classic components. When we will convert to glimmer we will use `@`-instead. * fix: simple-unless job/definition We can convert to a simple if here. * fix: allow inline-styles stats-box component To make linter happy. * fix: disable no-action and no-invalid-interactive Will be adressed in follow-up PRs. * chore: update ember-classic-decorator to latest * chore: upgrade ember-can to latest * chore: upgrade ember-composable-helpers to latest * chore: upgrade ember-concurrency * fix: recomputation deprecation `Trigger` schedule `do` on actions queue to work around recomputation deprecation when triggering Trigger on `did-insert`. * chore: upgrade ember-cli-string-helpers * chore: upgrade ember-copy * chore: upgrade ember-data-model-fragments * chore: upgrade ember-deprecation-workflow * chore: upgrade ember-inline-svg * chore: upgrade ember-modifier * chore: upgrade ember-truth-helpers * chore: upgrade ember-moment & ember-cli-moment-shim * chore: upgrade ember-power-select * chore: upgrade ember-responsive * chore: upgrade ember-sinon * chore: upgrade ember-cli-mirage For now we will stay on 2.2 - upgrades > 2.3 break the build. * chore: upgrade 3.24.0 to 3.28.5 * fix: add missing classic decorators on adapters * fix: missing classic decorators to serializers * fix: don't reopen Ember.Object anymore * fix: remove unused useNativeEvents ember-cli-page-objects doesn't provide this method anymore * fix: add missing attributeBindings for test-selectors ember-test-selectors doesn't provides automatic bindings for data-test-* attributes anymore. * fix: classic decorator for application serializer test * fix: remove `removeContext` from tests. It is unneeded and ember-cli-page-objects doesn't provides this method anymore. * fix: remove deprecations `run.*`-invocations * fix: `collapseWhitespace` in optimize test * fix: make sure to load async relationship before access * fix: dependent keys for relationship computeds We need to add `*.isFulfilled` as dependent keys for computeds that access async relationships. * fix: `computed.read`-invocations use `read` instead * chore: prettify templates * fix: use map instead of mapBy ember-cli-page-object Doesn't work with updated ember-cli-page-object anymore. * fix: remove remaining deprecated `run.*`-calls * chore: add more deprecations deprecation-workflow * fix: `implicit-injection`-deprecation All routes that add watchers will need to inject the store-service as the store service is internally used in watchers. * fix: more implicit injection deprecations * chore: silence implicit-injection deprecation We can tackle the deprecation when we find the time. * fix: new linting errors after upgrade * fix: remove merge conflicts prettierignore * chore: upgrade to run node 12.22 when building binaries
2022-03-08 17:28:36 +00:00
import { schedule, next } from '@ember/runloop';
2018-09-07 16:59:02 +00:00
import d3 from 'd3-selection';
import d3Scale from 'd3-scale';
import d3Axis from 'd3-axis';
import d3Array from 'd3-array';
import d3Format from 'd3-format';
import d3TimeFormat from 'd3-time-format';
import styleString from 'nomad-ui/utils/properties/glimmer-style-string';
import uniquely from 'nomad-ui/utils/properties/uniquely';
2018-09-07 16:59:02 +00:00
// Returns a new array with the specified number of points linearly
// distributed across the bounds
const lerp = ([low, high], numPoints) => {
const step = (high - low) / (numPoints - 1);
const arr = [];
for (var i = 0; i < numPoints; i++) {
arr.push(low + step * i);
}
return arr;
};
// Round a number or an array of numbers
2021-12-28 14:45:20 +00:00
const nice = (val) => (val instanceof Array ? val.map(nice) : Math.round(val));
2018-09-07 16:59:02 +00:00
const defaultXScale = (data, yAxisOffset, xProp, timeseries) => {
const scale = timeseries ? d3Scale.scaleTime() : d3Scale.scaleLinear();
2021-12-28 14:45:20 +00:00
const domain = data.length ? d3Array.extent(data, (d) => d[xProp]) : [0, 1];
scale.rangeRound([10, yAxisOffset]).domain(domain);
return scale;
};
const defaultYScale = (data, xAxisOffset, yProp) => {
2021-12-28 14:45:20 +00:00
let max = d3Array.max(data, (d) => d[yProp]) || 1;
if (max > 1) {
max = nice(max);
}
2021-12-28 14:45:20 +00:00
return d3Scale.scaleLinear().rangeRound([xAxisOffset, 10]).domain([0, max]);
};
export default class LineChart extends Component {
/** Args
data = null;
xProp = null;
yProp = null;
curve = 'linear';
title = 'Line Chart';
description = null;
timeseries = false;
activeAnnotation = null;
onAnnotationClick() {}
xFormat;
yFormat;
xScale;
yScale;
*/
@tracked width = 0;
@tracked height = 0;
@tracked isActive = false;
@tracked activeDatum = null;
@tracked activeData = [];
@tracked tooltipPosition = null;
@tracked element = null;
@tracked ready = false;
@uniquely('title') titleId;
@uniquely('desc') descriptionId;
get xProp() {
return this.args.xProp || 'time';
}
get yProp() {
return this.args.yProp || 'value';
}
get data() {
if (!this.args.data) return [];
if (this.args.dataProp) {
return this.args.data.mapBy(this.args.dataProp).flat();
}
return this.args.data;
}
get curve() {
return this.args.curve || 'linear';
}
2018-09-07 16:59:02 +00:00
@action
xFormat(timeseries) {
if (this.args.xFormat) return this.args.xFormat;
2021-12-28 16:08:12 +00:00
return timeseries
? d3TimeFormat.timeFormat('%b %d, %H:%M')
: d3Format.format(',');
}
2018-09-07 16:59:02 +00:00
@action
yFormat() {
if (this.args.yFormat) return this.args.yFormat;
return d3Format.format(',.2~r');
}
2018-09-07 16:59:02 +00:00
get activeDatumLabel() {
2019-03-26 07:46:44 +00:00
const datum = this.activeDatum;
2018-09-07 16:59:02 +00:00
if (!datum) return undefined;
2018-09-07 16:59:02 +00:00
2019-03-26 07:46:44 +00:00
const x = datum[this.xProp];
return this.xFormat(this.args.timeseries)(x);
}
2018-09-07 16:59:02 +00:00
get activeDatumValue() {
2019-03-26 07:46:44 +00:00
const datum = this.activeDatum;
2018-09-07 16:59:02 +00:00
if (!datum) return undefined;
2018-09-07 16:59:02 +00:00
2019-03-26 07:46:44 +00:00
const y = datum[this.yProp];
2018-09-07 16:59:02 +00:00
return this.yFormat()(y);
}
2018-09-07 16:59:02 +00:00
@styleString
get tooltipStyle() {
return this.tooltipPosition;
}
get xScale() {
const fn = this.args.xScale || defaultXScale;
return fn(this.data, this.yAxisOffset, this.xProp, this.args.timeseries);
}
2018-09-07 16:59:02 +00:00
get xRange() {
const { xProp, data } = this;
2021-12-28 14:45:20 +00:00
const range = d3Array.extent(data, (d) => d[xProp]);
const formatter = this.xFormat(this.args.timeseries);
return range.map(formatter);
}
get yRange() {
2019-03-26 07:46:44 +00:00
const yProp = this.yProp;
2021-12-28 14:45:20 +00:00
const range = d3Array.extent(this.data, (d) => d[yProp]);
const formatter = this.yFormat();
return range.map(formatter);
}
get yScale() {
const fn = this.args.yScale || defaultYScale;
return fn(this.data, this.xAxisOffset, this.yProp);
}
2018-09-07 16:59:02 +00:00
get xAxis() {
const formatter = this.xFormat(this.args.timeseries);
2018-09-07 16:59:02 +00:00
2021-12-28 16:08:12 +00:00
return d3Axis
.axisBottom()
.scale(this.xScale)
.ticks(5)
.tickFormat(formatter);
}
2018-09-07 16:59:02 +00:00
get yTicks() {
2019-03-26 07:46:44 +00:00
const height = this.xAxisOffset;
2018-09-07 16:59:02 +00:00
const tickCount = Math.ceil(height / 120) * 2 + 1;
2019-03-26 07:46:44 +00:00
const domain = this.yScale.domain();
const ticks = lerp(domain, tickCount);
return domain[1] - domain[0] > 1 ? nice(ticks) : ticks;
}
2018-09-07 16:59:02 +00:00
get yAxis() {
2018-09-07 16:59:02 +00:00
const formatter = this.yFormat();
2021-12-28 16:08:12 +00:00
return d3Axis
.axisRight()
.scale(this.yScale)
.tickValues(this.yTicks)
.tickFormat(formatter);
}
2018-09-07 16:59:02 +00:00
get yGridlines() {
2018-09-07 16:59:02 +00:00
// The first gridline overlaps the x-axis, so remove it
2019-03-26 07:46:44 +00:00
const [, ...ticks] = this.yTicks;
2018-09-07 16:59:02 +00:00
return d3Axis
.axisRight()
2019-03-26 07:46:44 +00:00
.scale(this.yScale)
2018-09-07 16:59:02 +00:00
.tickValues(ticks)
2021-02-26 01:50:59 +00:00
.tickSize(-this.canvasDimensions.width)
2018-09-07 16:59:02 +00:00
.tickFormat('');
}
2018-09-07 16:59:02 +00:00
get xAxisHeight() {
// Avoid divide by zero errors by always having a height
if (!this.element) return 1;
2018-09-07 16:59:02 +00:00
const axis = this.element.querySelector('.x-axis');
return axis && axis.getBBox().height;
}
2018-09-07 16:59:02 +00:00
get yAxisWidth() {
// Avoid divide by zero errors by always having a width
if (!this.element) return 1;
2018-09-07 16:59:02 +00:00
const axis = this.element.querySelector('.y-axis');
return axis && axis.getBBox().width;
}
2018-09-07 16:59:02 +00:00
get xAxisOffset() {
return Math.max(0, this.height - this.xAxisHeight);
}
2018-09-07 16:59:02 +00:00
get yAxisOffset() {
return Math.max(0, this.width - this.yAxisWidth);
}
2018-09-07 16:59:02 +00:00
2021-02-26 01:50:59 +00:00
get canvasDimensions() {
const [left, right] = this.xScale.range();
const [top, bottom] = this.yScale.range();
return { left, width: right - left, top, height: bottom - top };
}
@action
onInsert(element) {
this.element = element;
2018-09-07 16:59:02 +00:00
this.updateDimensions();
const canvas = d3.select(this.element.querySelector('.hover-target'));
2018-09-07 16:59:02 +00:00
const updateActiveDatum = this.updateActiveDatum.bind(this);
const chart = this;
2021-12-28 14:45:20 +00:00
canvas.on('mouseenter', function (ev) {
const mouseX = d3.pointer(ev, this)[0];
chart.latestMouseX = mouseX;
updateActiveDatum(mouseX);
Upgrade Ember and friends 3.28 (#12215) * chore: upgrade forward compatible packages * chore: v3.20.2...v3.24.0 * chore: silence string prototype extension deprecation * refact: don't test clicking disabled button job-list Recent test-helper upgrades will guard against clicking disabled buttons as this is not something that real users can do. We need to change our tests accordingly. * fix: await async test helper `expectError` We have to await this async test function otherwise the test's rendering context will be torn down before we run assertions against it. * fix: don't try to click disabled two-step-button Recent test-helper updates prohibit clicking disabled buttons. We need to adapt the tests accordingly. * fix: recommendation-accordion Use up-to-date semantics for handling list-accordion closing in recommendation-accordion. * fixes toggling recommendation-accordion toggle. * fix: simple-unless linting error application.hbs There's no reason to use unless here - we can use if instead. * fix: no-quoteless-attributes recommendation accordion * fix: no-quoteless-attributes recommendation-chart * fix: allow `unless` - global-header.hbs This is a valid use of unless in our opinion. * fix: allow unless in job-diff This is not a great use for unless but we don't want to change this behavior atm. * fix: no-attrs-in-components list-pager There is no need to use this.attrs in classic components. When we will convert to glimmer we will use `@`-instead. * fix: simple-unless job/definition We can convert to a simple if here. * fix: allow inline-styles stats-box component To make linter happy. * fix: disable no-action and no-invalid-interactive Will be adressed in follow-up PRs. * chore: update ember-classic-decorator to latest * chore: upgrade ember-can to latest * chore: upgrade ember-composable-helpers to latest * chore: upgrade ember-concurrency * fix: recomputation deprecation `Trigger` schedule `do` on actions queue to work around recomputation deprecation when triggering Trigger on `did-insert`. * chore: upgrade ember-cli-string-helpers * chore: upgrade ember-copy * chore: upgrade ember-data-model-fragments * chore: upgrade ember-deprecation-workflow * chore: upgrade ember-inline-svg * chore: upgrade ember-modifier * chore: upgrade ember-truth-helpers * chore: upgrade ember-moment & ember-cli-moment-shim * chore: upgrade ember-power-select * chore: upgrade ember-responsive * chore: upgrade ember-sinon * chore: upgrade ember-cli-mirage For now we will stay on 2.2 - upgrades > 2.3 break the build. * chore: upgrade 3.24.0 to 3.28.5 * fix: add missing classic decorators on adapters * fix: missing classic decorators to serializers * fix: don't reopen Ember.Object anymore * fix: remove unused useNativeEvents ember-cli-page-objects doesn't provide this method anymore * fix: add missing attributeBindings for test-selectors ember-test-selectors doesn't provides automatic bindings for data-test-* attributes anymore. * fix: classic decorator for application serializer test * fix: remove `removeContext` from tests. It is unneeded and ember-cli-page-objects doesn't provides this method anymore. * fix: remove deprecations `run.*`-invocations * fix: `collapseWhitespace` in optimize test * fix: make sure to load async relationship before access * fix: dependent keys for relationship computeds We need to add `*.isFulfilled` as dependent keys for computeds that access async relationships. * fix: `computed.read`-invocations use `read` instead * chore: prettify templates * fix: use map instead of mapBy ember-cli-page-object Doesn't work with updated ember-cli-page-object anymore. * fix: remove remaining deprecated `run.*`-calls * chore: add more deprecations deprecation-workflow * fix: `implicit-injection`-deprecation All routes that add watchers will need to inject the store-service as the store service is internally used in watchers. * fix: more implicit injection deprecations * chore: silence implicit-injection deprecation We can tackle the deprecation when we find the time. * fix: new linting errors after upgrade * fix: remove merge conflicts prettierignore * chore: upgrade to run node 12.22 when building binaries
2022-03-08 17:28:36 +00:00
schedule('afterRender', chart, () => (chart.isActive = true));
2018-09-07 16:59:02 +00:00
});
2021-12-28 14:45:20 +00:00
canvas.on('mousemove', function (ev) {
const mouseX = d3.pointer(ev, this)[0];
chart.latestMouseX = mouseX;
2018-09-07 16:59:02 +00:00
updateActiveDatum(mouseX);
});
canvas.on('mouseleave', () => {
Upgrade Ember and friends 3.28 (#12215) * chore: upgrade forward compatible packages * chore: v3.20.2...v3.24.0 * chore: silence string prototype extension deprecation * refact: don't test clicking disabled button job-list Recent test-helper upgrades will guard against clicking disabled buttons as this is not something that real users can do. We need to change our tests accordingly. * fix: await async test helper `expectError` We have to await this async test function otherwise the test's rendering context will be torn down before we run assertions against it. * fix: don't try to click disabled two-step-button Recent test-helper updates prohibit clicking disabled buttons. We need to adapt the tests accordingly. * fix: recommendation-accordion Use up-to-date semantics for handling list-accordion closing in recommendation-accordion. * fixes toggling recommendation-accordion toggle. * fix: simple-unless linting error application.hbs There's no reason to use unless here - we can use if instead. * fix: no-quoteless-attributes recommendation accordion * fix: no-quoteless-attributes recommendation-chart * fix: allow `unless` - global-header.hbs This is a valid use of unless in our opinion. * fix: allow unless in job-diff This is not a great use for unless but we don't want to change this behavior atm. * fix: no-attrs-in-components list-pager There is no need to use this.attrs in classic components. When we will convert to glimmer we will use `@`-instead. * fix: simple-unless job/definition We can convert to a simple if here. * fix: allow inline-styles stats-box component To make linter happy. * fix: disable no-action and no-invalid-interactive Will be adressed in follow-up PRs. * chore: update ember-classic-decorator to latest * chore: upgrade ember-can to latest * chore: upgrade ember-composable-helpers to latest * chore: upgrade ember-concurrency * fix: recomputation deprecation `Trigger` schedule `do` on actions queue to work around recomputation deprecation when triggering Trigger on `did-insert`. * chore: upgrade ember-cli-string-helpers * chore: upgrade ember-copy * chore: upgrade ember-data-model-fragments * chore: upgrade ember-deprecation-workflow * chore: upgrade ember-inline-svg * chore: upgrade ember-modifier * chore: upgrade ember-truth-helpers * chore: upgrade ember-moment & ember-cli-moment-shim * chore: upgrade ember-power-select * chore: upgrade ember-responsive * chore: upgrade ember-sinon * chore: upgrade ember-cli-mirage For now we will stay on 2.2 - upgrades > 2.3 break the build. * chore: upgrade 3.24.0 to 3.28.5 * fix: add missing classic decorators on adapters * fix: missing classic decorators to serializers * fix: don't reopen Ember.Object anymore * fix: remove unused useNativeEvents ember-cli-page-objects doesn't provide this method anymore * fix: add missing attributeBindings for test-selectors ember-test-selectors doesn't provides automatic bindings for data-test-* attributes anymore. * fix: classic decorator for application serializer test * fix: remove `removeContext` from tests. It is unneeded and ember-cli-page-objects doesn't provides this method anymore. * fix: remove deprecations `run.*`-invocations * fix: `collapseWhitespace` in optimize test * fix: make sure to load async relationship before access * fix: dependent keys for relationship computeds We need to add `*.isFulfilled` as dependent keys for computeds that access async relationships. * fix: `computed.read`-invocations use `read` instead * chore: prettify templates * fix: use map instead of mapBy ember-cli-page-object Doesn't work with updated ember-cli-page-object anymore. * fix: remove remaining deprecated `run.*`-calls * chore: add more deprecations deprecation-workflow * fix: `implicit-injection`-deprecation All routes that add watchers will need to inject the store-service as the store service is internally used in watchers. * fix: more implicit injection deprecations * chore: silence implicit-injection deprecation We can tackle the deprecation when we find the time. * fix: new linting errors after upgrade * fix: remove merge conflicts prettierignore * chore: upgrade to run node 12.22 when building binaries
2022-03-08 17:28:36 +00:00
schedule('afterRender', this, () => (this.isActive = false));
this.activeDatum = null;
this.activeData = [];
2018-09-07 16:59:02 +00:00
});
}
2018-09-07 16:59:02 +00:00
updateActiveDatum(mouseX) {
if (!this.data || !this.data.length) return;
2018-09-07 16:59:02 +00:00
const { xScale, xProp, yScale, yProp } = this;
let { dataProp, data } = this.args;
if (!dataProp) {
dataProp = 'data';
data = [{ data: this.data }];
}
// Map screen coordinates to data domain
2021-12-28 14:45:20 +00:00
const bisector = d3Array.bisector((d) => d[xProp]).left;
2018-09-07 16:59:02 +00:00
const x = xScale.invert(mouseX);
// Find the closest datum to the cursor for each series
const activeData = data
.map((series, seriesIndex) => {
const dataset = series[dataProp];
// If the dataset is empty, there can't be an activeData.
// This must be done here instead of preemptively in a filter to
// preserve the seriesIndex value.
if (!dataset.length) return null;
const index = bisector(dataset, x, 1);
// The data point on either side of the cursor
const dLeft = dataset[index - 1];
const dRight = dataset[index];
let datum;
// If there is only one point, it's the activeDatum
if (dLeft && !dRight) {
datum = dLeft;
} else {
// Pick the closer point
datum = x - dLeft[xProp] > dRight[xProp] - x ? dRight : dLeft;
}
return {
series,
datum: {
formattedX: this.xFormat(this.args.timeseries)(datum[xProp]),
formattedY: this.yFormat()(datum[yProp]),
datum,
},
index: data.length - seriesIndex - 1,
};
})
.compact();
// Of the selected data, determine which is closest
const closestDatum = activeData
.slice()
2021-12-28 16:08:12 +00:00
.sort(
(a, b) =>
Math.abs(a.datum.datum[xProp] - x) -
Math.abs(b.datum.datum[xProp] - x)
)[0];
// If any other selected data are beyond a distance threshold, drop them from the list
// xScale is used here to measure distance in screen-space rather than data-space.
const dist = Math.abs(xScale(closestDatum.datum.datum[xProp]) - mouseX);
const filteredData = activeData.filter(
2021-12-28 14:45:20 +00:00
(d) => Math.abs(xScale(d.datum.datum[xProp]) - mouseX) < dist + 10
);
2018-09-07 16:59:02 +00:00
this.activeData = filteredData;
this.activeDatum = closestDatum.datum.datum;
this.tooltipPosition = {
left: xScale(this.activeDatum[xProp]),
top: yScale(this.activeDatum[yProp]) - 10,
};
}
2018-09-07 16:59:02 +00:00
// The renderChart method should only ever be responsible for runtime calculations
// and appending d3 created elements to the DOM (such as axes).
renderChart() {
// There is nothing to do if the element hasn't been inserted yet
if (!this.element) return;
// Create the axes to get the dimensions of the resulting
2018-09-07 16:59:02 +00:00
// svg elements
this.mountD3Elements();
Upgrade Ember and friends 3.28 (#12215) * chore: upgrade forward compatible packages * chore: v3.20.2...v3.24.0 * chore: silence string prototype extension deprecation * refact: don't test clicking disabled button job-list Recent test-helper upgrades will guard against clicking disabled buttons as this is not something that real users can do. We need to change our tests accordingly. * fix: await async test helper `expectError` We have to await this async test function otherwise the test's rendering context will be torn down before we run assertions against it. * fix: don't try to click disabled two-step-button Recent test-helper updates prohibit clicking disabled buttons. We need to adapt the tests accordingly. * fix: recommendation-accordion Use up-to-date semantics for handling list-accordion closing in recommendation-accordion. * fixes toggling recommendation-accordion toggle. * fix: simple-unless linting error application.hbs There's no reason to use unless here - we can use if instead. * fix: no-quoteless-attributes recommendation accordion * fix: no-quoteless-attributes recommendation-chart * fix: allow `unless` - global-header.hbs This is a valid use of unless in our opinion. * fix: allow unless in job-diff This is not a great use for unless but we don't want to change this behavior atm. * fix: no-attrs-in-components list-pager There is no need to use this.attrs in classic components. When we will convert to glimmer we will use `@`-instead. * fix: simple-unless job/definition We can convert to a simple if here. * fix: allow inline-styles stats-box component To make linter happy. * fix: disable no-action and no-invalid-interactive Will be adressed in follow-up PRs. * chore: update ember-classic-decorator to latest * chore: upgrade ember-can to latest * chore: upgrade ember-composable-helpers to latest * chore: upgrade ember-concurrency * fix: recomputation deprecation `Trigger` schedule `do` on actions queue to work around recomputation deprecation when triggering Trigger on `did-insert`. * chore: upgrade ember-cli-string-helpers * chore: upgrade ember-copy * chore: upgrade ember-data-model-fragments * chore: upgrade ember-deprecation-workflow * chore: upgrade ember-inline-svg * chore: upgrade ember-modifier * chore: upgrade ember-truth-helpers * chore: upgrade ember-moment & ember-cli-moment-shim * chore: upgrade ember-power-select * chore: upgrade ember-responsive * chore: upgrade ember-sinon * chore: upgrade ember-cli-mirage For now we will stay on 2.2 - upgrades > 2.3 break the build. * chore: upgrade 3.24.0 to 3.28.5 * fix: add missing classic decorators on adapters * fix: missing classic decorators to serializers * fix: don't reopen Ember.Object anymore * fix: remove unused useNativeEvents ember-cli-page-objects doesn't provide this method anymore * fix: add missing attributeBindings for test-selectors ember-test-selectors doesn't provides automatic bindings for data-test-* attributes anymore. * fix: classic decorator for application serializer test * fix: remove `removeContext` from tests. It is unneeded and ember-cli-page-objects doesn't provides this method anymore. * fix: remove deprecations `run.*`-invocations * fix: `collapseWhitespace` in optimize test * fix: make sure to load async relationship before access * fix: dependent keys for relationship computeds We need to add `*.isFulfilled` as dependent keys for computeds that access async relationships. * fix: `computed.read`-invocations use `read` instead * chore: prettify templates * fix: use map instead of mapBy ember-cli-page-object Doesn't work with updated ember-cli-page-object anymore. * fix: remove remaining deprecated `run.*`-calls * chore: add more deprecations deprecation-workflow * fix: `implicit-injection`-deprecation All routes that add watchers will need to inject the store-service as the store service is internally used in watchers. * fix: more implicit injection deprecations * chore: silence implicit-injection deprecation We can tackle the deprecation when we find the time. * fix: new linting errors after upgrade * fix: remove merge conflicts prettierignore * chore: upgrade to run node 12.22 when building binaries
2022-03-08 17:28:36 +00:00
next(() => {
2018-09-07 16:59:02 +00:00
// Since each axis depends on the dimension of the other
// axis, the axes themselves are recomputed and need to
// be re-rendered.
this.mountD3Elements();
this.ready = true;
2019-03-26 07:46:44 +00:00
if (this.isActive) {
this.updateActiveDatum(this.latestMouseX);
2018-09-07 16:59:02 +00:00
}
});
}
2018-09-07 16:59:02 +00:00
@action
recomputeXAxis(el) {
if (!this.isDestroyed && !this.isDestroying) {
d3.select(el.querySelector('.x-axis')).call(this.xAxis);
}
}
@action
recomputeYAxis(el) {
if (!this.isDestroyed && !this.isDestroying) {
d3.select(el.querySelector('.y-axis')).call(this.yAxis);
}
}
2018-09-07 16:59:02 +00:00
mountD3Elements() {
2019-03-26 07:46:44 +00:00
if (!this.isDestroyed && !this.isDestroying) {
d3.select(this.element.querySelector('.x-axis')).call(this.xAxis);
d3.select(this.element.querySelector('.y-axis')).call(this.yAxis);
2021-12-28 16:08:12 +00:00
d3.select(this.element.querySelector('.y-gridlines')).call(
this.yGridlines
);
}
}
2018-09-07 16:59:02 +00:00
annotationClick(annotation) {
this.args.onAnnotationClick && this.args.onAnnotationClick(annotation);
}
2018-09-07 16:59:02 +00:00
@action
2018-09-07 16:59:02 +00:00
updateDimensions() {
2020-05-26 21:05:45 +00:00
const $svg = this.element.querySelector('svg');
2018-09-07 16:59:02 +00:00
this.height = $svg.clientHeight;
this.width = $svg.clientWidth;
2018-09-07 16:59:02 +00:00
this.renderChart();
}
}