Skip to content

Commit

Permalink
Fix a null data reference issue (#228)
Browse files Browse the repository at this point in the history
* Fix a null data reference issue

* Fix an error
  • Loading branch information
shifucun authored Jul 31, 2020
1 parent 39f3243 commit edaf991
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 39 deletions.
7 changes: 6 additions & 1 deletion server/routes/api/stats.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,12 @@ def get_stats_wrapper(dcid_str, stats_var):
with value to be the observation time series.
"""
dcids = dcid_str.split('^')
return json.dumps(dc.get_stats(dcids, stats_var))
result = dc.get_stats(dcids, stats_var)
for dcid in result:
if not result[dcid]:
# Convert {} to None so client side sees null instead of {}
result[dcid] = None
return json.dumps(result)


@bp.route('/api/stats/<path:stats_var>')
Expand Down
20 changes: 19 additions & 1 deletion static/js/shared/data_fetcher.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

import axios from "axios";

import { fetchStatsData } from "./data_fetcher";
import { fetchStatsData, StatsData } from "./data_fetcher";
import { DataGroup } from "../chart/base";

jest.mock("axios");
Expand Down Expand Up @@ -157,3 +157,21 @@ test("fetch stats data", () => {
]);
});
});


test("StatsData test", () => {
// Test partial data
const statsData = new StatsData([],[],[], {
"Count_Person": {
"geoId/01": null,
"geoId/02": {
"place_dcid": "geoId/02",
"place_name": "Place2",
"provenance_domain": "test.domain",
"data": {"1990":10, "1992": 20}
}
}
});
expect(statsData.getStatsVarGroupWithTime("geoId/01")).toEqual([])

})
78 changes: 41 additions & 37 deletions static/js/shared/data_fetcher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,17 @@ import axios, { AxiosResponse } from "axios";
import { DataPoint, DataGroup } from "../chart/base";
import { STATS_VAR_TEXT } from "./stats_var";

interface ApiResponse {
[key: string]: {
data: {
[key: string]: number;
};
place_name: string;
place_dcid: string;
provenance_domain: string;
interface TimeSeries {
data: {
[key: string]: number;
};
place_name: string;
place_dcid: string;
provenance_domain: string;
}

interface ApiResponse {
[key: string]: TimeSeries | null;
}

/**
Expand Down Expand Up @@ -71,12 +73,14 @@ class StatsData {
const dataPoints: DataPoint[] = [];
let placeName: string;
for (const statsVar of this.statsVars) {
if (this.data[statsVar][place].data) {
if (!this.data[statsVar][place]) continue;
const timeSeries = this.data[statsVar][place];
if (timeSeries.data) {
dataPoints.push({
label: STATS_VAR_TEXT[statsVar],
value: this.data[statsVar][place].data[date],
value: timeSeries.data[date],
});
placeName = this.data[statsVar][place].place_name;
placeName = timeSeries.place_name;
}
}
if (dataPoints.length > 0) {
Expand All @@ -98,11 +102,13 @@ class StatsData {
const result: DataGroup[] = [];
for (const statsVar of this.statsVars) {
const dataPoints: DataPoint[] = [];
if (Object.keys(this.data[statsVar][place].data).length !== 0) {
if (!this.data[statsVar][place]) continue;
const timeSeries = this.data[statsVar][place];
if (Object.keys(timeSeries.data).length !== 0) {
for (const date of this.dates) {
dataPoints.push({
label: date,
value: date in this.data[statsVar][place].data ? this.data[statsVar][place].data[date] : null,
value: timeSeries.data[date] || null,
});
}
result.push(new DataGroup(statsVar, dataPoints));
Expand All @@ -124,9 +130,11 @@ class StatsData {
for (const date of this.dates) {
const dataPoints: DataPoint[] = [];
for (const statsVar of this.statsVars) {
if (!this.data[statsVar][place]) continue;
const timeSeries = this.data[statsVar][place];
dataPoints.push({
label: STATS_VAR_TEXT[statsVar],
value: this.data[statsVar][place].data[date],
value: timeSeries.data[date],
});
}
result.push(new DataGroup(date, dataPoints));
Expand Down Expand Up @@ -155,9 +163,11 @@ class StatsData {
}
const result: DataPoint[] = [];
for (const statsVar of this.statsVars) {
if (!this.data[statsVar][place]) continue;
const timeSeries = this.data[statsVar][place];
result.push({
label: STATS_VAR_TEXT[statsVar],
value: this.data[statsVar][place].data[date],
value: timeSeries.data[date],
});
}
return result;
Expand Down Expand Up @@ -202,40 +212,34 @@ function fetchStatsData(
// Compute perCapita.
if (perCapita) {
for (const place in allResp[i].data) {
if (Object.keys(allResp[i].data[place]).length === 0) {
continue;
}
if (!allResp[i].data[place]) continue;
const dateValue = allResp[i].data[place].data;
const population = allResp[n].data[place].data;
const years = Object.keys(population);
years.sort();
const yearMin = years[0];
const yearMax = years[years.length - 1];
for (const date in allResp[i].data[place].data) {
if (allResp[i].data[place].data.hasOwnProperty(date)) {
const year = date.split("-")[0];
let pop: number;
if (year in population) {
pop = population[year];
} else if (year < yearMin) {
pop = population[yearMin];
} else {
pop = population[yearMax];
}
result.data[statsVars[i]][place].data[date] /= pop / scaling;
for (const date in dateValue) {
const year = date.split("-")[0];
let pop: number;
if (year in population) {
pop = population[year];
} else if (year < yearMin) {
pop = population[yearMin];
} else {
pop = population[yearMax];
}
result.data[statsVars[i]][place].data[date] /= pop / scaling;
}
}
}
// Build the dates collection, get the union of available dates for all data
for (const place in allResp[i].data) {
if (!allResp[i].data[place]) {
continue;
}
result.sources.add(allResp[i].data[place].provenance_domain)
for (const date in allResp[i].data[place].data) {
if (allResp[i].data[place].data.hasOwnProperty(date)) {
if (!allResp[i].data[place]) continue;
const timeSeries = allResp[i].data[place];
result.sources.add(timeSeries.provenance_domain)
for (const date in timeSeries.data) {
dates[date] = true;
}
}
}
}
Expand Down

0 comments on commit edaf991

Please sign in to comment.