Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Custom DC] Fix Disappearing Stat Var bug on Map and Scatter tool #4251

Merged
merged 16 commits into from
May 31, 2024
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions server/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -398,6 +398,10 @@ def create_app(nl_root=DEFAULT_NL_ROOT):
blocklist_svg = ["dc/g/Uncategorized", "oecd/g/OECD"]
app.config['BLOCKLIST_SVG'] = blocklist_svg

# Set whether to filter stat vars with low geographic coverage in the
# map and scatter tools.
app.config['USE_STAT_VAR_FILTERING'] = cfg.USE_STAT_VAR_FILTERING

if not cfg.TEST:
urls = get_health_check_urls()
libutil.check_backend_ready(urls)
Expand Down
6 changes: 5 additions & 1 deletion server/app_env/_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,4 +81,8 @@ class Config:
# Optional: custom dc template folder name:
# /server/templates/custom_dc/<CUSTOM_DC_TEMPLATE_FOLDER>/
# Defaults to the custom DC application environment name (Config.ENV value)
CUSTOM_DC_TEMPLATE_FOLDER = ''
CUSTOM_DC_TEMPLATE_FOLDER = ''
# Optional: Whether to hide stat vars with low geographic coverage from
# the map and scatter tools. Enabling this filtering prevents users from
# encountering almost-empty maps and sparse scatter plots.
USE_STAT_VAR_FILTERING = True
3 changes: 2 additions & 1 deletion server/app_env/custom.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,12 @@ class Config(_base.Config):
SHOW_DISASTER = False
USE_LLM = False
USE_MEMCACHE = False
USE_STAT_VAR_FILTERING = False


class LocalConfig(Config, local.Config):
pass


class ComposeConfig(Config, local.Config):
pass
pass
1 change: 1 addition & 0 deletions server/templates/tools/map.html
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
<div id="main-pane"></div>
<script>
infoConfig = {{info_json|tojson|safe}};
globalThis.useStatVarFiltering = {{ config['USE_STAT_VAR_FILTERING'] | lower }};
</script>
{% endblock %}

Expand Down
1 change: 1 addition & 0 deletions server/templates/tools/scatter.html
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
<div id="main-pane"></div>
<script>
infoConfig = {{info_json|tojson|safe}};
globalThis.useStatVarFiltering = {{ config['USE_STAT_VAR_FILTERING'] | lower }};
</script>
{% endblock %}

Expand Down
1 change: 1 addition & 0 deletions server/templates/tools/visualization.html
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
<div id="main-pane"></div>
<script>
infoConfig = {{info_json|tojson|safe}};
globalThis.useStatVarFiltering = {{ config['USE_STAT_VAR_FILTERING'] | lower }};
</script>
{% endblock %}

