Skip to content

Commit

Permalink
[Feature] Move series side config from data config panel to chart sty…
Browse files Browse the repository at this point in the history
…les (opensearch-project#1199)

* series side config moved to chart styles

Signed-off-by: Ramneet Chopra <ramneet_chopra@persistent.com>

* yarn test

Signed-off-by: Ramneet Chopra <ramneet_chopra@persistent.com>

* minor fixes

Signed-off-by: Ramneet Chopra <ramneet_chopra@persistent.com>

* layout for multi y axis fixed

Signed-off-by: Ramneet Chopra <ramneet_chopra@persistent.com>

Signed-off-by: Ramneet Chopra <ramneet_chopra@persistent.com>
  • Loading branch information
ramneet-persistent authored Nov 2, 2022
1 parent 43c2eaa commit 284db6c
Show file tree
Hide file tree
Showing 8 changed files with 217 additions and 42 deletions.
5 changes: 5 additions & 0 deletions common/constants/explorer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ export const PLOTLY_GAUGE_COLUMN_NUMBER = 4;
export const APP_ANALYTICS_TAB_ID_REGEX = /application-analytics-tab.+/;
export const DEFAULT_AVAILABILITY_QUERY = 'stats count() by span( timestamp, 1h )';
export const ADD_BUTTON_TEXT = '+ Add color theme';
export const ADD_SERIES_POSITION_TEXT = '+ Add label position';
export const NUMBER_INPUT_MIN_LIMIT = 1;

export const VIZ_CONTAIN_XY_AXIS = [
Expand Down Expand Up @@ -280,3 +281,7 @@ export const DATA_CONFIG_HINTS_INFO = {
[BREAKDOWNS]:
"Defines how each series is broken down. Breakdowns are 'by' clauses that subdivide the existing series.",
};
export const SERIES_POSITION_OPTIONS = [
{ id: htmlIdGenerator('ct')(), label: 'Left', side: 'left' },
{ id: htmlIdGenerator('ct')(), label: 'Right', side: 'right' },
];
Original file line number Diff line number Diff line change
Expand Up @@ -1885,6 +1885,13 @@ exports[`Utils helper functions renders displayVisualization function 2`] = `
},
],
},
Object {
"editor": [Function],
"id": "yaxis-side",
"mapTo": "seriesPosition",
"name": "Series label position",
"schemas": Array [],
},
Object {
"editor": [Function],
"id": "color-theme",
Expand Down Expand Up @@ -2386,6 +2393,13 @@ exports[`Utils helper functions renders displayVisualization function 2`] = `
},
],
},
Object {
"editor": [Function],
"id": "yaxis-side",
"mapTo": "seriesPosition",
"name": "Series label position",
"schemas": Array [],
},
Object {
"editor": [Function],
"id": "color-theme",
Expand Down Expand Up @@ -2901,6 +2915,13 @@ exports[`Utils helper functions renders displayVisualization function 2`] = `
},
],
},
Object {
"editor": [Function],
"id": "yaxis-side",
"mapTo": "seriesPosition",
"name": "Series label position",
"schemas": Array [],
},
Object {
"editor": [Function],
"id": "color-theme",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1410,6 +1410,13 @@ exports[`Config panel component Renders config panel with visualization data 1`]
},
],
},
Object {
"editor": [Function],
"id": "yaxis-side",
"mapTo": "seriesPosition",
"name": "Series label position",
"schemas": Array [],
},
Object {
"editor": [Function],
"id": "color-theme",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*/

import React, { Fragment, useCallback } from 'react';
import {
EuiButton,
EuiAccordion,
EuiFormRow,
EuiSpacer,
EuiIcon,
EuiFlexGroup,
EuiFlexItem,
htmlIdGenerator,
EuiComboBox,
} from '@elastic/eui';
import { isEmpty } from 'lodash';
import {
ADD_SERIES_POSITION_TEXT,
AGGREGATIONS,
SERIES_POSITION_OPTIONS,
} from '../../../../../../../../common/constants/explorer';
import { getPropName } from '../../../../../utils/utils';

export const ConfigYAxisSide = ({
visualizations,
schemas,
vizState = [],
handleConfigChange,
sectionName = 'Series position',
}: any) => {
const { data } = visualizations;
const { metadata: { fields = [] } = {} } = data?.rawVizData;
const { dataConfig = {} } = data?.userConfigs;

const options = (dataConfig[AGGREGATIONS] && dataConfig[AGGREGATIONS].length !== 0
? dataConfig[AGGREGATIONS]
: fields
).map((optionItem) => ({
...optionItem,
label: getPropName(optionItem),
side: 'left',
className: 'color-theme-combo-box-option',
ctid: htmlIdGenerator('ct')(),
}));

const getUpdatedOptions = () =>
options.filter((option) => !vizState.some((vizOpt) => option.label === vizOpt?.label));

const handleColorThemeChange = useCallback(
(ctId, ctName) => (event) => {
const value = event.length ? event[0][ctName] : '';
handleConfigChange([
...vizState.map((ct) => {
if (ctId !== ct.ctid) return ct;
return {
...ct,
[ctName]: value,
};
}),
]);
},
[vizState, handleConfigChange]
);

const handleDeletePosition = useCallback(
(ctId) => (event) => handleConfigChange([...vizState.filter((ct) => ct.ctid !== ctId)]),
[vizState, handleConfigChange]
);

const handleAddPosition = useCallback(() => {
const res = isEmpty(vizState)
? [options.length ? options[0] : { id: htmlIdGenerator('ct')(), label: '', side: 'left' }]
: [
...vizState,
...options.filter((option) => !vizState.some((vizOpt) => option.label === vizOpt?.label)),
];
handleConfigChange(res);
}, [vizState, handleConfigChange]);

return (
<EuiAccordion
initialIsOpen
id={`configPanel__${sectionName}`}
buttonContent={sectionName}
paddingSize="s"
>
<EuiButton fullWidth size="s" onClick={handleAddPosition}>
{ADD_SERIES_POSITION_TEXT}
</EuiButton>
<EuiSpacer size="s" />
{!isEmpty(vizState) &&
vizState.map((ct) => {
return (
<Fragment key={ct.ctid}>
<EuiFormRow fullWidth label="">
<EuiFlexGroup alignItems="center" gutterSize="xs">
<EuiFlexItem grow={4}>
<EuiFormRow helpText="Field">
<EuiComboBox
id={ct.ctid}
placeholder="Select a field"
options={getUpdatedOptions()}
singleSelection
selectedOptions={ct.label !== '' ? [ct] : []}
onChange={handleColorThemeChange(ct.ctid, 'label')}
aria-label="series-dropdown"
/>
</EuiFormRow>
</EuiFlexItem>
<EuiFlexItem grow={3}>
<EuiFormRow helpText="Position">
<EuiComboBox
id={ct.ctid}
placeholder="Select position"
options={SERIES_POSITION_OPTIONS}
singleSelection
selectedOptions={
ct.side !== ''
? SERIES_POSITION_OPTIONS.filter(
(positionItem) => positionItem.side === ct.side
)
: []
}
onChange={handleColorThemeChange(ct.ctid, 'side')}
aria-label="series-position-dropdown"
/>
</EuiFormRow>
</EuiFlexItem>
<EuiFlexItem grow={1}>
<EuiFormRow>
<EuiIcon type="trash" onClick={handleDeletePosition(ct.ctid)} />
</EuiFormRow>
</EuiFlexItem>
</EuiFlexGroup>
</EuiFormRow>
</Fragment>
);
})}
</EuiAccordion>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -306,11 +306,6 @@ export const DataConfigPanelItem = ({
fillVisDataInStore({ visData: visData, query, visConfMetadata, visMeta });
};

const isPositionButtonVisible = (sectionName: string) =>
sectionName === AGGREGATIONS &&
(visualizations.vis.name === VIS_CHART_TYPES.Line ||
visualizations.vis.name === VIS_CHART_TYPES.Scatter);

const getTimeStampFilteredFields = (options: IField[]) =>
filter(options, (i: IField) => i.type !== TIMESTAMP);

Expand Down Expand Up @@ -381,19 +376,6 @@ export const DataConfigPanelItem = ({
)}
{/* Show input fields for dimensions */}
{!isAggregations && getCommonDimensionsField(selectedObj, name)}
{isPositionButtonVisible(name) && (
<EuiFormRow label="Side">
<ButtonGroupItem
legend="Side"
groupOptions={[
{ id: 'left', label: 'Left' },
{ id: 'right', label: 'Right' },
]}
idSelected={selectedObj.side || 'right'}
handleButtonChange={(id: string) => updateList(id, 'side')}
/>
</EuiFormRow>
)}
</EuiPanel>
<EuiSpacer size="s" />
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,4 @@ export { ButtonGroupItem } from './config_button_group';
export { TextInputFieldItem } from './config_text_input';
export { ConfigBarChartStyles } from './config_bar_chart_styles';
export { ConfigAvailability } from './config_availability';
export { ConfigYAxisSide } from './config_yaxis_side';
56 changes: 32 additions & 24 deletions public/components/visualizations/charts/lines/line.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ export const Line = ({ visualizations, layout, config }: any) => {
userConfigs: {
dataConfig: {
chartStyles = {},
seriesPosition = [],
legend = {},
span = {},
colorTheme = [],
Expand Down Expand Up @@ -85,7 +86,8 @@ export const Line = ({ visualizations, layout, config }: any) => {
colorTheme.find((colorSelected) => colorSelected.name.name === field)?.color) ||
PLOTLY_COLOR[index % PLOTLY_COLOR.length];
const timestampField = find(fields, (field) => field.type === 'timestamp');
let xaxis = [timestampField];
const xaxis = [timestampField];
let multiYAxisLayout = {};

if (!timestampField || isEmpty(series)) return <EmptyPlaceholder icon={icontype} />;

Expand All @@ -94,31 +96,48 @@ export const Line = ({ visualizations, layout, config }: any) => {
return traces.map((trace, idx: number) => {
const selectedColor = getSelectedColorTheme(trace.aggName, idx);
const fillColor = hexToRgb(selectedColor, fillOpacity);
const side = seriesPosition.find((seriesItem) => seriesItem.label === trace.name);
const multiYaxis = { yaxis: `y${idx + 1}` };

multiYAxisLayout = {
...multiYAxisLayout,
[`yaxis${idx > 0 ? idx + 1 : ''}`]: {
titlefont: {
color: selectedColor,
},
automargin: true,
tickfont: {
color: selectedColor,
...(labelSize && {
size: labelSize,
}),
},
...(idx > 0 && { overlaying: 'y' }),
side: side ? side.side : 'left',
},
};

return {
...trace,
hoverinfo: tooltipMode === 'hidden' ? 'none' : tooltipText,
type: 'line',
mode,
...{
fill: 'tozeroy',
fillcolor: fillColor,
},
fill: 'tozeroy',
fillcolor: fillColor,
line: {
shape: lineShape,
width: lineWidth,
color: selectedColor,
},
marker: {
size: markerSize,
...{
color: fillColor,
line: {
color: selectedColor,
width: lineWidth,
},
color: fillColor,
line: {
color: selectedColor,
width: lineWidth,
},
},
...(idx >= 1 && multiYaxis),
};
});
};
Expand All @@ -143,16 +162,7 @@ export const Line = ({ visualizations, layout, config }: any) => {
transformPreprocessedDataToTraces(preprocessJsonData(jsonData, visConfig), visConfig),
traceStyles
);
}, [
chartStyles,
jsonData,
dimensions,
series,
span,
breakdowns,
panelOptions,
tooltipOptions,
]);
}, [chartStyles, jsonData, dimensions, series, span, breakdowns, panelOptions, tooltipOptions]);

const mergedLayout = useMemo(() => {
const axisLabelsStyle = {
Expand Down Expand Up @@ -181,9 +191,7 @@ export const Line = ({ visualizations, layout, config }: any) => {
tickangle: tickAngle,
...axisLabelsStyle,
},
yaxis: {
...axisLabelsStyle,
},
...multiYAxisLayout,
showlegend: showLegend,
margin: PLOT_MARGIN,
};
Expand Down
8 changes: 8 additions & 0 deletions public/components/visualizations/charts/lines/line_type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
ConfigLegend,
InputFieldItem,
ConfigColorTheme,
ConfigYAxisSide,
} from '../../../event_analytics/explorer/visualizations/config_panel/config_panes/config_controls';
import { ConfigAvailability } from '../../../event_analytics/explorer/visualizations/config_panel/config_panes/config_controls/config_availability';
import {
Expand Down Expand Up @@ -204,6 +205,13 @@ export const createLineTypeDefinition = (params: any = {}) => ({
},
],
},
{
id: 'yaxis-side',
name: 'Series label position',
editor: ConfigYAxisSide,
mapTo: 'seriesPosition',
schemas: [],
},
{
id: 'color-theme',
name: 'Color theme',
Expand Down

0 comments on commit 284db6c

Please sign in to comment.