Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
44 changes: 39 additions & 5 deletions assets/js/data-explorer/global.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ let dataSources;

let measureAbout = ``;
let measureSources = ``;
let measureDataSourceLinks = [];
let geoTable;
let timeTable;
let unreliabilityNotes;
Expand Down Expand Up @@ -53,11 +54,13 @@ let defaultTrendSources = [];
let defaultMapMetadata;
let defaultMapAbout;
let defaultMapSources;
let defaultMapDataSourceLinks;
let defaultPrimaryLinksMeasureMetadata;
let defaultSecondaryMeasureMetadata;
let defaultDisparitiesMetadata;
let defaultLinksAbout;
let defaultLinksSources = [];
let defaultLinksDataSourceLinks = [];

let selectedMapMeasure;
let selectedMapTime;
Expand All @@ -70,18 +73,22 @@ let showingComparisonTrend;

let selectedMapAbout;
let selectedMapSources;
let selectedMapDataSourceLinks;
let selectedMapMetadata;

let selectedTrendAbout;
let selectedTrendSources;
let selectedTrendDataSourceLinks;
let aqSelectedTrendMetadata;

let selectedComparisonAbout = "";
let selectedComparisonSources = [];
let selectedComparisonDataSourceLinks = [];
let selectedComparisonMetadata;

let selectedLinksAbout;
let selectedLinksSources = [];
let selectedLinksDataSourceLinks = [];
let selectedPrimaryMeasureMetadata;
let selectedSecondaryMeasureMetadata;

Expand Down Expand Up @@ -264,26 +271,53 @@ const renderTitleDescription = (title, desc) => {
});
}

// Maps known source names to their URLs for inline hyperlinking

const sourcesLinkMap = {
'New York City Community Health Survey (CHS)': 'https://www.nyc.gov/site/doh/data/data-sets/community-health-survey-public-use-data.page',
'Metropolitan Transportation Authority': 'https://www.mta.info/developers',
'New York City Housing and Vacancy Survey (NYCHVS)': 'https://www.nyc.gov/site/hpd/about/research.page',
'American Community Survey': 'https://www.census.gov/programs-surveys/acs/data.html'
};

const linkifySource = (text, overrideMap = {}) => {
if (!text) return text;
const combined = { ...sourcesLinkMap, ...overrideMap };
let result = text;
for (const [name, url] of Object.entries(combined)) {
if (result.includes(name)) {
result = result.replace(name, `<a href="${url}" target="_blank" rel="noopener noreferrer">${name}</a>`);
}
}
return result;
};

// Renders copy for the About the measures and the Data sources sections

