diff --git a/src/plugins/bar-graph/bar-graph-content.test.ts b/src/plugins/bar-graph/bar-graph-content.test.ts
index 565a7f56f..79c70942b 100644
--- a/src/plugins/bar-graph/bar-graph-content.test.ts
+++ b/src/plugins/bar-graph/bar-graph-content.test.ts
@@ -107,14 +107,14 @@ Object {
content.setSharedModel(sharedSampleDataSet());
content.setPrimaryAttribute("att-s");
expect(content.dataArray).toEqual([
- { "att-s": "cat", "value": 2 },
- { "att-s": "owl","value": 2}
+ { "att-s": "cat", "value": { count: 2, selected: false }},
+ { "att-s": "owl","value": { count: 2, selected: false }}
]);
content.setPrimaryAttribute("att-l");
expect(content.dataArray).toEqual([
- { "att-l": "yard", "value": 3 },
- { "att-l": "forest", "value": 1 }
+ { "att-l": "yard", "value": { count: 3, selected: false }},
+ { "att-l": "forest", "value": { count: 1, selected: false }}
]);
});
@@ -122,8 +122,8 @@ Object {
const content = TestingBarGraphContentModel.create({ });
content.setSharedModel(sharedSampleDataSet());
expect(content.dataArray).toEqual([
- { "att-s": "cat", "value": 2 },
- { "att-s": "owl","value": 2}
+ { "att-s": "cat", "value": { count: 2, selected: false }},
+ { "att-s": "owl","value": { count: 2, selected: false }}
]);
});
@@ -133,8 +133,8 @@ Object {
content.setPrimaryAttribute("att-s");
content.setSecondaryAttribute("att-l");
expect(content.dataArray).toEqual([
- { "att-s": "cat", "yard": 2 },
- { "att-s": "owl", "yard": 1, "forest": 1 }
+ { "att-s": "cat", "yard": { count: 2, selected: false }},
+ { "att-s": "owl", "yard": { count: 1, selected: false }, "forest": { count: 1, selected: false }}
]);
});
@@ -146,15 +146,15 @@ Object {
content.setPrimaryAttribute("att-s");
content.setSecondaryAttribute("att-l");
expect(content.dataArray).toEqual([
- { "att-s": "cat", "yard": 2 },
- { "att-s": "owl", "yard": 1, "(no value)": 1 }
+ { "att-s": "cat", "yard": { count: 2, selected: false }},
+ { "att-s": "owl", "yard": { count: 1, selected: false}, "(no value)": { count: 1, selected: false }}
]);
dataSet.dataSet?.attributes[0].setValue(3, undefined); // hide that owl entirely
expect(content.dataArray).toEqual([
- { "att-s": "cat", "yard": 2 },
- { "att-s": "owl", "yard": 1 },
- { "att-s": "(no value)", "(no value)": 1 }
+ { "att-s": "cat", "yard": { count: 2, selected: false }},
+ { "att-s": "owl", "yard": { count: 1, selected: false }},
+ { "att-s": "(no value)", "(no value)": { count: 1, selected: false }}
]);
});
diff --git a/src/plugins/bar-graph/bar-graph-content.ts b/src/plugins/bar-graph/bar-graph-content.ts
index bbbacfc2d..7ef2a9a53 100644
--- a/src/plugins/bar-graph/bar-graph-content.ts
+++ b/src/plugins/bar-graph/bar-graph-content.ts
@@ -145,6 +145,22 @@ export const BarGraphContentModel = TileContentModel
},
setSecondaryAttribute(attrId: string|undefined) {
self.secondaryAttribute = attrId;
+ },
+ selectCasesByValues(primaryVal: string, secondaryVal?: string) {
+ const dataSet = self.sharedModel?.dataSet;
+ const cases = self.cases;
+ const primaryAttribute = self.primaryAttribute;
+ if (!dataSet || !cases || !primaryAttribute) return;
+ const secondaryAttribute = self.secondaryAttribute;
+ if (!secondaryAttribute && secondaryVal) return;
+ let matchingCases = cases
+ .filter(caseID => displayValue(dataSet.getStrValue(caseID.__id__, primaryAttribute)) === primaryVal);
+ if (secondaryAttribute && secondaryVal) {
+ matchingCases = matchingCases
+ .filter(caseID => displayValue(dataSet.getStrValue(caseID.__id__, secondaryAttribute)) === secondaryVal);
+ }
+ const caseIds = matchingCases.map(caseID => caseID.__id__);
+ dataSet.setSelectedCases(caseIds);
}
}))
.actions(self => ({
diff --git a/src/plugins/bar-graph/bar-graph-utils.ts b/src/plugins/bar-graph/bar-graph-utils.ts
index e5a1d8681..a742c6c91 100644
--- a/src/plugins/bar-graph/bar-graph-utils.ts
+++ b/src/plugins/bar-graph/bar-graph-utils.ts
@@ -37,9 +37,10 @@ export function updateBarGraphContentWithNewSharedModelIds(
}
// Define types here to document all possible values that this tile logs
-type LoggableOperation = "setPrimaryAttribute" | "setSecondaryAttribute" | "setYAxisLabel";
+type LoggableOperation = "setPrimaryAttribute" | "setSecondaryAttribute" | "setYAxisLabel" | "selectCases";
type LoggableChange = {
- attributeId?: string;
+ attributeId?: string | string[];
+ attributeValue?: string | string[];
text?: string;
};
diff --git a/src/plugins/bar-graph/chart-area.tsx b/src/plugins/bar-graph/chart-area.tsx
index cc7768771..d0e9d89f2 100644
--- a/src/plugins/bar-graph/chart-area.tsx
+++ b/src/plugins/bar-graph/chart-area.tsx
@@ -92,6 +92,16 @@ export const ChartArea = observer(function BarGraphChart({ width, height }: IPro
const labelWidth = (xMax/primaryKeys.length)-10; // setting width will wrap lines when needed
+ function handleClick(primaryValue: string, secondaryValue?: string) {
+ if (!model || !model.primaryAttribute) return;
+ model.selectCasesByValues(primaryValue, secondaryValue);
+ logBarGraphEvent(model, "selectCases", {
+ attributeId:
+ model.secondaryAttribute ? [model.primaryAttribute, model.secondaryAttribute] : model.primaryAttribute,
+ attributeValue: secondaryValue ? [primaryValue, secondaryValue] : primaryValue
+ });
+ }
+
function simpleBars() {
const color = barColor(primary);
return (
@@ -104,7 +114,8 @@ export const ChartArea = observer(function BarGraphChart({ width, height }: IPro
const w = primaryScale.bandwidth();
const h = yMax - countScale(info.count);
return (
-
+ handleClick(key)} />
);
})}
@@ -123,29 +134,34 @@ export const ChartArea = observer(function BarGraphChart({ width, height }: IPro
x1Scale={secondaryScale}
yScale={((info: BarInfo) => countScale(info?.count||0)) as PositionScale}
>
- {(barGroups) =>
-
- {barGroups.map((barGroup) => (
-
- {barGroup.bars.map((bar) => {
- if (!bar.value) return null;
- // BarGroup really expects the values to be pure numeric, but we're using objects.
- // Alternatively, we could drop BarGroup and build the bars manually.
- const val = bar.value as unknown as BarInfo;
- return ;
+ {(barGroups) => {
+ return (
+
+ {barGroups.map((barGroup) => {
+ const primaryValue = data[barGroup.index][primary] as string;
+ return (
+
+ {barGroup.bars.map((bar) => {
+ if (!bar.value) return null;
+ // BarGroup really expects the values to be pure numeric, but we're using objects.
+ // Alternatively, we could drop BarGroup and build the bars manually.
+ const val = bar.value as unknown as BarInfo;
+ return handleClick(primaryValue, bar.key)} />;
+ })}
+
+ );
})}
- ))}
-
- }
+ );
+ }}
);
}
@@ -222,13 +238,14 @@ interface IBarWithHighlightProps {
height: number;
color: string;
selected: boolean;
+ onClick: () => void;
}
-function BarWithHighlight({ x, y, width, height, color, selected }: IBarWithHighlightProps) {
+function BarWithHighlight({ x, y, width, height, color, selected, onClick }: IBarWithHighlightProps) {
return (
{selected && }
-
+
);
}