From 6837f50b7c99c82000bc6b6b87e1bc847561bf66 Mon Sep 17 00:00:00 2001 From: Michael Levin Date: Thu, 9 Jan 2025 15:26:43 -0500 Subject: [PATCH] [Feature] Add report download links/icons to charts --- js/components/chart/ConsolidatedBarChart.js | 2 +- .../ConsolidatedBarChart.spec.js.snap | 86 +- .../AverageEngagementDuration.js | 4 +- .../dashboard_content/BrowsersChart.js | 17 +- .../dashboard_content/DashboardContent.js | 7 +- .../dashboard_content/DeviceDemographics.js | 13 + .../dashboard_content/DevicesChart.js | 17 +- .../dashboard_content/EngagementRate.js | 4 +- .../OperatingSystemsChart.js | 19 +- .../dashboard_content/Sessions30Days.js | 26 +- .../dashboard_content/SidebarContent.js | 76 +- .../dashboard_content/TopCitiesRealtime.js | 17 +- .../dashboard_content/TopCountriesRealtime.js | 21 +- .../dashboard_content/TopDownloads.js | 16 +- .../TopDownloadsAndVideoPlays.js | 49 +- .../TopLanguagesHistorical.js | 15 +- .../dashboard_content/TopPagesHistorical.js | 2 +- .../dashboard_content/TopPagesRealtime.js | 2 +- .../dashboard_content/TopVideoPlays.js | 2 +- .../dashboard_content/TrafficSources.js | 26 + .../__snapshots__/BrowsersChart.spec.js.snap | 91 +- .../DeviceDemographics.spec.js.snap | 70 +- .../__snapshots__/DevicesChart.spec.js.snap | 71 +- .../OperatingSystemsChart.spec.js.snap | 105 +- .../__snapshots__/Sessions30Days.spec.js.snap | 40 + .../__snapshots__/SidebarContent.spec.js.snap | 252 +- .../TopCitiesRealtime.spec.js.snap | 97 +- .../TopCountriesRealtime.spec.js.snap | 394 +- .../__snapshots__/TopDownloads.spec.js.snap | 436 +- .../TopDownloadsAndVideoPlays.spec.js.snap | 4624 ++++++++++------- .../TopLanguagesHistorical.spec.js.snap | 85 +- .../TopPagesHistorical.spec.js.snap | 46 +- .../TopPagesRealtime.spec.js.snap | 46 +- .../__snapshots__/TopVideoPlays.spec.js.snap | 42 +- .../__snapshots__/TrafficSources.spec.js.snap | 34 +- js/lib/chart_helpers/barchart.js | 7 +- sass/_colors.scss | 8 + sass/elements/_chart.scss | 13 +- sass/pages/root/_secondary-data.scss | 94 +- 39 files changed, 4293 insertions(+), 2683 deletions(-) diff --git a/js/components/chart/ConsolidatedBarChart.js b/js/components/chart/ConsolidatedBarChart.js index 4df00308..f3b2ac5b 100644 --- a/js/components/chart/ConsolidatedBarChart.js +++ b/js/components/chart/ConsolidatedBarChart.js @@ -41,7 +41,7 @@ function ConsolidatedBarChart({ dataUrl, chartDataKey, maxItems }) { return (
-
+
); } diff --git a/js/components/chart/__tests__/__snapshots__/ConsolidatedBarChart.spec.js.snap b/js/components/chart/__tests__/__snapshots__/ConsolidatedBarChart.spec.js.snap index 168f608e..5474cd1d 100644 --- a/js/components/chart/__tests__/__snapshots__/ConsolidatedBarChart.spec.js.snap +++ b/js/components/chart/__tests__/__snapshots__/ConsolidatedBarChart.spec.js.snap @@ -6,7 +6,7 @@ exports[`ConsolidatedBarChart when data is loaded and the expected key does not id="chart_browser" >
@@ -18,10 +18,10 @@ exports[`ConsolidatedBarChart when data is loaded and the expected key exists in id="chart_browser" >
@@ -211,10 +211,10 @@ exports[`ConsolidatedBarChart when data is loaded and the expected key exists in id="chart_browser" >
@@ -386,7 +386,7 @@ exports[`ConsolidatedBarChart when data is not loaded renders a component in loa id="chart_browser" >
@@ -398,7 +398,7 @@ exports[`ConsolidatedBarChart when data loading has an error renders a component id="chart_browser" >
diff --git a/js/components/dashboard_content/AverageEngagementDuration.js b/js/components/dashboard_content/AverageEngagementDuration.js index 757b4689..d87a6e90 100644 --- a/js/components/dashboard_content/AverageEngagementDuration.js +++ b/js/components/dashboard_content/AverageEngagementDuration.js @@ -19,14 +19,14 @@ import Tooltip from "../tooltip/Tooltip"; * @returns {import('react').ReactElement} The rendered element */ function AverageEngagementDuration({ dataHrefBase }) { - const dataURL = `${dataHrefBase}/engagement-duration-30-days.json`; + const jsonDataURL = `${dataHrefBase}/engagement-duration-30-days.json`; const ref = useRef(null); const [engagementDurationData, setEngagementDurationData] = useState(null); useEffect(() => { const initEngagementDurationsChart = async () => { if (!engagementDurationData) { - const data = await DataLoader.loadJSON(dataURL); + const data = await DataLoader.loadJSON(jsonDataURL); await setEngagementDurationData(data); } else { const chartBuilder = new ChartBuilder(); diff --git a/js/components/dashboard_content/BrowsersChart.js b/js/components/dashboard_content/BrowsersChart.js index b694d669..a655f295 100644 --- a/js/components/dashboard_content/BrowsersChart.js +++ b/js/components/dashboard_content/BrowsersChart.js @@ -17,14 +17,15 @@ import Tooltip from "../tooltip/Tooltip"; * @returns {import('react').ReactElement} The rendered element */ function BrowsersChart({ dataHrefBase }) { - const dataURL = `${dataHrefBase}/browsers.json`; + const jsonDataURL = `${dataHrefBase}/browsers.json`; + const csvDataURL = `${dataHrefBase}/browsers.csv`; const ref = useRef(null); const [browserData, setBrowserData] = useState(null); useEffect(() => { const initBrowsersChart = async () => { if (!browserData) { - const data = await DataLoader.loadJSON(dataURL); + const data = await DataLoader.loadJSON(jsonDataURL); await setBrowserData(data); } else { const chartBuilder = new ChartBuilder(); @@ -49,9 +50,19 @@ function BrowsersChart({ dataHrefBase }) { Web Browsers + + +
-
+
); diff --git a/js/components/dashboard_content/DashboardContent.js b/js/components/dashboard_content/DashboardContent.js index b6348dee..30bef27c 100644 --- a/js/components/dashboard_content/DashboardContent.js +++ b/js/components/dashboard_content/DashboardContent.js @@ -176,7 +176,7 @@ function DashboardContent({ dataURL, dataPrefix, agency }) { content="Top cities and countries from which user activity originated, and top language settings in user browsers. Location data may be affected by a user's VPN usage." >

Daily Sessions

@@ -261,7 +260,7 @@ function DashboardContent({ dataURL, dataPrefix, agency }) { content="Top traffic sources for the last 30 days." >
{ const initDevicesChart = async () => { if (!deviceData) { - const data = await DataLoader.loadJSON(dataURL); + const data = await DataLoader.loadJSON(jsonDataURL); await setDeviceData(data); } else { const chartBuilder = new ChartBuilder(); @@ -65,9 +66,19 @@ function DevicesChart({ dataHrefBase }) { Devices + + +
-
+
); diff --git a/js/components/dashboard_content/EngagementRate.js b/js/components/dashboard_content/EngagementRate.js index 5d6db4a0..0b0d1300 100644 --- a/js/components/dashboard_content/EngagementRate.js +++ b/js/components/dashboard_content/EngagementRate.js @@ -18,14 +18,14 @@ import Tooltip from "../tooltip/Tooltip"; * @returns {import('react').ReactElement} The rendered element */ function EngagementRate({ dataHrefBase }) { - const dataURL = `${dataHrefBase}/engagement-rate-30-days.json`; + const jsonDataURL = `${dataHrefBase}/engagement-rate-30-days.json`; const ref = useRef(null); const [engagementRateData, setEngagementRateData] = useState(null); useEffect(() => { const initEngagementRateChart = async () => { if (!engagementRateData) { - const data = await DataLoader.loadJSON(dataURL); + const data = await DataLoader.loadJSON(jsonDataURL); await setEngagementRateData(data); } else { const chartBuilder = new ChartBuilder(); diff --git a/js/components/dashboard_content/OperatingSystemsChart.js b/js/components/dashboard_content/OperatingSystemsChart.js index 5acec747..f8ccd198 100644 --- a/js/components/dashboard_content/OperatingSystemsChart.js +++ b/js/components/dashboard_content/OperatingSystemsChart.js @@ -19,7 +19,8 @@ import Tooltip from "../tooltip/Tooltip"; * @returns {import('react').ReactElement} The rendered element */ function OperatingSystemsChart({ dataHrefBase }) { - const osDataURL = `${dataHrefBase}/os.json`; + const osJsonDataURL = `${dataHrefBase}/os.json`; + const osCsvDataURL = `${dataHrefBase}/os.csv`; const windowsDataURL = `${dataHrefBase}/windows.json`; const osRef = useRef(null); const windowsRef = useRef(null); @@ -30,7 +31,7 @@ function OperatingSystemsChart({ dataHrefBase }) { useEffect(() => { const initOsCharts = async () => { if (!osData || !windowsData) { - await setOsData(await DataLoader.loadJSON(osDataURL)); + await setOsData(await DataLoader.loadJSON(osJsonDataURL)); await setWindowsData(await DataLoader.loadJSON(windowsDataURL)); } else { let chartBuilder = new ChartBuilder(); @@ -68,9 +69,19 @@ function OperatingSystemsChart({ dataHrefBase }) { Operating Systems + + +
-
+
-
+
); diff --git a/js/components/dashboard_content/Sessions30Days.js b/js/components/dashboard_content/Sessions30Days.js index 08573424..389c952c 100644 --- a/js/components/dashboard_content/Sessions30Days.js +++ b/js/components/dashboard_content/Sessions30Days.js @@ -18,14 +18,15 @@ import formatters from "../../lib/chart_helpers/formatters"; * @returns {import('react').ReactElement} The rendered element */ function Sessions30Days({ dataHrefBase }) { - const dataURL = `${dataHrefBase}/daily-sessions-30-days.json`; + const jsonDataURL = `${dataHrefBase}/daily-sessions-30-days.json`; + const csvDataURL = `${dataHrefBase}/daily-sessions-30-days.csv`; const ref = useRef(null); const [sessionData, setSessionData] = useState(null); useEffect(() => { const initSessionsChart = async () => { if (!sessionData) { - const data = await DataLoader.loadJSON(dataURL); + const data = await DataLoader.loadJSON(jsonDataURL); await setSessionData(data); } else { const chartBuilder = new ChartBuilder(); @@ -67,9 +68,24 @@ function Sessions30Days({ dataHrefBase }) { }, [sessionData]); return ( -
- -
+ <> +
+ Daily Sessions + + + +
+
+ +
+ ); } diff --git a/js/components/dashboard_content/SidebarContent.js b/js/components/dashboard_content/SidebarContent.js index 878620d8..cee072d0 100644 --- a/js/components/dashboard_content/SidebarContent.js +++ b/js/components/dashboard_content/SidebarContent.js @@ -84,13 +84,29 @@ function SidebarContent({ dataHrefBase, agency }) { -
-

+

+

Users on a{" "} single, specific page or app screen in the last 30 minutes. Hostnames are not currently reported in real-time, so only page title and screen name information is available.

+

+ + Download the data + + +

-
-

+

+

Sessions over the last week on hostnames, including traffic to all web pages and app screens within that hostname.

+

+ + Download the data + + +

-
-

+

+

Sessions over the last month on hostnames, including traffic to all web pages and app screens within that - hostname.{" "} - - Download the full dataset + hostname. +

+

+ + Download the data + - .

diff --git a/js/components/dashboard_content/TopCitiesRealtime.js b/js/components/dashboard_content/TopCitiesRealtime.js index 69db6880..3f2bfd73 100644 --- a/js/components/dashboard_content/TopCitiesRealtime.js +++ b/js/components/dashboard_content/TopCitiesRealtime.js @@ -20,19 +20,20 @@ import Tooltip from "../tooltip/Tooltip"; * @returns {import('react').ReactElement} The rendered element */ function TopCitiesRealtime({ dataHrefBase, refreshSeconds }) { - const dataURL = `${dataHrefBase}/top-cities-realtime.json`; + const jsonDataURL = `${dataHrefBase}/top-cities-realtime.json`; + const csvDataURL = `${dataHrefBase}/top-cities-realtime.csv`; const ref = useRef(null); const [realtimeCitiesData, setRealtimeCitiesData] = useState(null); useEffect(() => { const initRealtimeCitiesChart = async () => { if (!realtimeCitiesData) { - const data = await DataLoader.loadJSON(dataURL); + const data = await DataLoader.loadJSON(jsonDataURL); await setRealtimeCitiesData(data); // Refresh data every interval. useEffect will run and update the chart // when the state is changed. setInterval(() => { - DataLoader.loadJSON(dataURL).then((data) => { + DataLoader.loadJSON(jsonDataURL).then((data) => { setRealtimeCitiesData(data); }); }, refreshSeconds * 1000); @@ -70,6 +71,16 @@ function TopCitiesRealtime({ dataHrefBase, refreshSeconds }) { Cities + + +
diff --git a/js/components/dashboard_content/TopCountriesRealtime.js b/js/components/dashboard_content/TopCountriesRealtime.js index 25845d44..60bbd589 100644 --- a/js/components/dashboard_content/TopCountriesRealtime.js +++ b/js/components/dashboard_content/TopCountriesRealtime.js @@ -23,7 +23,8 @@ import Tooltip from "../tooltip/Tooltip"; * @returns {import('react').ReactElement} The rendered element */ function TopCountriesRealtime({ dataHrefBase, refreshSeconds }) { - const dataURL = `${dataHrefBase}/top-countries-realtime.json`; + const jsonDataURL = `${dataHrefBase}/top-countries-realtime.json`; + const csvDataURL = `${dataHrefBase}/top-countries-realtime.csv`; const countriesRef = useRef(null); const usTerritoriesRef = useRef(null); const internationalVisitsRef = useRef(null); @@ -33,12 +34,12 @@ function TopCountriesRealtime({ dataHrefBase, refreshSeconds }) { useEffect(() => { const initRealtimeCountriesChart = async () => { if (!countryData) { - const data = await DataLoader.loadJSON(dataURL); + const data = await DataLoader.loadJSON(jsonDataURL); await setCountryData(data); // Refresh data every interval. useEffect will run and update the chart // when the state is changed. setInterval(() => { - DataLoader.loadJSON(dataURL).then((data) => { + DataLoader.loadJSON(jsonDataURL).then((data) => { setCountryData(data); setChartsLoaded(false); }); @@ -156,6 +157,16 @@ function TopCountriesRealtime({ dataHrefBase, refreshSeconds }) { Countries + + +
@@ -166,7 +177,7 @@ function TopCountriesRealtime({ dataHrefBase, refreshSeconds }) { className="hide chart__bar-chart__nested" ref={usTerritoriesRef} > -
+
-
+
); diff --git a/js/components/dashboard_content/TopDownloads.js b/js/components/dashboard_content/TopDownloads.js index e5c6c5d9..da0259c7 100644 --- a/js/components/dashboard_content/TopDownloads.js +++ b/js/components/dashboard_content/TopDownloads.js @@ -47,20 +47,24 @@ function TopDownloads({ .value((d) => +d.total_events) .label( (d) => - ` + `
+ +
+ ${formatters.formatURL(d.page)} / - + download file - `, + +
+
`, ) .scale((values) => d3.scale @@ -78,7 +82,7 @@ function TopDownloads({ return (
-
+
); } diff --git a/js/components/dashboard_content/TopDownloadsAndVideoPlays.js b/js/components/dashboard_content/TopDownloadsAndVideoPlays.js index 81f62e7f..26984ed6 100644 --- a/js/components/dashboard_content/TopDownloadsAndVideoPlays.js +++ b/js/components/dashboard_content/TopDownloadsAndVideoPlays.js @@ -36,13 +36,14 @@ function TopDownloadsAndVideoPlays({ const numberOfTopDownloadsToDisplay = 10; const numberOfTopVideoPlaysToDisplay = 10; - const videoDataURL = `${dataHrefBase}/${videoPlaysReportFileName}`; + const jsonVideoDataURL = `${dataHrefBase}/${videoPlaysReportFileName}.json`; + const csvVideoDataURL = `${dataHrefBase}/${videoPlaysReportFileName}.csv`; const [videoPlayData, setVideoPlayData] = useState(null); useEffect(() => { const getVideoPlayData = async () => { if (!videoPlayData) { - const data = await DataLoader.loadJSON(videoDataURL); + const data = await DataLoader.loadJSON(jsonVideoDataURL); await setVideoPlayData(data); } }; @@ -66,7 +67,7 @@ function TopDownloadsAndVideoPlays({ return ( <> -
+
-

+

Top file downloads {timeIntervalDescription} on {agency} hostnames. -

+

+

+ + Download the data + + +

@@ -121,13 +138,29 @@ function TopDownloadsAndVideoPlays({
-

+

{__shouldDisplayVideoPlays() ? `Top videos played ${timeIntervalDescription} on ${agency} hostnames.` : `Video play data is unavailable for ${agency} hostnames.`} -

+

+

+ + Download the data + + +

{__shouldDisplayVideoPlays() ? ( { const initLanguagesChart = async () => { if (!languageData) { - const data = await DataLoader.loadJSON(dataURL); + const data = await DataLoader.loadJSON(jsonDataURL); await setLanguageData(data); } else { const chartBuilder = new ChartBuilder(); @@ -79,6 +80,16 @@ function TopLanguagesHistorical({ dataHrefBase }) { Languages + + +
diff --git a/js/components/dashboard_content/TopPagesHistorical.js b/js/components/dashboard_content/TopPagesHistorical.js index a8a20a6e..eb01788d 100644 --- a/js/components/dashboard_content/TopPagesHistorical.js +++ b/js/components/dashboard_content/TopPagesHistorical.js @@ -76,7 +76,7 @@ function TopPagesHistorical({ return (
-
+
); } diff --git a/js/components/dashboard_content/TopPagesRealtime.js b/js/components/dashboard_content/TopPagesRealtime.js index 1cdefef7..1ae5ba52 100644 --- a/js/components/dashboard_content/TopPagesRealtime.js +++ b/js/components/dashboard_content/TopPagesRealtime.js @@ -81,7 +81,7 @@ function TopPagesRealtime({ return (
-
+
); } diff --git a/js/components/dashboard_content/TopVideoPlays.js b/js/components/dashboard_content/TopVideoPlays.js index 564c2b72..a9a54467 100644 --- a/js/components/dashboard_content/TopVideoPlays.js +++ b/js/components/dashboard_content/TopVideoPlays.js @@ -61,7 +61,7 @@ function TopVideoPlays({ videoPlayData, numberOfListingsToDisplay }) { return (
-
+
); } diff --git a/js/components/dashboard_content/TrafficSources.js b/js/components/dashboard_content/TrafficSources.js index a20c989c..7f4ea24b 100644 --- a/js/components/dashboard_content/TrafficSources.js +++ b/js/components/dashboard_content/TrafficSources.js @@ -32,6 +32,19 @@ function TrafficSources({ dataHrefBase }) { Top Channels + + +
@@ -250,12 +265,27 @@ exports[`BrowsersChart when data is not loaded renders a component in loading st + + +
@@ -290,12 +320,27 @@ exports[`BrowsersChart when data loading has an error renders a component in err + + +
diff --git a/js/components/dashboard_content/__tests__/__snapshots__/DeviceDemographics.spec.js.snap b/js/components/dashboard_content/__tests__/__snapshots__/DeviceDemographics.spec.js.snap index 25a0ce83..6d1e8a12 100644 --- a/js/components/dashboard_content/__tests__/__snapshots__/DeviceDemographics.spec.js.snap +++ b/js/components/dashboard_content/__tests__/__snapshots__/DeviceDemographics.spec.js.snap @@ -36,12 +36,27 @@ exports[`DeviceDemographics renders 1`] = ` + + +
@@ -115,12 +145,27 @@ exports[`DeviceDemographics renders 1`] = ` + + +
@@ -156,12 +201,27 @@ exports[`DeviceDemographics renders 1`] = ` + + +
diff --git a/js/components/dashboard_content/__tests__/__snapshots__/DevicesChart.spec.js.snap b/js/components/dashboard_content/__tests__/__snapshots__/DevicesChart.spec.js.snap index ad7badb9..94d79c24 100644 --- a/js/components/dashboard_content/__tests__/__snapshots__/DevicesChart.spec.js.snap +++ b/js/components/dashboard_content/__tests__/__snapshots__/DevicesChart.spec.js.snap @@ -29,15 +29,30 @@ exports[`DevicesChart when data is loaded renders a component with data loaded 1 + + +
@@ -160,12 +175,27 @@ exports[`DevicesChart when data is not loaded renders a component in loading sta + + +
@@ -200,12 +230,27 @@ exports[`DevicesChart when data loading has an error renders a component in erro + + +
diff --git a/js/components/dashboard_content/__tests__/__snapshots__/OperatingSystemsChart.spec.js.snap b/js/components/dashboard_content/__tests__/__snapshots__/OperatingSystemsChart.spec.js.snap index bf3163b9..9ed8882f 100644 --- a/js/components/dashboard_content/__tests__/__snapshots__/OperatingSystemsChart.spec.js.snap +++ b/js/components/dashboard_content/__tests__/__snapshots__/OperatingSystemsChart.spec.js.snap @@ -30,15 +30,30 @@ exports[`OperatingSystemsChart when data is loaded renders a component with data + + +
@@ -198,7 +213,7 @@ exports[`OperatingSystemsChart when data is loaded renders a component with data
@@ -305,12 +320,27 @@ exports[`OperatingSystemsChart when data is not loaded renders a component in lo + + +
@@ -356,12 +386,27 @@ exports[`OperatingSystemsChart when data loading has an error renders a componen + + +
diff --git a/js/components/dashboard_content/__tests__/__snapshots__/Sessions30Days.spec.js.snap b/js/components/dashboard_content/__tests__/__snapshots__/Sessions30Days.spec.js.snap index 6a1cb564..02874d77 100644 --- a/js/components/dashboard_content/__tests__/__snapshots__/Sessions30Days.spec.js.snap +++ b/js/components/dashboard_content/__tests__/__snapshots__/Sessions30Days.spec.js.snap @@ -2,6 +2,26 @@ exports[`Sessions30Days when data is not loaded renders a component in loading state 1`] = ` +
+ Daily Sessions + + + +
@@ -14,6 +34,26 @@ exports[`Sessions30Days when data is not loaded renders a component in loading s exports[`Sessions30Days when data loading has an error renders a component in error state 1`] = ` +
+ Daily Sessions + + + +
diff --git a/js/components/dashboard_content/__tests__/__snapshots__/SidebarContent.spec.js.snap b/js/components/dashboard_content/__tests__/__snapshots__/SidebarContent.spec.js.snap index 83da024a..badfca2a 100644 --- a/js/components/dashboard_content/__tests__/__snapshots__/SidebarContent.spec.js.snap +++ b/js/components/dashboard_content/__tests__/__snapshots__/SidebarContent.spec.js.snap @@ -118,25 +118,47 @@ exports[`SidebarContent when 7 days tab is selected renders a component with top role="tabpanel" >
-

Top file downloads over the last week on Department of Interior hostnames. -

+

+

+ + Download the data + + +

@@ -236,13 +278,33 @@ exports[`SidebarContent when 7 days tab is selected renders a component with top
-

Video play data is unavailable for Department of Interior hostnames. -

+

+

+ + Download the data + + +

@@ -381,31 +443,47 @@ exports[`SidebarContent when 30 days tab is selected renders a component with to role="tabpanel" >
-

Top file downloads over the last month on Department of Interior hostnames. -

+

+

+ + Download the data + + +

@@ -505,13 +603,33 @@ exports[`SidebarContent when 30 days tab is selected renders a component with to
-

Video play data is unavailable for Department of Interior hostnames. -

+

+

+ + Download the data + + +

@@ -632,9 +750,11 @@ exports[`SidebarContent when 30 minutes tab is selected renders a component with role="tabpanel" >
-

Top file downloads yesterday on Department of Interior hostnames. -

+

+

+ + Download the data + + +

@@ -751,13 +911,33 @@ exports[`SidebarContent when 30 minutes tab is selected renders a component with
-

Video play data is unavailable for Department of Interior hostnames. -

+

+

+ + Download the data + + +

diff --git a/js/components/dashboard_content/__tests__/__snapshots__/TopCitiesRealtime.spec.js.snap b/js/components/dashboard_content/__tests__/__snapshots__/TopCitiesRealtime.spec.js.snap index 2dba1214..737dbe7e 100644 --- a/js/components/dashboard_content/__tests__/__snapshots__/TopCitiesRealtime.spec.js.snap +++ b/js/components/dashboard_content/__tests__/__snapshots__/TopCitiesRealtime.spec.js.snap @@ -29,6 +29,21 @@ exports[`TopCitiesRealtime when data is loaded renders a component with data loa + + +
@@ -304,6 +319,21 @@ exports[`TopCitiesRealtime when data is not loaded renders a component in loadin + + +
+ + +
+ + +
@@ -358,7 +373,7 @@ exports[`TopCountriesRealtime when data is loaded and a country with name "" exi id="chart_us_and_territories" >
@@ -397,6 +412,21 @@ exports[`TopCountriesRealtime when data is loaded and a country with name null e + + +
@@ -723,7 +753,7 @@ exports[`TopCountriesRealtime when data is loaded and a country with name null e id="chart_us_and_territories" >
@@ -762,6 +792,21 @@ exports[`TopCountriesRealtime when data is loaded and a country with name undefi + + +
@@ -1082,7 +1127,7 @@ exports[`TopCountriesRealtime when data is loaded and a country with name undefi
@@ -1184,6 +1229,21 @@ exports[`TopCountriesRealtime when data is loaded and all country names are vali + + +
@@ -1504,7 +1564,7 @@ exports[`TopCountriesRealtime when data is loaded and all country names are vali
@@ -1606,6 +1666,21 @@ exports[`TopCountriesRealtime when data is not loaded renders a component in loa + + +
@@ -1666,6 +1741,21 @@ exports[`TopCountriesRealtime when data loading has an error renders a component + + +
diff --git a/js/components/dashboard_content/__tests__/__snapshots__/TopDownloads.spec.js.snap b/js/components/dashboard_content/__tests__/__snapshots__/TopDownloads.spec.js.snap index 6b7f3e45..9e3d9b34 100644 --- a/js/components/dashboard_content/__tests__/__snapshots__/TopDownloads.spec.js.snap +++ b/js/components/dashboard_content/__tests__/__snapshots__/TopDownloads.spec.js.snap @@ -6,66 +6,78 @@ exports[`TopDownloads when data is loaded renders a component with data loaded 1 class="top-downloads__bar-chart" >
- + - - +
+ - - + + robust-childhood.com - - + + - - / - - + + / + + - - + + - - + + download file - + + + + + + +
- +
- + - - +
+ - - + + early-locality.org - - + + - - / - - + + / + + - - + + - - + + download file - + + + + + + +
- +
- + - - +
+ - - + + wide-intervention.name - - + + - - / - - + + / + + - - + + - - + + download file - + + + + + + +
- +
- + - - +
+ - - + + vain-coil.name - - + + - - / - - + + / + + - - + + - - + + download file - + + + + + + +
- +
- + - - +
+ - - + + shameful-contest.org - - + + - - / - - + + / + + - - + + - - + + download file - + + + + + + +
- +
@@ -364,7 +424,7 @@ exports[`TopDownloads when data is not loaded renders a component in loading sta class="top-downloads__bar-chart" >
@@ -376,7 +436,7 @@ exports[`TopDownloads when data loading has an error renders a component in erro class="top-downloads__bar-chart" >
diff --git a/js/components/dashboard_content/__tests__/__snapshots__/TopDownloadsAndVideoPlays.spec.js.snap b/js/components/dashboard_content/__tests__/__snapshots__/TopDownloadsAndVideoPlays.spec.js.snap index 567e6602..5828b086 100644 --- a/js/components/dashboard_content/__tests__/__snapshots__/TopDownloadsAndVideoPlays.spec.js.snap +++ b/js/components/dashboard_content/__tests__/__snapshots__/TopDownloadsAndVideoPlays.spec.js.snap @@ -3,7 +3,7 @@ exports[`TopDownloadsAndVideoPlays when data is loaded and video play data has > 2 results renders a component with data loaded 1`] = `
-

Top file downloads over the last week on NASA hostnames. -

+

+

+ + Download the data + + +

- + - - +
+ + + - - frayed-bulb.com - - + + + + + / + + - - / - - + - - - - + + download file - + + + + + + +
- +
2,002
- + - - +
+ + + - - unfit-tune.info - - + + + + + / + + - - / - - + - - - - + + download file - + + + + + + +
- +
9,889
- + - - +
+ + + - - major-innocence.name - - + + + + + / + + - - / - - + - - - - + + download file - + + + + + + +
- +
3,671
- + - - +
+ + + - - favorite-dune.org - - + + + + + / + + - - / - - + - - - - + + download file - + + + + + + +
- +
3,487
- + - - +
+ + + - - criminal-futon.biz - - + + + + + / + + - - / - - + - - - - + + download file - + + + + + + +
- +
7,353
- + - - +
+ + + - - stark-iris.org - - + + + + + / + + - - / - - + - - - - + + download file - + + + + + + +
- +
6,703
- + - - +
+ + + - - perfect-reveal.org - - + + + + + / + + - - / - - + - - - - + + download file - + + + + + + +
- +
2,532
- + - - +
+ + + - - low-superiority.com - - + + + + + / + + - - / - - + - - - - + + download file - + + + + + + +
- +
6,477
- + - - +
+ + + - - outgoing-fraction.com - - + + + + + / + + - - / - - + - - - - + + download file - + + + + + + +
- +
282
- + - - +
+ + + - - ambitious-venture.biz - - + + + + + / + + - - / - - + - - - - + + download file - + + + + + + +
- +
6,353
@@ -794,21 +934,41 @@ exports[`TopDownloadsAndVideoPlays when data is loaded and video play data has >
-

Top videos played over the last week on NASA hostnames. -

+

+

+ + Download the data + + +

7,410
9,078
2,177
3,888
3,831
5,994
3,288
7,669
6,760
4,298
@@ -1056,7 +1216,7 @@ exports[`TopDownloadsAndVideoPlays when data is loaded and video play data has > exports[`TopDownloadsAndVideoPlays when data is loaded and video play data has 2 results renders a component with data loaded 1`] = `
-

Top file downloads over the last week on NASA hostnames. -

+

+

+ + Download the data + + +

- + + +
+ + + + bright-monotheism.net - - + + - - / - - + + / + + + + - - - - + + download file - + + + + + + +
-
+
- + - - +
+ + + - - admirable-art.org - - + + - - / - - + + / + + + + - - - - + + download file - + + + + + + +
- +
- + - - +
+ + + - - whimsical-pipe.com - - + + - - / - - + + / + + + + - - - - + + download file - + + + + + + +
- +
- + - - +
+ + + - - ringed-sweatsuit.net - - + + - - / - - + + / + + + + - - - - + + download file - + + + + + + +
- +
- + - - +
+ + + - - pointed-necktie.info - - + + - - / - - + + / + + + + - - - - + + download file - + + + + + + +
- +
- + - - +
+ + + - - quarterly-stallion.org - - + + - - / - - + + / + + + + - - - - + + download file - + + + + + + +
- +
- + - - +
+ + + - - scornful-behest.info - - + + - - / - - + + / + + + + - - - - + + download file - + + + + + + +
- +
- + - - +
+ + + - - emotional-custard.net - - + + + + + / + + - - / - - + - - - - + + download file - + + + + + + +
- +
- + - - +
+ + + - - nervous-recipient.com - - + + - - / - - + + / + + + + - - - - + + download file - + + + + + + +
- +
- + - - +
+ + + - - fitting-scallops.biz - - + + - - / - - + + / + + + + - - - - + + download file - + + + + + + +
- +
- + - - +
+ + + - - heartfelt-crook.biz - - + + - - / - - + + / + + + + - - - - + + download file - + + + + + + +
- +
- + - - +
+ + + - - exciting-disclaimer.info - - + + - - / - - + + / + + + + - - - - + + download file - + + + + + + +
- +
- + - - +
+ + + - - tame-name.name - - + + - - / - - + + / + + + + - - - - + + download file - + + + + + + +
- +
- + - - +
+ + + - - giddy-octagon.org - - + + - - / - - + + / + + + + - - - - + + download file - + + + + + + +
- +
- + - - +
+ + + - - early-dragster.net - - + + - - / - - + + / + + + + - - - - + + download file - + + + + + + +
- +
- + - - +
+ + + - - gray-aggression.info - - + + - - / - - + + / + + + + - - - - + + download file - + + + + + + +
- +
- + - - +
+ + + - - heartfelt-elite.net - - + + - - / - - + + / + + + + - - - - + + download file - + + + + + + +
- +
- + - - +
+ + + - - overjoyed-sage.org - - + + - - / - - + + / + + + + - - - - + + download file - + + + + + + +
- +
- + - - +
+ + + - - critical-lobby.com - - + + - - / - - + + / + + + + - - - - + + download file - + + + + + + +
- +
- + - - +
+ + + - - jumbo-fahrenheit.info - - + + - - / - - + + / + + + + - - - - + + download file - + + + + + + +
- +
@@ -2537,13 +2957,33 @@ exports[`TopDownloadsAndVideoPlays when data is loaded and video play data has 2
-

Video play data is unavailable for NASA hostnames. -

+

+

+ + Download the data + + +

@@ -2552,7 +2992,7 @@ exports[`TopDownloadsAndVideoPlays when data is loaded and video play data has 2 exports[`TopDownloadsAndVideoPlays when data is loaded and video play data is empty renders a component with data loaded 1`] = `
-

Top file downloads over the last week on NASA hostnames. -

+

+

+ + Download the data + + +

- + - - +
+ + + - - robust-childhood.com - - + + + + + / + + - - / - - + - - - - + + download file - + + + + + + +
- +
- + - - +
+ + + - - early-locality.org - - + + + + + / + + - - / - - + - - - - + + download file - + + + + + + +
- +
- + - - +
+ + + - - wide-intervention.name - - + + + + + / + + - - / - - + - - - - + + download file - + + + + + + +
- +
- + - - +
+ + + - - vain-coil.name - - + + + + + / + + - - / - - + - - - - + + download file - + + + + + + +
- +
- + - - +
+ + + - - shameful-contest.org - - + + + + + / + + - - / - - + - - - - + + download file - + + + + + + +
- +
- + - - +
+ + + - - unwelcome-pressroom.com - - + + + + + / + + - - / - - + - - - - + + download file - + + + + + + +
- +
- + - - +
+ + + - - eager-breakdown.net - - + + + + + / + + - - / - - + - - - - + + download file - + + + + + + +
- +
- + - - +
+ + + - - honest-reliability.name - - + + + + + / + + - - / - - + - - - - + + download file - + + + + + + +
- +
- + - - +
+ + + - - hidden-yarn.org - - + + + + + / + + - - / - - + - - - - + + download file - + + + + + + +
- +
- + - - +
+ + + - - outgoing-journalism.name - - + + + + + / + + - - / - - + - - - - + + download file - + + + + + + +
- +
- + - - +
+ + + - - giant-daddy.name - - + + + + + / + + - - / - - + - - - - + + download file - + + + + + + +
- +
- + - - +
+ + + - - smoggy-obligation.name - - + + + + + / + + - - / - - + - - - - + + download file - + + + + + + +
- +
- + - - +
+ + + - - ragged-millet.org - - + + + + + / + + - - / - - + - - - - + + download file - + + + + + + +
- +
- + - - +
+ + + - - indelible-amount.biz - - + + + + + / + + - - / - - + - - - - + + download file - + + + + + + +
- +
- + - - +
+ + + - - lumbering-living.biz - - + + + + + / + + - - / - - + - - - - + + download file - + + + + + + +
- +
- + - - +
+ + + - - suspicious-antler.net - - + + + + + / + + - - / - - + - - - - + + download file - + + + + + + +
- +
- + - - +
+ + + - - lavish-cenotaph.org - - + + + + + / + + - - / - - + - - - - + + download file - + + + + + + +
- +
- + - - +
+ + + - - cool-autumn.info - - + + + + + / + + - - / - - + - - - - + + download file - + + + + + + +
- +
- + - - +
+ + + - - dramatic-quartz.org - - + + + + + / + + - - / - - + - - - - + + download file - + + + + + + +
- +
- + - - +
+ + + - - graceful-cabinet.name - - + + + + + / + + - - / - - + - - - - + + download file - + + + + + + +
- +
@@ -4033,13 +4733,33 @@ exports[`TopDownloadsAndVideoPlays when data is loaded and video play data is em
-

Video play data is unavailable for NASA hostnames. -

+

+

+ + Download the data + + +

@@ -4048,7 +4768,7 @@ exports[`TopDownloadsAndVideoPlays when data is loaded and video play data is em exports[`TopDownloadsAndVideoPlays when data is not loaded renders a component in loading state 1`] = `
-

Top file downloads over the last week on NASA hostnames. -

+

+

+ + Download the data + + +

@@ -4148,13 +4888,33 @@ exports[`TopDownloadsAndVideoPlays when data is not loaded renders a component i
-

Video play data is unavailable for NASA hostnames. -

+

+

+ + Download the data + + +

@@ -4163,7 +4923,7 @@ exports[`TopDownloadsAndVideoPlays when data is not loaded renders a component i exports[`TopDownloadsAndVideoPlays when data loading has an error renders a component in error state 1`] = `
-

Top file downloads over the last week on NASA hostnames. -

+

+

+ + Download the data + + +

@@ -4263,13 +5043,33 @@ exports[`TopDownloadsAndVideoPlays when data loading has an error renders a comp
-

Video play data is unavailable for NASA hostnames. -

+

+

+ + Download the data + + +

diff --git a/js/components/dashboard_content/__tests__/__snapshots__/TopLanguagesHistorical.spec.js.snap b/js/components/dashboard_content/__tests__/__snapshots__/TopLanguagesHistorical.spec.js.snap index b64f8dba..3d44fdbe 100644 --- a/js/components/dashboard_content/__tests__/__snapshots__/TopLanguagesHistorical.spec.js.snap +++ b/js/components/dashboard_content/__tests__/__snapshots__/TopLanguagesHistorical.spec.js.snap @@ -29,6 +29,21 @@ exports[`TopLanguagesHistorical when data is loaded renders a component with dat + + +
@@ -250,6 +265,21 @@ exports[`TopLanguagesHistorical when data is not loaded renders a component in l + + +
+ + +
@@ -259,7 +259,7 @@ exports[`TopPagesHistorical when data is not loaded renders a component in loadi data-source="http://www.example.com/data//foobar.json" >
@@ -271,7 +271,7 @@ exports[`TopPagesHistorical when data loading has an error renders a component i data-source="http://www.example.com/data//foobar.json" >
diff --git a/js/components/dashboard_content/__tests__/__snapshots__/TopPagesRealtime.spec.js.snap b/js/components/dashboard_content/__tests__/__snapshots__/TopPagesRealtime.spec.js.snap index 3a85b492..66434044 100644 --- a/js/components/dashboard_content/__tests__/__snapshots__/TopPagesRealtime.spec.js.snap +++ b/js/components/dashboard_content/__tests__/__snapshots__/TopPagesRealtime.spec.js.snap @@ -4,10 +4,10 @@ exports[`TopPagesRealtime when data is loaded renders a component with data load
@@ -195,7 +195,7 @@ exports[`TopPagesRealtime when data is not loaded renders a component in loading
@@ -205,7 +205,7 @@ exports[`TopPagesRealtime when data loading has an error renders a component in
diff --git a/js/components/dashboard_content/__tests__/__snapshots__/TopVideoPlays.spec.js.snap b/js/components/dashboard_content/__tests__/__snapshots__/TopVideoPlays.spec.js.snap index 1afce1b0..e249c211 100644 --- a/js/components/dashboard_content/__tests__/__snapshots__/TopVideoPlays.spec.js.snap +++ b/js/components/dashboard_content/__tests__/__snapshots__/TopVideoPlays.spec.js.snap @@ -6,10 +6,10 @@ exports[`TopVideoPlays renders a component with data loaded 1`] = ` class="top-video-plays__bar-chart" >
diff --git a/js/components/dashboard_content/__tests__/__snapshots__/TrafficSources.spec.js.snap b/js/components/dashboard_content/__tests__/__snapshots__/TrafficSources.spec.js.snap index 0d4a7c0e..0a503050 100644 --- a/js/components/dashboard_content/__tests__/__snapshots__/TrafficSources.spec.js.snap +++ b/js/components/dashboard_content/__tests__/__snapshots__/TrafficSources.spec.js.snap @@ -36,6 +36,21 @@ exports[`TrafficSources renders 1`] = ` + + +
@@ -80,6 +95,21 @@ exports[`TrafficSources renders 1`] = ` + + +
diff --git a/js/lib/chart_helpers/barchart.js b/js/lib/chart_helpers/barchart.js index b8de4b73..579dd712 100644 --- a/js/lib/chart_helpers/barchart.js +++ b/js/lib/chart_helpers/barchart.js @@ -35,7 +35,7 @@ export default function barChart() { const enter = bin .enter() .append("div") - .attr("class", "chart__bar-chart__item"); + .attr("class", "chart__bar-chart__item margin-bottom-2"); enter .append("div") .attr( @@ -45,7 +45,10 @@ export default function barChart() { enter.append("div").attr("class", "chart__bar-chart__item__value"); enter .append("div") - .attr("class", "chart__bar-chart__item__bar bg-palette-color-5") + .attr( + "class", + "chart__bar-chart__item__bar bg-palette-color-5 margin-top-0", + ) .style("width", "0%"); const componentScale = scale diff --git a/sass/_colors.scss b/sass/_colors.scss index e32b2a16..1147e3df 100644 --- a/sass/_colors.scss +++ b/sass/_colors.scss @@ -77,6 +77,10 @@ $palette-colors: ( &:hover { color: $black; } + + &:visited { + color: $black; + } } .dark-grey { @@ -85,6 +89,10 @@ $palette-colors: ( &:hover { color: $dark-gray; } + + &:visited { + color: $dark-gray; + } } .white { diff --git a/sass/elements/_chart.scss b/sass/elements/_chart.scss index f80daeed..c0c19294 100644 --- a/sass/elements/_chart.scss +++ b/sass/elements/_chart.scss @@ -18,7 +18,6 @@ @include clearfix; font-size: 1.25rem; - margin: 0 0 units(2); overflow: hidden; position: relative; } @@ -44,8 +43,6 @@ } .chart__bar-chart__item__label { - height: 2.2rem; - a { text-decoration: none; } @@ -56,9 +53,7 @@ } .chart__bar-chart__item__value { - height: 1.25rem; - margin-bottom: 0.45rem; - margin-top: -2.2rem; + margin-top: -1.9rem; text-align: right; white-space: nowrap; } @@ -66,7 +61,7 @@ .chart__bar-chart__nested { .chart__bar-chart { font-size: 80%; - margin: units(1) 0; + margin: units("05") 0; } .chart__bar-chart__item { @@ -74,6 +69,10 @@ margin-left: units(4); } + .chart__bar-chart__item__label { + height: 1.6rem; + } + .chart__bar-chart__item__bar { display: none; } diff --git a/sass/pages/root/_secondary-data.scss b/sass/pages/root/_secondary-data.scss index f1711aec..48e141f0 100644 --- a/sass/pages/root/_secondary-data.scss +++ b/sass/pages/root/_secondary-data.scss @@ -42,70 +42,13 @@ // Assumes there are 30 items in the top pages charts. Will need adjusted // accordingly if the number of chart items changes. min-height: 60rem; - border-bottom: 1px solid colors.$uswds-light-gray; - - .chart__bar-chart { - margin-top: 0; - } - - .chart__bar-chart__item__label { - color: colors.$dark-gray; - height: 2.2rem; - } - - .chart__bar-chart__item__value { - height: 1.25rem; - margin-bottom: 0.45rem; - margin-top: -2.2rem; - text-align: right; - white-space: nowrap; - } } .top-downloads { - border-bottom: 1px solid colors.$uswds-light-gray; - - &__headline { - padding-top: 0; - } - - h4 { - margin: units(1) 0 units(1) 0; - } - - &__bar-chart { - padding: 0; - - .chart__bar-chart { - margin-top: 0; - } - - .chart__bar-chart__item__label { - height: units(8); - height: 4rem; - line-height: 1.6; - - .top-download__page-name { - display: block; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; - } - - .top-download__page-domain { - color: colors.$dark-gray; - text-transform: lowercase; - } - - .top-download__file-location { - text-transform: lowercase; - } - } - - .chart__bar-chart__item__bar { - margin-top: units(2); - } - } + // This prevents "jumping" in the sidebar when chart data is loading. + // Assumes there are 30 items in the top pages charts. Will need adjusted + // accordingly if the number of chart items changes. + min-height: 10rem; } .top-video-plays { @@ -113,34 +56,5 @@ // Assumes there are 30 items in the top pages charts. Will need adjusted // accordingly if the number of chart items changes. min-height: 10rem; - - &__headline { - padding-top: 0; - } - - h4 { - margin: units(1) 0 units(1) 0; - } - - .chart__bar-chart { - margin-top: 0; - } - - .chart__bar-chart__item__label { - color: colors.$dark-gray; - height: auto; - line-height: normal; - } - - .chart__bar-chart__item__value { - height: auto; - margin-top: -1.5rem; - text-align: right; - white-space: nowrap; - } - - .chart__bar-chart__item { - margin-top: units(1); - } } }