Skip to content

Commit

Permalink
Configure update handler for AttributesGroupBy selector on Visualizat…
Browse files Browse the repository at this point in the history
…ionContainer (metric display)

Signed-off-by: Peter Fitzgibbons <peter.fitzgibbons@gmail.com>
  • Loading branch information
pjfitzgibbons committed Aug 3, 2023
1 parent 85c2f63 commit 7eea892
Show file tree
Hide file tree
Showing 5 changed files with 89 additions and 89 deletions.
1 change: 1 addition & 0 deletions common/types/metrics.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,6 @@ export interface MetricType extends VisualizationType {
type: 'savedCustomMetric' | 'prometheusMetric';
aggregation: string;
attributesGroupBy: string[];
availableAttributes?: string[];
};
}
21 changes: 20 additions & 1 deletion public/components/custom_panels/helpers/utils.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -355,11 +355,19 @@ const updateCatalogVisualizationQuery = ({
const promQuery =
attributesGroupBy.length === 0
? catalogTableName
: '${aggregation} by(${attributesArrayToString}) (${catalogTableName})';
: `${aggregation} by(${attributesGroupString}) (${catalogTableName})`;

return `source = ${catalogSourceName}.query_range('${promQuery}', ${startEpochTime}, ${endEpochTime}, '14')`;
};

const getAttributesForCatalog = async (pplService, catalogName) => {
const columnSchema = await pplService.fetch({
query: 'describe ' + catalogName, // + ' | fields COLUMN_NAME, DATA_TYPE',
format: 'jdbc',
});
return columnSchema.jsonData.map((sch) => sch.COLUMN_NAME).filter((col) => col[0] !== '@');
};

// Creates a catalogVisualization for a runtime catalog based PPL query and runs getQueryResponse
export const renderCatalogVisualization = async ({
http,
Expand All @@ -377,6 +385,7 @@ export const renderCatalogVisualization = async ({
setIsError,
spanResolution,
metricMetaData,
setMetricMetaData,
}: {
http: CoreStart['http'];
pplService: PPLService;
Expand All @@ -393,6 +402,7 @@ export const renderCatalogVisualization = async ({
setIsError: React.Dispatch<React.SetStateAction<VizContainerError>>;
spanResolution?: string;
metricMetaData?: MetricType;
setMetricMetaData?: React.Dispatch<React.SetStateAction<MetricType>>;
}) => {
setIsLoading(true);
setIsError({} as VizContainerError);
Expand All @@ -405,6 +415,15 @@ export const renderCatalogVisualization = async ({

const defaultAggregation = 'avg'; // pass in attributes to this function
// const attributes: string[] = ['instance', 'job']; // pass in attributes to this function
if (metricMetaData) {
if (!metricMetaData.query.availableAttributes) {
const availableAttributes = await getAttributesForCatalog(pplService, catalogSource);
setMetricMetaData!({
...metricMetaData,
query: { ...metricMetaData.query, availableAttributes },
});
}
}

const visualizationQuery = updateCatalogVisualizationQuery({
catalogSourceName,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,12 @@
text-align: center;
}

.visualization-div.metricVis {
height: calc(100% - 85px) !important;

}


%center-div {
top: 50%;
left: 50%;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ interface Props {
catalogVisualization?: boolean;
spanParam?: string;
metricMetaData?: MetricType;
setMetricMetaData?: (metricMetaData: MetricType) => void;
setMetricMetaData?: React.Dispatch<React.SetStateAction<MetricType>>;
contextMenuId: 'visualization' | 'notebook' | 'metrics';
}

Expand Down Expand Up @@ -295,6 +295,7 @@ export const VisualizationContainer = ({
setIsLoading,
setIsError,
metricMetaData,
setMetricMetaData,
});
else
await renderSavedVisualization(
Expand All @@ -315,9 +316,11 @@ export const VisualizationContainer = ({
);
};

const metricVisCss = metricMetaData ? 'metricVis' : '';

const memoisedVisualizationBox = useMemo(
() => (
<div className="visualization-div">
<div className={`visualization-div ${metricVisCss}`}>
{isLoading ? (
<EuiLoadingChart size="xl" mono className="visualization-loading-chart" />
) : !_.isEmpty(isError) ? (
Expand Down Expand Up @@ -361,9 +364,14 @@ export const VisualizationContainer = ({
setAvailableAttributeKeys(attributeKeys);
}, [visualizationData]);

const updateMetricConfig = ({ aggregation }: { aggregation: string }) => {
console.log('updateMetricsConfig', { aggregation });
setMetricMetaData!({ query: { aggregation } });
const updateMetricConfig = ({
aggregation,
attributesGroupBy,
}: {
aggregation: string;
attributesGroupBy: string[];
}) => {
setMetricMetaData!({ query: { aggregation, attributesGroupBy } });
};

return (
Expand All @@ -386,13 +394,6 @@ export const VisualizationContainer = ({
</EuiToolTip>
</EuiText>
</EuiFlexItem>
<EuiFlexItem grow={false}>
<MetricsEditInline
visualizationData={visualizationData}
metricMetaData={metricMetaData}
updateMetricConfig={updateMetricConfig}
/>
</EuiFlexItem>
<EuiFlexItem grow={false} className="visualization-action-button">
{editMode ? (
<EuiIcon
Expand Down Expand Up @@ -420,6 +421,11 @@ export const VisualizationContainer = ({
)}
</EuiFlexItem>
</EuiFlexGroup>
<MetricsEditInline
visualizationData={visualizationData}
metricMetaData={metricMetaData}
updateMetricConfig={updateMetricConfig}
/>
</div>
{memoisedVisualizationBox}
</EuiPanel>
Expand Down
120 changes: 44 additions & 76 deletions public/components/metrics/sidebar/metrics_edit_inline.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
EuiFlexGroup,
EuiFlexItem,
EuiFormLabel,
EuiFormRow,
EuiPopover,
EuiPopoverTitle,
EuiSelect,
Expand All @@ -35,106 +36,73 @@ export const MetricsEditInline = ({
visualizationData?: any;
metricMetaData?: MetricType;
updateMetricConfig: ({}: { aggregation?: string; attributesGroupBy?: string[] }) => void;
availableAttributes?: string[];
}) => {
const [aggregationIsOpen, setAggregationIsOpen] = useState(false);
const [attributesGroupByIsOpen, setAttributesGroupByIsOpen] = useState(false);
const [availableAttributes, setAvailableAttributes] = useState([]);

useObservable(
from(visualizationData?.datarows || []).pipe(
mergeMap((row) => Object.keys(row[0])),
filter((attributeKey) => attributeKey !== '__name__'),
distinct((attributeKey) => attributeKey),
map((attributeKey) => ({ label: attributeKey, value: attributeKey })),
toArray()
),
setAvailableAttributes,
[visualizationData]
);
const availableAttributesLabels =
metricMetaData?.query?.availableAttributes?.map((attribute) => ({
label: attribute,
name: attribute,
})) || [];

const selectedOptionsFrom = (query) => {
return query.attributesGroupBy.map((attribute) => ({ label: attribute, name: attribute }));
};
// useEffect(() => {
// console.log({ availableAttributes });
// }, [availableAttributes]);

const onChangeAggregation = (e) => {
updateMetricConfig({ aggregation: e.target.value });
const onChangeAggregation = (value) => {
updateMetricConfig({ aggregation: value });
setAggregationIsOpen(false);
};

const onChangeAttributesGroupBy = (e) => {
updateMetricConfig({ selectedAttributesGroupBy: e.target.value });
const onChangeAttributesGroupBy = (selectedAttributes) => {
const attributesGroupBy = selectedAttributes.map(({ label }) => label);
updateMetricConfig({ attributesGroupBy });

setAttributesGroupByIsOpen(false);
};

useEffect(() => {
console.log({ availableAttributes, metricMetaData, visualizationData });
}, [availableAttributes, metricMetaData, visualizationData]);

const renderAggregationEditor = () => (
<div>
<EuiPopoverTitle>Aggregation</EuiPopoverTitle>
<EuiSelect
compressed
value={metricMetaData.query.aggregation}
onChange={onChangeAggregation}
options={AGGREGATION_OPTIONS}
/>
</div>
<EuiFlexGroup>
<EuiFlexItem>
<EuiFormRow label="AGGREGATION">
<EuiSelect
compressed
value={metricMetaData.query.aggregation}
onChange={onChangeAggregation}
options={AGGREGATION_OPTIONS}
/>
</EuiFormRow>
</EuiFlexItem>
</EuiFlexGroup>
);

const renderAttributesGroupByEditor = () => (
<div>
<EuiPopoverTitle>Group By Attributes</EuiPopoverTitle>
<EuiComboBox
compressed
value={metricMetaData.query.attributesGroupBy}
onChange={onChangeAggregation}
options={[{ label: 'host' }]}
/>
</div>
<EuiFlexGroup>
<EuiFlexItem>
<EuiFormRow label="ATTRIBUTES GROUP BY">
<EuiComboBox
className={'attributesGroupBy'}
compressed
selectedOptions={selectedOptionsFrom(metricMetaData.query)}
onChange={onChangeAttributesGroupBy}
options={availableAttributesLabels}
prepend={'ATTRIBUTES GROUP BY'}
/>
</EuiFormRow>
</EuiFlexItem>
</EuiFlexGroup>
);

return (
<div>
<EuiFlexGroup>
<EuiFlexItem grow={false}>
<EuiPopover
id="aggregation"
button={
<EuiExpression
description="aggregation"
value={metricMetaData.query.aggregation}
isActive={aggregationIsOpen}
onClick={() => setAggregationIsOpen(true)}
/>
}
isOpen={aggregationIsOpen}
closePopover={() => setAggregationIsOpen(false)}
panelPaddingSize="s"
anchorPosition="downLeft"
>
{renderAggregationEditor()}
</EuiPopover>
</EuiFlexItem>
<EuiFlexItem grow={false}>
<EuiPopover
id="attributes"
button={
<EuiExpression
description="group by attributes"
value={'(none selected)'}
isActive={attributesGroupByIsOpen}
onClick={() => setAttributesGroupByIsOpen(true)}
/>
}
isOpen={attributesGroupByIsOpen}
closePopover={() => setAttributesGroupByIsOpen(false)}
panelPaddingSize="s"
anchorPosition="downLeft"
>
{renderAttributesGroupByEditor()}
</EuiPopover>
</EuiFlexItem>
<EuiFlexItem grow={false}>{renderAggregationEditor()}</EuiFlexItem>
<EuiFlexItem grow={false}>{renderAttributesGroupByEditor()}</EuiFlexItem>
</EuiFlexGroup>
</div>
);
Expand Down

0 comments on commit 7eea892

Please sign in to comment.