-
- {(detectorLabel.length > 0 && entityFields.length > 0) && (
- {detectorLabel} -
- )}
- {(detectorLabel.length > 0 && entityFields.length === 0) && (
- {detectorLabel}
- )}
- {entityFields.map((entity, j) => {
- return (
- {entity.fieldName} {entity.fieldValue}
- );
- })}
-
-
} position="left" size="s" />
+
+
({
}
}));
+// The mocks for ui/chrome and ui/timefilter are copied from charts_utils.test.js
+// TODO: Refactor the involved tests to avoid this duplication
+jest.mock('ui/chrome',
+ () => ({
+ getBasePath: () => {
+ return '';
+ },
+ getUiSettingsClient: () => {
+ return {
+ get: (key) => {
+ switch (key) {
+ case 'timepicker:timeDefaults':
+ return { from: 'now-15m', to: 'now', mode: 'quick' };
+ case 'timepicker:refreshIntervalDefaults':
+ return { pause: false, value: 0 };
+ default:
+ throw new Error(`Unexpected config key: ${key}`);
+ }
+ }
+ };
+ },
+ }), { virtual: true });
+
+import moment from 'moment';
+import { timefilter } from 'ui/timefilter';
+
+timefilter.enableTimeRangeSelector();
+timefilter.enableAutoRefreshSelector();
+timefilter.setTime({
+ from: moment(seriesConfig.selectedEarliest).toISOString(),
+ to: moment(seriesConfig.selectedLatest).toISOString()
+});
+
import { shallow } from 'enzyme';
import React from 'react';
@@ -69,8 +102,8 @@ describe('ExplorerChartsContainer', () => {
mlChartTooltipService={mlChartTooltipService}
/>);
- // Only do a snapshot of the label section, the included
- // ExplorerChart component does that in its own tests anyway.
- expect(wrapper.find('.explorer-chart-label')).toMatchSnapshot();
+ // We test child components with snapshots separately
+ // so we just do some high level sanity check here.
+ expect(wrapper.find('.ml-explorer-chart-container').children()).toHaveLength(3);
});
});
diff --git a/x-pack/plugins/ml/public/explorer/explorer_charts/styles/explorer_chart.less b/x-pack/plugins/ml/public/explorer/explorer_charts/styles/explorer_chart.less
index de8e351685f7e..267cebc9a6e2f 100644
--- a/x-pack/plugins/ml/public/explorer/explorer_charts/styles/explorer_chart.less
+++ b/x-pack/plugins/ml/public/explorer/explorer_charts/styles/explorer_chart.less
@@ -3,7 +3,7 @@ ml-explorer-chart,
display: block;
padding-bottom: 10px;
- svg {
+ .ml-explorer-chart-svg {
font-size: 12px;
font-family: "Open Sans", "Lato", "Helvetica Neue", Helvetica, Arial;
@@ -106,3 +106,7 @@ ml-explorer-chart,
stroke-opacity: 0.65;
}
}
+
+.ml-explorer-chart-content-wrapper {
+ height: 215px;
+}
diff --git a/x-pack/plugins/ml/public/explorer/explorer_charts/styles/explorer_charts_container.less b/x-pack/plugins/ml/public/explorer/explorer_charts/styles/explorer_charts_container.less
index 9d1f205f9b224..04a55fb0bc316 100644
--- a/x-pack/plugins/ml/public/explorer/explorer_charts/styles/explorer_charts_container.less
+++ b/x-pack/plugins/ml/public/explorer/explorer_charts/styles/explorer_charts_container.less
@@ -99,36 +99,13 @@
}
- .ml-explorer-chart-container {
- .explorer-chart-label {
- display: block;
- font-size: 13px;
- font-weight: normal;
-
- .explorer-chart-label-fields {
- vertical-align: top;
- /* account 80px for the "View" link */
- max-width: calc(~"100% - 80px");
- text-overflow: ellipsis;
- overflow: hidden;
- white-space: nowrap;
- display: inline-block;
- }
-
- .euiIcon {
- vertical-align: top;
- margin: 4px 0 0 4px;
- }
-
- a {
- float:right;
- padding-left: 5px;
- }
- }
-
- .content-wrapper {
- height: 215px;
- }
- }
}
}
+
+/* wrapper class for the top right alert icon and view button */
+.ml-explorer-chart-icons {
+ float:right;
+ padding-left: 5px;
+ /* counter-margin for EuiButtonEmpty's padding */
+ margin: 2px -8px 0 0;
+}
diff --git a/x-pack/plugins/ml/public/util/chart_utils.js b/x-pack/plugins/ml/public/util/chart_utils.js
index df0a1121ee7a9..0031cd5c74a7c 100644
--- a/x-pack/plugins/ml/public/util/chart_utils.js
+++ b/x-pack/plugins/ml/public/util/chart_utils.js
@@ -228,6 +228,15 @@ export function getTickValues(startTimeMs, tickInterval, earliest, latest) {
return tickValues;
}
+const LABEL_WRAP_THRESHOLD = 60;
+
+// Checks if the string length of a chart label (detector description
+// and entity fields) is above LABEL_WRAP_THRESHOLD.
+export function isLabelLengthAboveThreshold({ detectorLabel, entityFields }) {
+ const labelLength = (detectorLabel.length + entityFields.map(d => `${d.fieldName} ${d.fieldValue}`).join(' ').length);
+ return (labelLength > LABEL_WRAP_THRESHOLD);
+}
+
// To get xTransform it would be nicer to use d3.transform, but that doesn't play well with JSDOM.
// So this uses a regex variant because we definitely want test coverage for the label removal.
// Once JSDOM supports SVGAnimatedTransformList we can use this simpler inline version:
diff --git a/x-pack/plugins/ml/public/util/chart_utils.test.js b/x-pack/plugins/ml/public/util/chart_utils.test.js
index d44cc933d0ad2..88ae5551f8797 100644
--- a/x-pack/plugins/ml/public/util/chart_utils.test.js
+++ b/x-pack/plugins/ml/public/util/chart_utils.test.js
@@ -6,6 +6,9 @@
import seriesConfig from '../explorer/explorer_charts/__mocks__/mock_series_config_filebeat';
+// A copy of these mocks for ui/chrome and ui/timefilter are also
+// used in explorer_charts_container.test.js.
+// TODO: Refactor the involved tests to avoid this duplication
jest.mock('ui/chrome',
() => ({
getBasePath: () => {
@@ -47,6 +50,7 @@ import { timefilter } from 'ui/timefilter';
import {
getExploreSeriesLink,
getTickValues,
+ isLabelLengthAboveThreshold,
getXTransform,
removeLabelOverlap
} from './chart_utils';
@@ -134,6 +138,23 @@ describe('getTickValues', () => {
});
});
+describe('isLabelLengthAboveThreshold', () => {
+
+ test('short label', () => {
+ const isLongLabel = isLabelLengthAboveThreshold({
+ detectorLabel: 'count',
+ entityFields: seriesConfig.entityFields
+ });
+ expect(isLongLabel).toBeFalsy();
+ });
+
+ test('long label', () => {
+ const isLongLabel = isLabelLengthAboveThreshold(seriesConfig);
+ expect(isLongLabel).toBeTruthy();
+ });
+
+});
+
describe('getXTransform', () => {
const expectedXTransform = 0.007167499999999999;