Skip to content

Commit

Permalink
[D&D] Adds Bar line and Area charts to Wizard (opensearch-project#2266)
Browse files Browse the repository at this point in the history
* Working histogram

Signed-off-by: Ashwin Pc <ashwinpc@amazon.com>

* Adds histogram options

Signed-off-by: Ashwin Pc <ashwinpc@amazon.com>

* Adds line chart

Signed-off-by: Ashwin Pc <ashwinpc@amazon.com>

* Adds area chart

Signed-off-by: Ashwin Pc <ashwinpc@amazon.com>

* updates nav sizes

Signed-off-by: Ashwin Pc <ashwinpc@amazon.com>

* adds resizeable container to right nav

Signed-off-by: Ashwin Pc <ashwinpc@amazon.com>

* Misc fixes

Signed-off-by: Ashwin Pc <ashwinpc@amazon.com>

* Adds chart switcher test

Signed-off-by: Ashwin Pc <ashwinpc@amazon.com>

* Github comment feedback

Co-authored-by: Josh Romero <rmerqg@amazon.com>
Signed-off-by: Ashwin Pc <ashwinpc@amazon.com>

* Updates copy

Signed-off-by: Ashwin Pc <ashwinpc@amazon.com>

Signed-off-by: Ashwin Pc <ashwinpc@amazon.com>
Co-authored-by: Josh Romero <rmerqg@amazon.com>
Signed-off-by: Sergey V. Osipov <sipopo@yandex.ru>
  • Loading branch information
2 people authored and sipopo committed Dec 16, 2022
1 parent 59479fb commit a7115b2
Show file tree
Hide file tree
Showing 35 changed files with 811 additions and 80 deletions.
2 changes: 2 additions & 0 deletions src/plugins/vis_type_vislib/public/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,6 @@ export function plugin(initializerContext: PluginInitializerContext) {
return new Plugin(initializerContext);
}

export { getConfigCollections } from './utils/collections';

export * from './types';
2 changes: 2 additions & 0 deletions src/plugins/vis_type_vislib/public/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -106,3 +106,5 @@ export interface BasicVislibParams extends CommonVislibParams {
times: TimeMarker[];
type: string;
}

export { Positions };
2 changes: 1 addition & 1 deletion src/plugins/visualizations/public/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ export { Vis } from './vis';
export { TypesService } from './vis_types/types_service';
export { VISUALIZE_EMBEDDABLE_TYPE, VIS_EVENT_TO_TRIGGER } from './embeddable';
export { VisualizationContainer, VisualizationNoResults } from './components';
export { getSchemas as getVisSchemas } from './legacy/build_pipeline';
export { getSchemas as getVisSchemas, buildVislibDimensions } from './legacy/build_pipeline';

/** @public types */
export { VisualizationsSetup, VisualizationsStart };
Expand Down
3 changes: 2 additions & 1 deletion src/plugins/wizard/opensearch_dashboards.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@
"dashboard",
"visualizations",
"opensearchUiShared",
"visDefaultEditor"
"visDefaultEditor",
"visTypeVislib"
],
"optionalPlugins": []
}
2 changes: 1 addition & 1 deletion src/plugins/wizard/public/application/_variables.scss
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,4 @@
@import "@elastic/eui/src/global_styling/variables/form";

$osdHeaderOffset: $euiHeaderHeightCompensation;
$wizSideNavWidth: 470px;
$wizLeftNavWidth: 462px;
13 changes: 11 additions & 2 deletions src/plugins/wizard/public/application/app.scss
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,18 @@
padding: 0;
display: grid;
grid-template:
"topNav topNav topNav" min-content
"leftNav workspace rightNav" 1fr / #{$wizSideNavWidth} 1fr #{$wizSideNavWidth};
"topNav topNav" min-content
"leftNav workspaceNav" 1fr / #{$wizLeftNavWidth} 1fr;
height: calc(100vh - #{$osdHeaderOffset});

&__resizeContainer {
min-height: 0;
background-color: $euiColorEmptyShade;
}

&__resizeButton {
transform: translateX(-$euiSizeM / 2);
}
}

