diff --git a/src/components/PopoverCard/index.tsx b/src/components/PopoverCard/index.tsx index 80afa132..bfb66f5a 100644 --- a/src/components/PopoverCard/index.tsx +++ b/src/components/PopoverCard/index.tsx @@ -14,6 +14,8 @@ export interface PopoverCardProps { xValue?: string; yLabel?: string; yValue?: string; + lineLabel?: string; + lineValue?: string; } const PopoverCard: React.FC = (props) => { @@ -46,7 +48,7 @@ const PopoverCard: React.FC = (props) => { return ( - {(props.xValue || props.yValue) && ( + {(props.xValue || props.yValue || props.lineValue !== undefined) && (
{props.xValue && (
@@ -60,6 +62,12 @@ const PopoverCard: React.FC = (props) => { {props.yValue}
)} + {props.lineValue && ( +
+ {props.lineLabel} + {props.lineValue} +
+ )}
)}
diff --git a/src/containers/MainPlotContainer/index.tsx b/src/containers/MainPlotContainer/index.tsx index 2421888c..f7605c72 100644 --- a/src/containers/MainPlotContainer/index.tsx +++ b/src/containers/MainPlotContainer/index.tsx @@ -47,6 +47,8 @@ import { getXAxisRange, getYAxisRange, getAnnotations, + getConnectByFeatureDisplayName, + getFormattedHoveredConnectByFeatureValue, } from "./selectors"; import { getFeatureDefTooltip } from "../../state/selection/selectors"; import { formatThumbnailSrc } from "../../state/util"; @@ -66,11 +68,13 @@ interface PropsFromState { hoveredPointData: SelectedPointData | null; hoveredXValue: string; hoveredYValue: string; + hoveredConnectByFeatureValue: string; mousePosition: MousePosition; plotDataArray: any; thumbnailRoot: string; xDisplayName: string; yDisplayName: string; + connectByFeatureDisplayName: string; xDropDownValue: string; yDropDownValue: string; yDropDownOptions: MeasuredFeatureDef[]; @@ -203,7 +207,8 @@ class MainPlotContainer extends React.Component ) ); @@ -383,6 +392,8 @@ function mapStateToProps(state: State): PropsFromState { thumbnailRoot: selectionStateBranch.selectors.getThumbnailRoot(state), xDisplayName: getXDisplayName(state), yDisplayName: getYDisplayName(state), + connectByFeatureDisplayName: getConnectByFeatureDisplayName(state), + hoveredConnectByFeatureValue: getFormattedHoveredConnectByFeatureValue(state), xDropDownOptions: getXDisplayOptions(state), xDropDownValue: selectionStateBranch.selectors.getPlotByOnX(state), xTickConversion: getXTickConversion(state), diff --git a/src/containers/MainPlotContainer/selectors.ts b/src/containers/MainPlotContainer/selectors.ts index 6f11dcf3..7809aef0 100644 --- a/src/containers/MainPlotContainer/selectors.ts +++ b/src/containers/MainPlotContainer/selectors.ts @@ -44,6 +44,7 @@ import { getShowConnectLines, getFilteredConnectByCategoryValues, getLineMovingAverageWindow, + getConnectByFeature, } from "../../state/selection/selectors"; import { MainPlotSettings, SelectedPointData, TickConversion } from "../../state/selection/types"; import { @@ -103,16 +104,24 @@ export const handleNullValues = ( }; export const getPlotlyCustomData = createSelector( - [getFilteredCellData], - (filteredCellData: DataForPlot): PlotlyCustomData[] => { + [getFilteredCellData, getShowConnectLines, getConnectByFeature], + ( + filteredCellData: DataForPlot, + showConnectByLines: boolean, + connectByFeature: string + ): PlotlyCustomData[] => { const thumbnailPaths = filteredCellData.labels.thumbnailPaths; const srcPaths = filteredCellData.labels.sourcePaths; const indices = filteredCellData.indices; + const connectByFeatureValues = showConnectByLines + ? filteredCellData.values[connectByFeature] + : undefined; return map(indices, (cellIndex, i) => { return { index: cellIndex, thumbnailPath: thumbnailPaths[i], srcPath: srcPaths?.[i], + connectByFeature: connectByFeatureValues?.[i], }; }); } @@ -549,26 +558,30 @@ const makeNumberAxis = (): TickConversion => { }; }; +const getFeatureTickConversion = ( + featureKey: string, + featureDefs: MeasuredFeatureDef[] +): TickConversion => { + const feature = find(featureDefs, { key: featureKey }); + if (feature && feature.discrete) { + return makeNumberToTextConversion(feature.options); + } + return makeNumberAxis(); +}; + export const getXTickConversion = createSelector( [getPlotByOnX, getMeasuredFeaturesDefs], - (plotByOnX, measuredFeaturesDefs: MeasuredFeatureDef[]): TickConversion => { - const feature = findFeature(measuredFeaturesDefs, plotByOnX); - if (feature && feature.discrete) { - return makeNumberToTextConversion(feature.options); - } - return makeNumberAxis(); - } + getFeatureTickConversion ); export const getYTickConversion = createSelector( [getPlotByOnY, getMeasuredFeaturesDefs], - (plotByOnY, measuredFeaturesDefs: MeasuredFeatureDef[]): TickConversion => { - const feature = find(measuredFeaturesDefs, { key: plotByOnY }); - if (feature && feature.discrete) { - return makeNumberToTextConversion(feature.options); - } - return makeNumberAxis(); - } + getFeatureTickConversion +); + +export const getConnectByFeatureTickConversion = createSelector( + [getConnectByFeature, getMeasuredFeaturesDefs], + getFeatureTickConversion ); export const getDataForOverlayCard = createSelector( @@ -630,6 +643,14 @@ export const getYDisplayName = createSelector( } ); +export const getConnectByFeatureDisplayName = createSelector( + [getConnectByFeature, getMeasuredFeaturesDefs], + (connectByFeature, featureDefs): string => { + const feature = findFeature(featureDefs, connectByFeature); + return feature?.displayName ?? connectByFeature; + } +); + function formatAxisValue( value: number | string | undefined, isCategorical: boolean, @@ -666,3 +687,16 @@ export const getFormattedHoveredYValue = createSelector( ); } ); + +export const getFormattedHoveredConnectByFeatureValue = createSelector( + [ + getHoveredPointData, + getCategoricalFeatureKeys, + getConnectByFeature, + getConnectByFeatureTickConversion, + ], + (hoveredPointData, categoricalFeatures, connectByKey, tickConversion): string => { + const value = hoveredPointData?.connectByFeatureValue ?? undefined; + return formatAxisValue(value, includes(categoricalFeatures, connectByKey), tickConversion); + } +); diff --git a/src/state/selection/types.ts b/src/state/selection/types.ts index 23d97224..07e2477f 100755 --- a/src/state/selection/types.ts +++ b/src/state/selection/types.ts @@ -127,6 +127,7 @@ export interface SelectedPointData { groupBy?: string; xValue?: number | string; yValue?: number | string; + connectByFeatureValue?: number | string | null; } export interface ChangeHoveredPointAction { diff --git a/src/state/types.ts b/src/state/types.ts index 21fe8014..de9016a9 100755 --- a/src/state/types.ts +++ b/src/state/types.ts @@ -68,6 +68,8 @@ export interface SelectedGroupDatum { export interface PlotlyCustomData { thumbnailPath: string; index: number; + srcPath?: string; + connectByFeatureValue?: number | null; } export enum DataType {