Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[ML] Migrate Explorer Charts to React. #22622

Merged
merged 8 commits into from
Sep 3, 2018
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,11 @@
* you may not use this file except in compliance with the Elastic License.
*/

import ngMock from 'ng_mock';
import expect from 'expect.js';

describe('ML - mlChartTooltipService', () => {
let mlChartTooltipService;

beforeEach(ngMock.module('kibana'));
beforeEach(() => {
ngMock.inject(function ($injector) {
mlChartTooltipService = $injector.get('mlChartTooltipService');
});
});
import { mlChartTooltipService } from '../chart_tooltip_service';

describe('ML - mlChartTooltipService', () => {
it('service API duck typing', () => {
expect(mlChartTooltipService).to.be.an('object');
expect(mlChartTooltipService.show).to.be.a('function');
Expand Down
71 changes: 4 additions & 67 deletions x-pack/plugins/ml/public/components/chart_tooltip/chart_tooltip.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@
*/



import $ from 'jquery';
import template from './chart_tooltip.html';

import { uiModules } from 'ui/modules';
const module = uiModules.get('apps/ml');

module.directive('mlChartTooltip', function (mlChartTooltipService) {
import { mlChartTooltipService } from './chart_tooltip_service';

module.directive('mlChartTooltip', function () {
return {
restrict: 'E',
replace: true,
Expand All @@ -21,67 +21,4 @@ module.directive('mlChartTooltip', function (mlChartTooltipService) {
mlChartTooltipService.element = element;
}
};
})
.service('mlChartTooltipService', function ($timeout) {
this.element = null;
this.fadeTimeout = null;
const doc = document.documentElement;
const FADE_TIMEOUT_MS = 200;

this.show = function (contents, target, offset = { x: 0, y: 0 }) {
if (this.element !== null) {

// if a previous fade out was happening, stop it
if (this.fadeTimeout !== null) {
$timeout.cancel(this.fadeTimeout);
}

// populate the tooltip contents
this.element.html(contents);

// side bar width
const navOffset = $('.global-nav').width();
const contentWidth = $('body').width() - navOffset - 10;
const tooltipWidth = this.element.width();
const scrollTop = (window.pageYOffset || doc.scrollTop) - (doc.clientTop || 0);

const pos = target.getBoundingClientRect();
const x = (pos.left + (offset.x) + 4) - navOffset;
const y = pos.top + (offset.y) + scrollTop;

if (x + tooltipWidth > contentWidth) {
// the tooltip is hanging off the side of the page,
// so move it to the other side of the target
this.element.css({
'left': x - (tooltipWidth + offset.x + 22),
'top': (y - 28)
});
} else {
this.element.css({
'left': x,
'top': (y - 28)
});
}

this.element.css({
'opacity': '0.9',
'display': 'block'
});
}
};

this.hide = function () {
if (this.element !== null) {
this.element.css({
'opacity': '0',
});

// after the fade out transition has finished, set the display to
// none so it doesn't block any mouse events underneath it.
this.fadeTimeout = $timeout(() => {
this.element.css('display', 'none');
this.fadeTimeout = null;
}, FADE_TIMEOUT_MS);
}
};
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/



import $ from 'jquery';

const doc = document.documentElement;
const FADE_TIMEOUT_MS = 200;

export const mlChartTooltipService = {
element: null,
fadeTimeout: null,
};

mlChartTooltipService.show = function (contents, target, offset = { x: 0, y: 0 }) {
if (this.element === null) {
return;
}

// if a previous fade out was happening, stop it
if (this.fadeTimeout !== null) {
clearTimeout(this.fadeTimeout);
}

// populate the tooltip contents
this.element.html(contents);

// side bar width
const navOffset = $('.global-nav').width();
const contentWidth = $('body').width() - navOffset - 10;
const tooltipWidth = this.element.width();
const scrollTop = (window.pageYOffset || doc.scrollTop) - (doc.clientTop || 0);

const pos = target.getBoundingClientRect();
const x = (pos.left + (offset.x) + 4) - navOffset;
const y = pos.top + (offset.y) + scrollTop;

if (x + tooltipWidth > contentWidth) {
// the tooltip is hanging off the side of the page,
// so move it to the other side of the target
this.element.css({
'left': x - (tooltipWidth + offset.x + 22),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit, json keys should not be strings

'top': (y - 28)
});
} else {
this.element.css({
'left': x,
'top': (y - 28)
});
}

this.element.css({
'opacity': '0.9',
'display': 'block'
});
};

mlChartTooltipService.hide = function () {
if (this.element === null) {
return;
}

this.element.css({
'opacity': '0',
});

// after the fade out transition has finished, set the display to
// none so it doesn't block any mouse events underneath it.
this.fadeTimeout = setTimeout(() => {
this.element.css('display', 'none');
this.fadeTimeout = null;
}, FADE_TIMEOUT_MS);
};
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,13 @@ import { parseInterval } from 'ui/utils/parse_interval';
import { numTicksForDateFormat } from 'plugins/ml/util/chart_utils';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it worth making all these imports relative paths?

import { calculateTextWidth } from 'plugins/ml/util/string_utils';
import { IntervalHelperProvider } from 'plugins/ml/util/ml_time_buckets';
import { mlChartTooltipService } from '../../components/chart_tooltip/chart_tooltip_service';

import { uiModules } from 'ui/modules';
import { timefilter } from 'ui/timefilter';
const module = uiModules.get('apps/ml');

module.directive('mlDocumentCountChart', function (
Private,
mlChartTooltipService) {

module.directive('mlDocumentCountChart', function (Private) {
function link(scope, element, attrs) {
const svgWidth = attrs.width ? +attrs.width : 400;
const svgHeight = scope.height = attrs.height ? +attrs.height : 400;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,12 @@ import d3 from 'd3';

import { numTicks } from 'plugins/ml/util/chart_utils';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use relative paths?

import { ordinalSuffix } from 'ui/utils/ordinal_suffix';
import { mlChartTooltipService } from '../../components/chart_tooltip/chart_tooltip_service';

import { uiModules } from 'ui/modules';
const module = uiModules.get('apps/ml');

module.directive('mlMetricDistributionChart', function (mlChartTooltipService) {
module.directive('mlMetricDistributionChart', function () {

function link(scope, element, attrs) {
const svgWidth = attrs.width ? +attrs.width : 400;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/



import './styles/main.less';

import PropTypes from 'prop-types';
import React from 'react';

export function LoadingIndicator({ height }) {
walterra marked this conversation as resolved.
Show resolved Hide resolved
height = height ? +height : 100;
return (
<div className="ml-loading-indicator" style={{ height: `${height}px` }}>
<div className="loading-spinner"><i className="fa fa-spinner fa-spin" /></div>
</div>
);
}
LoadingIndicator.propTypes = {
height: PropTypes.number
};
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/* angular */
ml-loading-indicator {
.loading-indicator {
text-align: center;
Expand All @@ -12,3 +13,17 @@ ml-loading-indicator {
}
}
}

/* react */
.ml-loading-indicator {
text-align: center;
font-size: 17px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;

.loading-spinner {
font-size: 24px;
}
}
14 changes: 2 additions & 12 deletions x-pack/plugins/ml/public/explorer/explorer.html
Original file line number Diff line number Diff line change
Expand Up @@ -145,18 +145,8 @@ <h4 class="euiTitle euiTitle--small">No {{swimlaneViewByFieldName}} influencers
</div>
</div>

<div ng-controller="MlExplorerChartsContainerController" class="euiText">
<ml-explorer-charts-container
series-to-plot="seriesToPlot"
time-field-name="timeFieldName"
plot-earliest="plotEarliest"
plot-latest="plotLatest"
selected-earliest="selectedEarliest"
selected-latest="selectedLatest"
charts-per-row="chartsPerRow"
layout-cells-per-chart="layoutCellsPerChart"
too-many-buckets="tooManyBuckets">
</ml-explorer-charts-container>
<div class="euiText explorer-charts">
<ml-explorer-charts-container />
</div>

<ml-anomalies-table
Expand Down
Loading