Skip to content

Commit

Permalink
Merge pull request #2798 from Gkrumbach07/story/RHOAIENG-2976-spike-d…
Browse files Browse the repository at this point in the history
…etermine-artifact-rendering-details

Add Compare Runs metric section
  • Loading branch information
openshift-merge-bot[bot] authored May 15, 2024
2 parents 62f93c0 + c1291d3 commit 8645fe6
Show file tree
Hide file tree
Showing 42 changed files with 1,790 additions and 205 deletions.
22 changes: 17 additions & 5 deletions frontend/src/concepts/pipelines/apiHooks/mlmd/types.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Artifact, Context, ContextType, Event } from '~/third_party/mlmd';
import { Artifact, Context, ContextType, Event, Execution } from '~/third_party/mlmd';
import { PipelineRunKFv2 } from '~/concepts/pipelines/kfTypes';

export type MlmdContext = Context;

Expand All @@ -8,9 +9,20 @@ export enum MlmdContextTypes {
RUN = 'system.PipelineRun',
}

// An artifact which has associated event.
// You can retrieve artifact name from event.path.steps[0].key
export interface LinkedArtifact {
// each artifact is linked to an event
export type LinkedArtifact = {
event: Event;
artifact: Artifact;
}
};

// each execution can have multiple output artifacts
export type ExecutionArtifact = {
execution: Execution;
linkedArtifacts: LinkedArtifact[];
};

// each run has multiple executions, each execution can have multiple artifacts
export type RunArtifact = {
run: PipelineRunKFv2;
executionArtifacts: ExecutionArtifact[];
};
Original file line number Diff line number Diff line change
@@ -1,22 +1,18 @@
import React from 'react';
import { usePipelinesAPI } from '~/concepts/pipelines/context';
import { GetArtifactTypesRequest } from '~/third_party/mlmd';
import { ArtifactType, GetArtifactTypesRequest } from '~/third_party/mlmd';
import useFetchState, { FetchState, FetchStateCallbackPromise } from '~/utilities/useFetchState';