.headerIsExpanded .wizLayout {
Expand Down
35 changes: 32 additions & 3 deletions src/plugins/wizard/public/application/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

import React from 'react';
import { I18nProvider } from '@osd/i18n/react';
import { EuiPage } from '@elastic/eui';
import { EuiPage, EuiResizableContainer } from '@elastic/eui';
import { DragDropProvider } from './utils/drag_drop/drag_drop_context';
import { LeftNav } from './components/left_nav';
import { TopNav } from './components/top_nav';
Expand All @@ -21,8 +21,37 @@ export const WizardApp = () => {
<EuiPage className="wizLayout">
<TopNav />
<LeftNav />
<Workspace />
<RightNav />
<EuiResizableContainer className="wizLayout__resizeContainer">
{(EuiResizablePanel, EuiResizableButton) => (
<>
<EuiResizablePanel
className="wizLayout__workspaceResize"
paddingSize="none"
initialSize={80}
minSize="300px"
mode="main"
>
<Workspace />
</EuiResizablePanel>
<EuiResizableButton className="wizLayout__resizeButton" />
<EuiResizablePanel
className="wizLayout__rightNavResize"
paddingSize="none"
initialSize={20}
minSize="250px"
mode={[
'collapsible',
{
position: 'top',
},
]}
id="wizRightResize"
>
<RightNav />
</EuiResizablePanel>
</>
)}
</EuiResizableContainer>
</EuiPage>
</DragDropProvider>
</I18nProvider>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
overflow-y: auto;
margin-right: -$euiSizeS;
padding-right: $euiSizeS;
margin-left: -$euiSizeS;
padding-left: $euiSizeS;
margin-top: $euiSizeS;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,37 +6,35 @@
import React, { memo } from 'react';
import { EuiCallOut, EuiLink } from '@elastic/eui';
import { FormattedMessage } from '@osd/i18n/react';
import { i18n } from '@osd/i18n';

export const InfoComponent = () => {
const title = (
<>
return (
<EuiCallOut
className="hide-for-sharing"
data-test-subj="experimentalVisInfo"
size="s"
title={i18n.translate('wizard.experimentalInfoTitle', {
defaultMessage: 'This editor is experimental and should not be used in production',
})}
iconType="beaker"
>
<FormattedMessage
id="wizard.experimentalInfoText"
defaultMessage="This editor is experimental, do not use in production.
For feedback, please create an issue in {githubLink}."
defaultMessage="We want to hear from you about how we can improve your experience. Leave feedback in {githubLink}."
values={{
githubLink: (
<EuiLink
external
href="https://github.com/opensearch-project/OpenSearch-Dashboards/issues/new/choose"
href="https://github.com/opensearch-project/OpenSearch-Dashboards/issues/2280"
target="_blank"
>
GitHub
the GitHub issue
</EuiLink>
),
}}
/>
</>
);

return (
<EuiCallOut
className="hide-for-sharing"
data-test-subj="experimentalVisInfo"
size="s"
title={title}
iconType="beaker"
/>
</EuiCallOut>
);
};

Expand Down
55 changes: 47 additions & 8 deletions src/plugins/wizard/public/application/components/right_nav.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,24 @@
* SPDX-License-Identifier: Apache-2.0
*/

import React from 'react';
import { EuiSuperSelect, EuiSuperSelectOption, EuiIcon, IconType } from '@elastic/eui';
import React, { useState } from 'react';
import {
EuiSuperSelect,
EuiSuperSelectOption,
EuiIcon,
IconType,
EuiConfirmModal,
} from '@elastic/eui';
import { i18n } from '@osd/i18n';
import { FormattedMessage } from '@osd/i18n/react';
import { useVisualizationType } from '../utils/use';
import './side_nav.scss';
import { useOpenSearchDashboards } from '../../../../opensearch_dashboards_react/public';
import { WizardServices } from '../../types';
import { setActiveVisualization, useTypedDispatch } from '../utils/state_management';

export const RightNav = () => {
const [newVisType, setNewVisType] = useState<string>();
const {
services: { types },
} = useOpenSearchDashboards<WizardServices>();
Expand All @@ -23,6 +32,7 @@ export const RightNav = () => {
value: name,
inputDisplay: <OptionItem icon={icon} title={title} />,
dropdownDisplay: <OptionItem icon={icon} title={title} />,
'data-test-subj': `visType-${name}`,
}));

return (
Expand All @@ -32,19 +42,48 @@ export const RightNav = () => {
options={options}
valueOfSelected={activeVisName}
onChange={(name) => {
dispatch(
setActiveVisualization({
name,
style: types.get(name)?.ui.containerConfig.style.defaults,
})
);
setNewVisType(name);
}}
fullWidth
data-test-subj="chartPicker"
/>
</div>
<div className="wizSidenav__style">
<StyleSection />
</div>
{newVisType && (
<EuiConfirmModal
title={i18n.translate('wizard.rightNav.changeVisType.modalTitle', {
defaultMessage: 'Change visualization type',
})}
confirmButtonText={i18n.translate('wizard.rightNav.changeVisType.confirmText', {
defaultMessage: 'Change type',
})}
cancelButtonText={i18n.translate('wizard.rightNav.changeVisType.cancelText', {
defaultMessage: 'Cancel',
})}
onCancel={() => setNewVisType(undefined)}
onConfirm={() => {
dispatch(
setActiveVisualization({
name: newVisType,
style: types.get(newVisType)?.ui.containerConfig.style.defaults,
})
);

setNewVisType(undefined);
}}
maxWidth="300px"
data-test-subj="confirmVisChangeModal"
>
<p>
<FormattedMessage
id="wizard.rightNav.changeVisType.modalDescription"
defaultMessage="Changing the visualization type will reset all field selections. Do you want to continue?"
/>
</p>
</EuiConfirmModal>
)}
</section>
);
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
}

&--fixedWidthChild {
width: calc(#{$wizSideNavWidth} - #{$euiSizeXL} * 2);
width: calc(#{$wizLeftNavWidth} - #{$euiSizeXL} * 2);
}

&--selectableWrapper .euiSelectableList {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
&.right {
border-left: $euiBorderThin;
grid-area: rightNav;
height: 100%;
}

&__header {
Expand Down Expand Up @@ -46,5 +47,5 @@
}

.wizDatasourceSelect {
max-width: calc(#{$wizSideNavWidth} - 1px);
max-width: calc(#{$wizLeftNavWidth} - 1px);
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
grid-gap: $euiSizeM;
padding: $euiSizeM;
background-color: $euiColorEmptyShade;
height: 100%;

&__empty {
height: 100%;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { WizardServices } from '../../types';
import { validateSchemaState } from '../utils/validate_schema_state';
import { useTypedSelector } from '../utils/state_management';
import { useVisualizationType } from '../utils/use';
import { PersistedState } from '../../../../visualizations/public';

import hand_field from '../../assets/hand_field.svg';
import fields_bg from '../../assets/fields_bg.svg';
Expand All @@ -34,6 +35,8 @@ export const Workspace: FC = ({ children }) => {
timeRange: data.query.timefilter.timefilter.getTime(),
});
const rootState = useTypedSelector((state) => state);
// Visualizations require the uiState to persist even when the expression changes
const uiState = useMemo(() => new PersistedState(), []);

useEffect(() => {
async function loadExpression() {
Expand Down Expand Up @@ -77,7 +80,11 @@ export const Workspace: FC = ({ children }) => {
</EuiFlexGroup>
<EuiPanel className="wizCanvas" data-test-subj="visualizationLoader">
{expression ? (
<ReactExpressionRenderer expression={expression} searchContext={searchContext} />
<ReactExpressionRenderer
expression={expression}
searchContext={searchContext}
uiState={uiState}
/>
) : (
<EuiFlexItem className="wizWorkspace__empty" data-test-subj="emptyWorkspace">
<EuiEmptyPrompt
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*/

import { cloneDeep } from 'lodash';
import { OpenSearchaggsExpressionFunctionDefinition } from '../../../../data/public';
import { ExpressionFunctionOpenSearchDashboards } from '../../../../expressions';
import { buildExpressionFunction } from '../../../../expressions/public';
import { VisualizationState } from '../../application/utils/state_management';
import { getAggService, getIndexPatterns } from '../../plugin_services';

export const getAggExpressionFunctions = async (visualization: VisualizationState) => {
const { activeVisualization, indexPattern: indexId = '' } = visualization;
const { aggConfigParams } = activeVisualization || {};

const indexPatternsService = getIndexPatterns();
const indexPattern = await indexPatternsService.get(indexId);
// aggConfigParams is the serealizeable aggConfigs that need to be reconstructed here using the agg servce
const aggConfigs = getAggService().createAggConfigs(indexPattern, cloneDeep(aggConfigParams));

const opensearchDashboards = buildExpressionFunction<ExpressionFunctionOpenSearchDashboards>(
'opensearchDashboards',
{}
);

// soon this becomes: const opensearchaggs = vis.data.aggs!.toExpressionAst();
const opensearchaggs = buildExpressionFunction<OpenSearchaggsExpressionFunctionDefinition>(
'opensearchaggs',
{
index: indexId,
metricsAtAllLevels: false,
partialRows: false,
aggConfigs: JSON.stringify(aggConfigs.aggs),
includeFormatHints: false,
}
);

return {
aggConfigs,
expressionFns: [opensearchDashboards, opensearchaggs],
};
};
8 changes: 7 additions & 1 deletion src/plugins/wizard/public/visualizations/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,15 @@

import type { TypeServiceSetup } from '../services/type_service';
import { createMetricConfig } from './metric';
import { createHistogramConfig, createLineConfig, createAreaConfig } from './vislib';

export function registerDefaultTypes(typeServiceSetup: TypeServiceSetup) {
const visualizationTypes = [createMetricConfig];
const visualizationTypes = [
createHistogramConfig,
createLineConfig,
createAreaConfig,
createMetricConfig,
];

visualizationTypes.forEach((createTypeConfig) => {
typeServiceSetup.createVisualizationType(createTypeConfig());
Expand Down
Loading

0 comments on commit a7115b2

Please sign in to comment.