const renderAboutSources = (about, sources) => {
const renderAboutSources = (about, sources, dataSourceLinks = null) => {

console.log("**** renderAboutSources");
dataSources.innerHTML = ''

// build override map from DataSourceLink entries: label is the source text to match
const overrideMap = {};
if (Array.isArray(dataSourceLinks)) {
dataSourceLinks.forEach(({ label, url }) => { overrideMap[label] = url; });
}

// de-dupe data sources
let type = typeof sources

if (type === 'object') {
let singleSource;
singleSource = sources.every( (val, i, arr) => val === arr[0] )
singleSource === true ? dataSources.innerHTML = sources[0] : dataSources.innerHTML = sources
singleSource = sources.every( (val, i, arr) => val === arr[0] )
singleSource === true ? dataSources.innerHTML = linkifySource(sources[0], overrideMap) : dataSources.innerHTML = sources.map(s => linkifySource(s, overrideMap)).join(',')
} else {
dataSources.innerHTML = sources
dataSources.innerHTML = linkifySource(sources, overrideMap)
}

aboutMeasures.innerHTML = about;

}

// ----------------------------------------------------------------------- //
Expand Down
66 changes: 45 additions & 21 deletions assets/js/data-explorer/measures.js
Original file line number Diff line number Diff line change
Expand Up @@ -464,12 +464,13 @@ const updateMapData = (e) => {

// "indicatorName" is set in loadIndicator

selectedMapAbout = `<strong>${measure}:</strong> ${about}</p>`;
selectedMapSources = `${sources}`;
selectedMapAbout = `<strong>${measure}:</strong> ${about}</p>`;
selectedMapSources = `${sources}`;
selectedMapDataSourceLinks = selectedMapMetadata[0].DataSourceLink ?? null;

// render measure info boxes

renderAboutSources(selectedMapAbout, selectedMapSources);
renderAboutSources(selectedMapAbout, selectedMapSources, selectedMapDataSourceLinks);


// ----- create dataset --------------------------------------------------- //
Expand Down Expand Up @@ -546,6 +547,8 @@ const updateBoroughTrendData = (e) => {
const about = selectedTrendMetadata[0].how_calculated;
const sources = selectedTrendMetadata[0].Sources;

selectedTrendDataSourceLinks = selectedTrendMetadata[0].DataSourceLink ?? null;

aqSelectedTrendMetadata = aq.from(selectedTrendMetadata)
.derive({
IndicatorLabel: aq.escape(indicatorName),
Expand All @@ -562,7 +565,7 @@ const updateBoroughTrendData = (e) => {

// render measure info boxes

renderAboutSources(selectedTrendAbout, selectedTrendSources);
renderAboutSources(selectedTrendAbout, selectedTrendSources, selectedTrendDataSourceLinks);


// ----- create dataset --------------------------------------------------- //
Expand Down Expand Up @@ -665,28 +668,32 @@ const updateComparisonTrendData = (e) => {

selectedComparisonAbout = [];
selectedComparisonSources = [];
selectedComparisonDataSourceLinks = [];

// reset info boxes

selectedComparisonAbout = [];
selectedComparisonSources = [];
selectedComparisonDataSourceLinks = [];

// this iterates over all the indicators and measures in the chosen comparison

aqCombinedComparisonMetadata.objects()
.filter(m => m.ComparisonID == comparisonId)
.forEach(m => {
selectedComparisonAbout += `<p><strong>${m.IndicatorName} - ${m.MeasurementType}:</strong> ${m.how_calculated}</p>`;
selectedComparisonSources.push(m.Sources)
selectedComparisonSources.push(m.Sources);
selectedComparisonDataSourceLinks.push(...(m.DataSourceLink ?? []));
})

// get unique sources

let uniqueSelectedComparisonSources = [...new Set(selectedComparisonSources)];
let uniqueComparisonDataSourceLinks = [...new Map(selectedComparisonDataSourceLinks.map(l => [l.url, l])).values()];

// render the measure info boxes

renderAboutSources(selectedComparisonAbout, uniqueSelectedComparisonSources);
renderAboutSources(selectedComparisonAbout, uniqueSelectedComparisonSources, uniqueComparisonDataSourceLinks);


// ----- create dataset --------------------------------------------------- //
Expand Down Expand Up @@ -841,8 +848,13 @@ const updateLinksData = async (e) => {
selectedLinksSources.push(primarySources.concat(" "))
selectedLinksSources.push(secondarySources)

selectedLinksDataSourceLinks = [
...(selectedPrimaryMeasureMetadata[0].DataSourceLink ?? []),
...(selectedSecondaryMeasureMetadata[0].DataSourceLink ?? [])
];

// render the measure info boxes
renderAboutSources(selectedLinksAbout, selectedLinksSources);
renderAboutSources(selectedLinksAbout, selectedLinksSources, selectedLinksDataSourceLinks);


// ----- render the chart --------------------------------------------------- //
Expand Down Expand Up @@ -1172,6 +1184,7 @@ const renderMeasures = async () => {

measureAbout = "";
measureSources = [];
measureDataSourceLinks = [];

// clear on click event handlers from view options

Expand Down Expand Up @@ -1419,6 +1432,7 @@ const renderMeasures = async () => {

measureAbout += `<p><strong>${measure.MeasurementType}:</strong> ${measure.how_calculated}</p>`;
measureSources.push(measure.Sources);
measureDataSourceLinks.push(...(measure.DataSourceLink ?? []));


});
Expand Down Expand Up @@ -1559,7 +1573,7 @@ const renderMeasures = async () => {
// ----- set measure info boxes --------------------------------------------------- //

renderTitleDescription(indicatorShortName, indicatorDesc);
renderAboutSources(measureAbout, measureSources);
renderAboutSources(measureAbout, measureSources, measureDataSourceLinks);


// ----- render the table --------------------------------------------------- //
Expand Down Expand Up @@ -1638,13 +1652,14 @@ const renderMeasures = async () => {

// ----- set measure info boxes --------------------------------------------------- //

defaultMapAbout = `<p><strong>${measure}:</strong> ${about}</p>`;
defaultMapSources = `${sources}`;
defaultMapAbout = `<p><strong>${measure}:</strong> ${about}</p>`;
defaultMapSources = `${sources}`;
defaultMapDataSourceLinks = defaultMapMetadata[0].DataSourceLink ?? null;

// render measure info boxes

renderTitleDescription(indicatorShortName, indicatorDesc);
renderAboutSources(defaultMapAbout, defaultMapSources);
renderAboutSources(defaultMapAbout, defaultMapSources, defaultMapDataSourceLinks);


// ----- create dataset --------------------------------------------------- //
Expand Down Expand Up @@ -1749,7 +1764,7 @@ const renderMeasures = async () => {

// ----- set measure info boxes --------------------------------------------------- //

renderAboutSources(selectedMapAbout, selectedMapSources);
renderAboutSources(selectedMapAbout, selectedMapSources, selectedMapDataSourceLinks);

// ----- get current dropdown values --------------------------------------------------- //

Expand Down Expand Up @@ -1868,6 +1883,7 @@ const renderMeasures = async () => {
const about = defaultTrendMetadata[0]?.how_calculated;
const sources = defaultTrendMetadata[0].Sources;
const measure = defaultTrendMetadata[0].MeasurementType;
const defaultTrendDataSourceLinks = defaultTrendMetadata[0].DataSourceLink ?? null;

aqDefaultTrendMetadata = aq.from(defaultTrendMetadata)
.derive({
Expand All @@ -1886,7 +1902,7 @@ const renderMeasures = async () => {
defaultTrendSources.push(sources)

renderTitleDescription(indicatorShortName, indicatorDesc);
renderAboutSources(defaultTrendAbout, defaultTrendSources);
renderAboutSources(defaultTrendAbout, defaultTrendSources, defaultTrendDataSourceLinks);


// ----- create dataset --------------------------------------------------- //
Expand Down Expand Up @@ -1962,10 +1978,10 @@ const renderMeasures = async () => {

// ----- set measure info boxes --------------------------------------------------- //

renderAboutSources(selectedTrendAbout, selectedTrendSources);
renderAboutSources(selectedTrendAbout, selectedTrendSources, selectedTrendDataSourceLinks);

// ----- render the chart --------------------------------------------------- //

aqFilteredTrendData = aq.from(filteredTrendData);

renderTrendChart(aqFilteredTrendData, aqSelectedTrendMetadata);
Expand Down Expand Up @@ -2025,24 +2041,27 @@ const renderMeasures = async () => {

selectedComparisonAbout = [];
selectedComparisonSources = [];
selectedComparisonDataSourceLinks = [];

aqComparisonIndicatorsMetadata.objects().forEach(m => {

selectedComparisonAbout +=
`<p><strong>${m.IndicatorName} - ${m.MeasurementType}:</strong> ${m.how_calculated}</p>`;

selectedComparisonSources.push(m.Sources);
selectedComparisonDataSourceLinks.push(...(m.DataSourceLink ?? []));

})

// get unique sources

let uniqueSelectedComparisonSources = [...new Set(selectedComparisonSources)];
let uniqueComparisonDataSourceLinks = [...new Map(selectedComparisonDataSourceLinks.map(l => [l.url, l])).values()];

// render the measure info boxes

renderTitleDescription(indicatorShortName, indicatorDesc);
renderAboutSources(selectedComparisonAbout, uniqueSelectedComparisonSources);
renderAboutSources(selectedComparisonAbout, uniqueSelectedComparisonSources, uniqueComparisonDataSourceLinks);


// ----- create dataset --------------------------------------------------- //
Expand Down Expand Up @@ -2109,7 +2128,7 @@ const renderMeasures = async () => {

// ----- set measure info boxes --------------------------------------------------- //

renderAboutSources(selectedComparisonAbout, selectedComparisonSources);
renderAboutSources(selectedComparisonAbout, selectedComparisonSources, selectedComparisonDataSourceLinks);

// ----- render the chart --------------------------------------------------- //

Expand Down Expand Up @@ -2272,12 +2291,17 @@ const renderMeasures = async () => {

defaultLinksSources = [];
defaultLinksSources.push(primarySources)
defaultLinksSources.push(secondarySources)
defaultLinksSources.push(secondarySources)

defaultLinksDataSourceLinks = [
...(defaultPrimaryLinksMeasureMetadata[0]?.DataSourceLink ?? []),
...(defaultSecondaryMeasureMetadata[0]?.DataSourceLink ?? [])
];

// ----- create dataset - - - - - - - - - - - - - - - - - - - - - - - - - - //

renderTitleDescription(indicatorShortName, indicatorDesc);
renderAboutSources(defaultLinksAbout, defaultLinksSources);
renderAboutSources(defaultLinksAbout, defaultLinksSources, defaultLinksDataSourceLinks);


// ----- render the chart - - - - - - - - - - - - - - - - - - - - - - - - - - //
Expand Down Expand Up @@ -2369,7 +2393,7 @@ const renderMeasures = async () => {

// ----- set measure info boxes - - - - - - - - - - - - - - - - - - - - - - - - - - //

renderAboutSources(selectedLinksAbout, selectedLinksSources);
renderAboutSources(selectedLinksAbout, selectedLinksSources, selectedLinksDataSourceLinks);

// ----- render the chart - - - - - - - - - - - - - - - - - - - - - - - - - - //

Expand Down