export const useGetArtifactTypeMap = (): FetchState<Record<number, string>> => {
export const useGetArtifactTypes = (): FetchState<ArtifactType[]> => {
const { metadataStoreServiceClient } = usePipelinesAPI();

const call = React.useCallback<FetchStateCallbackPromise<Record<number, string>>>(async () => {
const call = React.useCallback<FetchStateCallbackPromise<ArtifactType[]>>(async () => {
const request = new GetArtifactTypesRequest();

const res = await metadataStoreServiceClient.getArtifactTypes(request);

const artifactTypeMap: Record<number, string> = {};
res.getArtifactTypesList().forEach((artifactType) => {
artifactTypeMap[artifactType.getId()] = artifactType.getName();
});
return artifactTypeMap;
return res.getArtifactTypesList();
}, [metadataStoreServiceClient]);

return useFetchState(call, {});
return useFetchState(call, []);
};
23 changes: 17 additions & 6 deletions frontend/src/concepts/pipelines/apiHooks/mlmd/useMlmdContext.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,28 @@
import React from 'react';
import { MlmdContext, MlmdContextTypes } from '~/concepts/pipelines/apiHooks/mlmd/types';
import { usePipelinesAPI } from '~/concepts/pipelines/context';
import { GetContextByTypeAndNameRequest } from '~/third_party/mlmd';
import {
GetContextByTypeAndNameRequest,
MetadataStoreServicePromiseClient,
} from '~/third_party/mlmd';
import useFetchState, {
FetchState,
FetchStateCallbackPromise,
NotReadyError,
} from '~/utilities/useFetchState';

export const getMlmdContext = async (
client: MetadataStoreServicePromiseClient,
name: string,
type: MlmdContextTypes,
): Promise<MlmdContext | undefined> => {
const request = new GetContextByTypeAndNameRequest();
request.setTypeName(type);
request.setContextName(name);
const res = await client.getContextByTypeAndName(request);
return res.getContext();
};

/**
* A hook used to use the MLMD service and fetch the MLMD context
* If being used without name/type, this hook will throw an error
Expand All @@ -28,11 +43,7 @@ export const useMlmdContext = (
return Promise.reject(new NotReadyError('No context name'));
}

const request = new GetContextByTypeAndNameRequest();
request.setTypeName(type);
request.setContextName(name);
const res = await metadataStoreServiceClient.getContextByTypeAndName(request);
const context = res.getContext();
const context = await getMlmdContext(metadataStoreServiceClient, name, type);
if (!context) {
return Promise.reject(new Error('Cannot find specified context'));
}
Expand Down
121 changes: 121 additions & 0 deletions frontend/src/concepts/pipelines/content/artifacts/charts/ROCCurve.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
import React from 'react';
import {
Chart,
ChartAxis,
ChartGroup,
ChartLine,
ChartVoronoiContainer,
} from '@patternfly/react-charts';
import {
chart_color_blue_100 as chartColorBlue100,
chart_color_blue_200 as chartColorBlue200,
chart_color_blue_300 as chartColorBlue300,
chart_color_blue_400 as chartColorBlue400,
chart_color_blue_500 as chartColorBlue500,
chart_color_cyan_100 as chartColorCyan100,
chart_color_cyan_200 as chartColorCyan200,
chart_color_cyan_300 as chartColorCyan300,
chart_color_cyan_400 as chartColorCyan400,
chart_color_cyan_500 as chartColorCyan500,
chart_color_black_100 as chartColorBlack100,
} from '@patternfly/react-tokens';

export type ROCCurveConfig = {
index: number;
data: {
name: string;
x: number;
y: number;
index: number;
}[];
};

export const RocCurveChartColorScale = [
chartColorBlue100.value,
chartColorBlue200.value,
chartColorBlue300.value,
chartColorBlue400.value,
chartColorBlue500.value,
chartColorCyan100.value,
chartColorCyan200.value,
chartColorCyan300.value,
chartColorCyan400.value,
chartColorCyan500.value,
];

type ROCCurveProps = {
configs: ROCCurveConfig[];
maxDimension?: number;
};

const ROCCurve: React.FC<ROCCurveProps> = ({ configs, maxDimension }) => {
const width = Math.min(maxDimension || 800, 500);
const height = width;
const baseLineData = Array.from(Array(100).keys()).map((x) => ({ x: x / 100, y: x / 100 }));

return (
<div style={{ width }}>
<Chart
ariaDesc="ROC Curve"
ariaTitle="ROC Curve"
containerComponent={
<ChartVoronoiContainer
constrainToVisibleArea
voronoiBlacklist={['baseline']}
labels={({ datum }) => `threshold (Series #${datum.index + 1}): ${datum.name}`}
/>
}
height={height}
width={width}
padding={{ bottom: 100, left: 100, right: 50, top: 50 }}
legendAllowWrap
legendPosition="bottom-left"
legendData={configs.map((config) => ({
name: `Series #${config.index + 1}`,
symbol: {
fill: RocCurveChartColorScale[config.index % RocCurveChartColorScale.length],
type: 'square',
},
}))}
>
<ChartAxis
showGrid
dependentAxis
label="True positive rate"
tickValues={Array.from(Array(11).keys()).map((x) => x / 10)}
/>
<ChartAxis
showGrid
label="False positive rate"
tickValues={Array.from(Array(21).keys()).map((x) => x / 20)}
/>
<ChartGroup>
<ChartLine
name="baseline"
data={baseLineData}
style={{
data: {
strokeDasharray: '3,3',
stroke: chartColorBlack100.value,
},
}}
/>
{configs.map((config, idx) => (
<ChartLine
key={idx}
data={config.data}
interpolation="basis"
style={{
data: {
stroke: RocCurveChartColorScale[config.index % RocCurveChartColorScale.length],
},
}}
/>
))}
</ChartGroup>
</Chart>
</div>
);
};

export default ROCCurve;
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
.confusionMatrix {
margin: 20px;
margin-right: 75px;
display: flex;
}

.confusionMatrix-table {
border-collapse: collapse;
}

.confusionMatrix-cell {
border: solid 1px white;
position: relative;
text-align: center;
vertical-align: middle;
}

.confusionMatrix-labelCell {
text-align: right;
white-space: nowrap;
padding-right: 10px;
}

.confusionMatrix-gradientLegendOuter {
display: flex;
flex-direction: column;
justify-content: space-between;
}

.confusionMatrix-gradientLegend {
border-right: solid 1px #777;
margin-left: 30px;
min-width: 10px;
position: relative;
width: 10px;
}

.confusionMatrix-gradientLegendMaxOuter {
top: 0;
border-top: solid 1px #777;
left: 100%;
padding-left: 5px;
position: absolute;
width: 5px;
}

.confusionMatrix-gradientLegendMaxLabel {
left: 15px;
position: absolute;
top: -7px;
}

.confusionMatrix-verticalMarker {
writing-mode: vertical-lr;
white-space: nowrap;
}

.confusionMatrix-markerLabel {
border-top: solid 1px #777;
left: 100%;
padding-left: 5px;
position: absolute;
width: 5px;
}

.confusionMatrix-trueLabel {
font-weight: bold;
padding-left: 20px;
}

Loading

0 comments on commit 8645fe6

Please sign in to comment.