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

Make d3 place nicely with object values #62004

Merged
merged 3 commits into from
Apr 2, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ function DateRangesParamEditor({
</EuiText>
<EuiSpacer size="s" />

{ranges.map(({ from, to, id }) => {
{ranges.map(({ from, to, id }, index) => {
const deleteBtnTitle = i18n.translate(
'visDefaultEditor.controls.dateRanges.removeRangeButtonAriaLabel',
{
Expand Down Expand Up @@ -154,6 +154,7 @@ function DateRangesParamEditor({
placeholder={FROM_PLACEHOLDER}
value={from || ''}
onChange={ev => onChangeRange(id, 'from', ev.target.value)}
data-test-subj={`visEditorDateRange${index}__from`}
/>
</EuiFlexItem>
<EuiFlexItem grow={false}>
Expand All @@ -168,6 +169,7 @@ function DateRangesParamEditor({
description: 'End of a date range, e.g. From 2018-02-26 *To* 2018-02-28',
}
)}
data-test-subj={`visEditorDateRange${index}__to`}
compressed
fullWidth={true}
isInvalid={areBothEmpty || !validateDateMath(to)}
Expand Down Expand Up @@ -203,7 +205,12 @@ function DateRangesParamEditor({

<EuiSpacer size="s" />
<EuiFlexItem>
<EuiButtonEmpty iconType="plusInCircleFilled" onClick={onAddRange} size="xs">
<EuiButtonEmpty
iconType="plusInCircleFilled"
onClick={onAddRange}
size="xs"
data-test-subj="visEditorAddDateRange"
>
<FormattedMessage
id="visDefaultEditor.controls.dateRanges.addRangeButtonLabel"
defaultMessage="Add range"
Expand Down
36 changes: 33 additions & 3 deletions src/legacy/core_plugins/vis_type_vislib/public/vislib/lib/data.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,26 @@ import { orderXValues } from '../components/zero_injection/ordered_x_keys';
import { labels } from '../components/labels/labels';
import { getFormatService } from '../../services';

// X axis and split series values in a data table can sometimes be objects,
// e.g. when working with date ranges. d3 casts all ordinal values to strings
// which is a problem for these objects because they just return `[object Object]`
// and thus all map to the same value.
// This little helper overwrites the toString method of an object and keeps it the
// same otherwise - allowing d3 to correctly work with the values.
class D3MappableObject {
constructor(data) {
for (const key in data) {
if (data.hasOwnProperty(key)) {
this[key] = data[key];
}
}
}

toString() {
return JSON.stringify(this);
}
}

/**
* Provides an API for pulling values off the data
* and calculating values using the data
Expand Down Expand Up @@ -52,9 +72,14 @@ export class Data {
const copyChart = data => {
const newData = {};
Object.keys(data).forEach(key => {
if (key !== 'series') {
newData[key] = data[key];
} else {
if (key === 'xAxisOrderedValues') {
newData[key] = data[key].map(val => {
if (typeof val === 'object') {
return new D3MappableObject(val);
}
return val;
});
} else if (key === 'series') {
newData[key] = data[key].map(seri => {
const converter = getFormatService().deserialize(seri.format);
const zConverter = getFormatService().deserialize(seri.zFormat);
Expand All @@ -67,12 +92,17 @@ export class Data {
const newVal = _.clone(val);
newVal.extraMetrics = val.extraMetrics;
newVal.series = val.series || seri.label;
if (typeof newVal.x === 'object') {
newVal.x = new D3MappableObject(newVal.x);
}
return newVal;
}),
yAxisFormatter: val => converter.convert(val),
zAxisFormatter: val => zConverter.convert(val),
};
});
} else {
newData[key] = data[key];
}
});

Expand Down
19 changes: 19 additions & 0 deletions test/functional/apps/visualize/_vertical_bar_chart.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,25 @@ export default function({ getService, getPageObjects }) {
});
});

describe('bar charts range on x axis', () => {
it('should individual bars for each configured range', async function() {
await PageObjects.visualize.navigateToNewVisualization();
await PageObjects.visualize.clickVerticalBarChart();
await PageObjects.visualize.clickNewSearch();
await PageObjects.timePicker.setDefaultAbsoluteRange();
await PageObjects.visEditor.clickBucket('X-axis');
log.debug('Aggregation = Date Range');
await PageObjects.visEditor.selectAggregation('Date Range');
log.debug('Field = @timestamp');
await PageObjects.visEditor.selectField('@timestamp');
await PageObjects.visEditor.clickAddDateRange();
await PageObjects.visEditor.setDateRangeByIndex('1', 'now-2w/w', 'now-1w/w');
await PageObjects.visEditor.clickGo();
const bottomLabels = await PageObjects.visChart.getXAxisLabels();
expect(bottomLabels.length).to.be(2);
});
});

// FLAKY: https://github.com/elastic/kibana/issues/22322
describe.skip('vertical bar chart flaky part', function() {
const vizName1 = 'Visualization VerticalBarChart';
Expand Down
9 changes: 9 additions & 0 deletions test/functional/page_objects/visualize_editor_page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,15 @@ export function VisualizeEditorPageProvider({ getService, getPageObjects }: FtrP
await radioBtn.click();
}

public async clickAddDateRange() {
await testSubjects.click(`visEditorAddDateRange`);
}

public async setDateRangeByIndex(index: string, from: string, to: string) {
await testSubjects.setValue(`visEditorDateRange${index}__from`, from);
await testSubjects.setValue(`visEditorDateRange${index}__to`, to);
}

/**
* Adds new bucket
* @param bucketName bucket name, like 'X-axis', 'Split rows', 'Split series'
Expand Down