Expand Down
11 changes: 7 additions & 4 deletions static/js/apps/visualization/stat_var_selector.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,10 @@ import {
import { Spinner } from "../../components/spinner";
import { getStatVarInfo } from "../../shared/stat_var";
import { StatVarHierarchy } from "../../stat_var_hierarchy/stat_var_hierarchy";
import { getFilteredStatVarPromise } from "../../utils/app/visualization_utils";
import {
getFilteredStatVarPromise,
getNumEntitiesExistence,
} from "../../utils/app/visualization_utils";
import { AppContext } from "./app_context";
import { VIS_TYPE_CONFIG } from "./vis_type_configs";

Expand Down Expand Up @@ -104,9 +107,9 @@ export function StatVarSelector(props: StatVarSelectorPropType): JSX.Element {
selectSV={addSv}
searchLabel={""}
deselectSV={removeSv}
numEntitiesExistence={Math.min(
Math.max(samplePlaces.length, 1),
visTypeConfig.svHierarchyNumExistence || 1
numEntitiesExistence={getNumEntitiesExistence(
samplePlaces,
visTypeConfig
)}
/>
)}
Expand Down
1 change: 1 addition & 0 deletions static/js/shared/ga_events.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ import { ScatterChartType } from "../tools/scatter/util";
import { Chart as TimelineToolChart } from "../tools/timeline/chart";
import * as dataFetcher from "../tools/timeline/data_fetcher";
import { axiosMock } from "../tools/timeline/mock_functions";
import { getNumEntitiesExistence } from "../utils/app/visualization_utils";
import {
GA_EVENT_PLACE_CATEGORY_CLICK,
GA_EVENT_PLACE_CHART_CLICK,
Expand Down
35 changes: 35 additions & 0 deletions static/js/tools/download/mock_functions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,13 @@ export function axiosMock(): void {
numEntitiesExistence: undefined,
})
.mockResolvedValue(rootGroupsData);
when(axios.post)
.calledWith("/api/variable-group/info", {
dcid: "dc/g/Root",
entities: [],
numEntitiesExistence: 1,
})
.mockResolvedValue(rootGroupsData);

// get root stat var group for places in geoId/06
when(axios.post)
Expand All @@ -126,6 +133,13 @@ export function axiosMock(): void {
numEntitiesExistence: undefined,
})
.mockResolvedValue(rootGroupsData);
when(axios.post)
.calledWith("/api/variable-group/info", {
dcid: "dc/g/Root",
entities: ["geoId/06001", "geoId/06002"],
numEntitiesExistence: 1,
})
.mockResolvedValue(rootGroupsData);

when(axios.post)
.calledWith("/api/variable-group/info", {
Expand All @@ -134,6 +148,13 @@ export function axiosMock(): void {
numEntitiesExistence: undefined,
})
.mockResolvedValue(rootGroupsData);
when(axios.post)
.calledWith("/api/variable-group/info", {
dcid: "dc/g/Root",
entities: ["geoId/06002", "geoId/06001"],
numEntitiesExistence: 1,
})
.mockResolvedValue(rootGroupsData);

// get demographics stat var group for places in geoId/06
when(axios.post)
Expand All @@ -143,6 +164,13 @@ export function axiosMock(): void {
numEntitiesExistence: undefined,
})
.mockResolvedValue(demographicsGroupsData);
when(axios.post)
.calledWith("/api/variable-group/info", {
dcid: "dc/g/Demographics",
entities: ["geoId/06001", "geoId/06002"],
numEntitiesExistence: 1,
})
.mockResolvedValue(demographicsGroupsData);

when(axios.post)
.calledWith("/api/variable-group/info", {
Expand All @@ -151,6 +179,13 @@ export function axiosMock(): void {
numEntitiesExistence: undefined,
})
.mockResolvedValue(demographicsGroupsData);
when(axios.post)
.calledWith("/api/variable-group/info", {
dcid: "dc/g/Demographics",
entities: ["geoId/06002", "geoId/06001"],
numEntitiesExistence: 1,
})
.mockResolvedValue(demographicsGroupsData);

// stat var info for demographics node
when(axios.get)
Expand Down
6 changes: 0 additions & 6 deletions static/js/tools/map/stat_var_chooser.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,6 @@ import {
} from "./context";
import { DEFAULT_DISPLAY_OPTIONS, getMapPointPlaceType } from "./util";

const NUM_ENTITIES_EXISTENCE = 10;

interface StatVarChooserProps {
openSvHierarchyModalCallback: () => void;
openSvHierarchyModal: boolean;
Expand Down Expand Up @@ -114,10 +112,6 @@ export function StatVarChooser(props: StatVarChooserProps): JSX.Element {
selectSV={(svDcid) =>
selectStatVar(dateCtx, statVar, display, placeInfo, svDcid)
}
numEntitiesExistence={Math.min(
NUM_ENTITIES_EXISTENCE,
samplePlaces.length
)}
/>
);
}
Expand Down
34 changes: 21 additions & 13 deletions static/js/tools/scatter/app.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -490,99 +490,107 @@ function mockAxios(): void {
})
.mockResolvedValue(rootGroupsData);

when(axios.post)
.calledWith("/api/variable-group/info", {
dcid: "dc/g/Root",
entities: [],
numEntitiesExistence: 1,
})
.mockResolvedValue(rootGroupsData);

when(axios.post)
.calledWith("/api/variable-group/info", {
dcid: "dc/g/Root",
entities: ["geoId/10001", "geoId/10003", "geoId/10005"],
numEntitiesExistence: 3,
numEntitiesExistence: 1,
})
.mockResolvedValue(rootGroupsData);

when(axios.post)
.calledWith("/api/variable-group/info", {
dcid: "dc/g/Root",
entities: ["geoId/10001", "geoId/10005", "geoId/10003"],
numEntitiesExistence: 3,
numEntitiesExistence: 1,
})
.mockResolvedValue(rootGroupsData);

when(axios.post)
.calledWith("/api/variable-group/info", {
dcid: "dc/g/Root",
entities: ["geoId/10003", "geoId/10001", "geoId/10005"],
numEntitiesExistence: 3,
numEntitiesExistence: 1,
})
.mockResolvedValue(rootGroupsData);

when(axios.post)
.calledWith("/api/variable-group/info", {
dcid: "dc/g/Root",
entities: ["geoId/10003", "geoId/10005", "geoId/10001"],
numEntitiesExistence: 3,
numEntitiesExistence: 1,
})
.mockResolvedValue(rootGroupsData);

when(axios.post)
.calledWith("/api/variable-group/info", {
dcid: "dc/g/Root",
entities: ["geoId/10005", "geoId/10003", "geoId/10001"],
numEntitiesExistence: 3,
numEntitiesExistence: 1,
})
.mockResolvedValue(rootGroupsData);

when(axios.post)
.calledWith("/api/variable-group/info", {
dcid: "dc/g/Root",
entities: ["geoId/10005", "geoId/10001", "geoId/10003"],
numEntitiesExistence: 3,
numEntitiesExistence: 1,
})
.mockResolvedValue(rootGroupsData);

when(axios.post)
.calledWith("/api/variable-group/info", {
dcid: "dc/g/Demographics",
entities: ["geoId/10001", "geoId/10003", "geoId/10005"],
numEntitiesExistence: 3,
numEntitiesExistence: 1,
})
.mockResolvedValue(demographicsGroupsData);

when(axios.post)
.calledWith("/api/variable-group/info", {
dcid: "dc/g/Demographics",
entities: ["geoId/10001", "geoId/10005", "geoId/10003"],
numEntitiesExistence: 3,
numEntitiesExistence: 1,
})
.mockResolvedValue(demographicsGroupsData);

when(axios.post)
.calledWith("/api/variable-group/info", {
dcid: "dc/g/Demographics",
entities: ["geoId/10003", "geoId/10001", "geoId/10005"],
numEntitiesExistence: 3,
numEntitiesExistence: 1,
})
.mockResolvedValue(demographicsGroupsData);

when(axios.post)
.calledWith("/api/variable-group/info", {
dcid: "dc/g/Demographics",
entities: ["geoId/10003", "geoId/10005", "geoId/10001"],
numEntitiesExistence: 3,
numEntitiesExistence: 1,
})
.mockResolvedValue(demographicsGroupsData);

when(axios.post)
.calledWith("/api/variable-group/info", {
dcid: "dc/g/Demographics",
entities: ["geoId/10005", "geoId/10003", "geoId/10001"],
numEntitiesExistence: 3,
numEntitiesExistence: 1,
})
.mockResolvedValue(demographicsGroupsData);

when(axios.post)
.calledWith("/api/variable-group/info", {
dcid: "dc/g/Demographics",
entities: ["geoId/10005", "geoId/10001", "geoId/10003"],
numEntitiesExistence: 3,
numEntitiesExistence: 1,
})
.mockResolvedValue(demographicsGroupsData);

Expand Down Expand Up @@ -686,7 +694,7 @@ test("all functionalities", async () => {
expect(axios.post).toHaveBeenCalledWith("/api/variable-group/info", {
dcid: "dc/g/Root",
entities: [],
numEntitiesExistence: 0,
numEntitiesExistence: 1,
});
});
await app.update();
Expand Down
10 changes: 7 additions & 3 deletions static/js/tools/scatter/chart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -139,11 +139,15 @@ export function Chart(props: ChartPropsType): JSX.Element {
}
}, DEBOUNCE_INTERVAL_MS);
const resizeObserver = new ResizeObserver(debouncedHandler);
if (chartContainerRef.current) {
resizeObserver.observe(chartContainerRef.current);
// The value of chartContainerRef.current may change between setting the
// observe and unobserving during cleanup, so we store the current value
// in a variable.
const currentChartContainerElement = chartContainerRef.current;
if (currentChartContainerElement) {
resizeObserver.observe(currentChartContainerElement);
}
return () => {
resizeObserver.unobserve(chartContainerRef.current);
resizeObserver.unobserve(currentChartContainerElement);
debouncedHandler.cancel();
};
}, [props, chartContainerRef, geoJsonFetched]);
Expand Down
6 changes: 0 additions & 6 deletions static/js/tools/scatter/statvar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,6 @@ const defaultModalSelected: ModalSelected = Object.freeze({
y: false,
});

const NUM_ENTITIES_EXISTENCE = 10;

interface StatVarChooserProps {
openSvHierarchyModalCallback: () => void;
openSvHierarchyModal: boolean;
Expand Down Expand Up @@ -164,10 +162,6 @@ export function StatVarChooser(props: StatVarChooserProps): JSX.Element {
}
selectedSVs={selectedSvs}
selectSV={(sv) => addStatVar(x, y, sv, setThirdStatVar, setModalOpen)}
numEntitiesExistence={Math.min(
NUM_ENTITIES_EXISTENCE,
samplePlaces.length
)}
/>
{/* Modal for selecting 2 stat vars when a third is selected */}
<Modal isOpen={modalOpen} backdrop="static" id="statvar-modal">
Expand Down
Loading
Loading