Skip to content

Commit

Permalink
Improve MAT conditional filters (#752)
Browse files Browse the repository at this point in the history
* Drop fields from MAT form state when they are hidden

* Hide irrelevant options in X and Y axis based on test name

* Show Y axis countries option when All Countries selected

* Remove console log

* Improve handling of conditional filters

Co-authored-by: Maja Komel <[email protected]>
  • Loading branch information
sarathms and majakomel authored Dec 28, 2022
1 parent f9d1696 commit 9c5dfdd
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 34 deletions.
75 changes: 45 additions & 30 deletions components/aggregation/mat/Form.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useCallback, useEffect, useState, useRef, useLayoutEffect } from 'react'
import React, { useCallback, useEffect, useState, useMemo } from 'react'
import PropTypes from 'prop-types'
import { useForm, Controller } from 'react-hook-form'
import styled from 'styled-components'
Expand Down Expand Up @@ -55,18 +55,17 @@ const messages = defineMessages({


const xAxisOptions = [
'measurement_start_day',
'category_code',
'probe_cc',
['measurement_start_day', [], false],
['category_code', ['web_connectivity'], false],
['probe_cc', [], true],
]

const yAxisOptions = [
'domain',
'input',
'category_code',
'probe_cc',
'probe_asn',
''
['domain', ['web_connectivity'], false],
['category_code', ['web_connectivity'], false],
['probe_cc', [], true],
['probe_asn', [], false],
['', [], false]
]

const testsWithValidDomainFilter = [
Expand All @@ -76,6 +75,15 @@ const testsWithValidDomainFilter = [
'tcp_connect'
]

const filterAxisOptions = (options, countryValue, testNameValue) => {
return options
.filter(([option, validTestNames, hideForSingleCountry]) => {
if (hideForSingleCountry && countryValue !== '') return false
return validTestNames.length === 0 || validTestNames.includes(testNameValue)
})
.map(([option]) => option)
}

function isValidFilterForTestname(testName = 'XX', arrayWithMapping) {
// whether the dependent filter is valid to show along with `testName`
return arrayWithMapping.includes(testName)
Expand All @@ -99,36 +107,27 @@ const defaultDefaultValues = {
}

export const Form = ({ onSubmit, testNames, query }) => {
const isInitialMount = useRef(true)
const intl = useIntl()
const [showConfirmation, setShowConfirmation] = useState(false)

const defaultValues = Object.assign({}, defaultDefaultValues, query)
const { handleSubmit, control, getValues, watch, reset, setValue } = useForm({
defaultValues
defaultValues,
shouldUnregister: true,
})

// If `query` changes after the page mounts, reset the form to use default
// values based on new `query`
useEffect(() => {
// Skip running this on mount to avoid unnecessary re-renders
// Based on: https://reactjs.org/docs/hooks-faq.html#can-i-run-an-effect-only-on-updates
if (isInitialMount.current) {
isInitialMount.current = false
} else {
reset(Object.assign({}, defaultDefaultValues, query))
}
}, [reset, query])

const sortedCountries = localisedCountries(intl.locale)
.sort((a,b) => new Intl.Collator(intl.locale).compare(a.localisedCountryName, b.localisedCountryName))

const testNameValue = watch('test_name')
const showWebConnectivityFilters = isValidFilterForTestname(testNameValue, testsWithValidDomainFilter)
const countryValue = watch('probe_cc')
const showWebConnectivityFilters = useMemo(() => (isValidFilterForTestname(testNameValue, testsWithValidDomainFilter)), [testNameValue])
// reset domain and input when web_connectivity is deselected
useLayoutEffect(() => {
setValue('domain', '')
setValue('input', '')
useEffect(() => {
if (!showWebConnectivityFilters) {
setValue('domain', '')
setValue('input', '')
}
}, [setValue, showWebConnectivityFilters])

const [showDatePicker, setShowDatePicker] = useState(false)
Expand Down Expand Up @@ -170,6 +169,22 @@ export const Form = ({ onSubmit, testNames, query }) => {
}
}, [getValues, onConfirm])

const xAxisOptionsFiltered = useMemo(() => {
return filterAxisOptions(xAxisOptions, countryValue, testNameValue)
}, [testNameValue, countryValue])

useEffect(() => {
if (!xAxisOptionsFiltered.includes(getValues('axis_x'))) setValue('axis_x', 'measurement_start_day')
}, [setValue, getValues, xAxisOptionsFiltered])

const yAxisOptionsFiltered = useMemo(() => {
return filterAxisOptions(yAxisOptions, countryValue, testNameValue)
}, [testNameValue, countryValue])

useEffect(() => {
if (!yAxisOptionsFiltered.includes(getValues('axis_y'))) setValue('axis_y', '')
}, [setValue, getValues, yAxisOptionsFiltered])

return (
<form onSubmit={handleSubmit(onSubmit)}>
<ConfirmationModal show={showConfirmation} onConfirm={onConfirm} onCancel={onCancel} />
Expand Down Expand Up @@ -259,7 +274,7 @@ export const Form = ({ onSubmit, testNames, query }) => {
control={control}
render={({field}) => (
<Select {...field} width={1}>
{xAxisOptions.map((option, idx) => (
{xAxisOptionsFiltered.map((option, idx) => (
<option key={idx} value={option}>{option.length > 0 ? intl.formatMessage(messages[option]) : option}</option>
))}
</Select>
Expand All @@ -275,7 +290,7 @@ export const Form = ({ onSubmit, testNames, query }) => {
control={control}
render={({field}) => (
<Select {...field} width={1}>
{yAxisOptions.map((option, idx) => (
{yAxisOptionsFiltered.map((option, idx) => (
<option key={idx} value={option}>{option.length > 0 ? intl.formatMessage(messages[option]) : option}</option>
))}
</Select>
Expand Down
2 changes: 1 addition & 1 deletion pages/_app.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
// https://github.com/vercel/next.js/blob/canary/examples/with-loading/pages/_app.js
import 'scripts/wdyr'
import 'regenerator-runtime/runtime'
import { useEffect, useId, useMemo, useState } from 'react'
import { useEffect } from 'react'
import 'regenerator-runtime/runtime'
import NProgress from 'nprogress'
import { useRouter } from 'next/router'
Expand Down
6 changes: 3 additions & 3 deletions public/static/lang/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -462,8 +462,8 @@
"MAT.SubTitle": "Create charts based on aggregate views of real-time OONI data from around the world",
"MAT.JSONData": "JSON Data",
"MAT.CSVData": "CSV Data",
"MAT.Form.Label.XAxis": "X Axis",
"MAT.Form.Label.YAxis": "Y Axis",
"MAT.Form.Label.XAxis": "Columns",
"MAT.Form.Label.YAxis": "Rows",
"MAT.Form.Label.AxisOption.domain": "Domain",
"MAT.Form.Label.AxisOption.input": "Input",
"MAT.Form.Label.AxisOption.measurement_start_day": "Measurement Day",
Expand Down Expand Up @@ -496,7 +496,7 @@
"MAT.Charts.NoData.Details": "Details:",
"MAT.Help.Box.Title": "Help",
"MAT.Help.Title": "FAQs",
"MAT.Help.Content": "# What is the MAT?\n\nOONI's Measurement Aggregation Toolkit (MAT) is a tool that enables you to generate your own custom charts based on **aggregate views of real-time OONI data** collected from around the world.\n\nOONI data consists of network measurements collected by [OONI Probe](https://ooni.org/install/) users around the world. \n\nThese measurements contain information about various types of **internet censorship**, such as the [blocking of websites and apps](https://ooni.org/nettest/) around the world. \n\n# Who is the MAT for?\n\nThe MAT was built for researchers, journalists, and human rights defenders interested in examining internet censorship around the world.\n\n# Why use the MAT?\n\nWhen examining cases of internet censorship, it's important to **look at many measurements at once** (\"in aggregate\") in order to answer key questions like the following:\n\n* Does the testing of a service (e.g. Facebook) present **signs of blocking every time that it is tested** in a country? This can be helpful for ruling out [false positives](https://ooni.org/support/faq/#what-are-false-positives).\n* What types of websites (e.g. human rights websites) are blocked in each country?\n* In which countries is a specific website (e.g. `bbc.com`) blocked?\n* How does the blocking of different apps (e.g. WhatsApp or Telegram) vary across countries?\n* How does the blocking of a service vary across countries and [ASNs](https://ooni.org/support/glossary/#asn)?\n* How does the blocking of a service change over time?\n\nWhen trying to answer questions like the above, we normally perform relevant data analysis (instead of inspecting measurements one by one). \n\nThe MAT incorporates our data analysis techniques, enabling you to answer such questions without any data analysis skills, and with the click of a button!\n\n# How to use the MAT?\n\nThrough the filters at the start of the page, select the parameters you care about in order to plot charts based on aggregate views of OONI data.\n\nThe MAT includes the following filters:\n\n* **Countries:** Select a country through the drop-down menu (the \"All Countries\" option will show global coverage)\n* **Test Name:** Select an [OONI Probe test](https://ooni.org/nettest/) based on which you would like to get measurements (for example, select `Web Connectivity` to view the testing of websites)\n* **Domain:** Type the domain for the website you would like to get measurements (e.g. `twitter.com`)\n* **Website categories:** Select the [website category](https://github.com/citizenlab/test-lists/blob/master/lists/00-LEGEND-new_category_codes.csv) for which you would like to get measurements (e.g. `News Media` for news media websites)\n* **ASN:** Type the [ASN](https://ooni.org/support/glossary/#asn) of the network for which you would like to get measurements (e.g. `AS30722` for Vodafone Italia)\n* **Date range:** Select the date range of the measurements by adjusting the `Since` and `Until` filters\n* **X axis:** Select the values that you would like to appear on the horizontal axis of your chart\n* **Y axis:** Select the values that you would like to appear on the vertical axis of your chart\n\nDepending on what you would like to explore, adjust the MAT filters accordingly and click `Show Chart`. \n\nFor example, if you would like to check the testing of BBC in all countries around the world:\n\n* Type `www.bbc.com` under `Domain`\n* Select `Countries` under the `Y axis`\n* Click `Show Chart`\n\nThis will plot numerous charts based on the OONI Probe testing of `www.bbc.com` worldwide.\n\n# Interpreting MAT charts\n\nThe MAT charts (and associated tables) include the following values:\n\n* **OK count:** Successful measurements (i.e. NO sign of internet censorship)\n* **Confirmed count:** Measurements from automatically **confirmed blocked websites** (e.g. a [block page](https://ooni.org/support/glossary/#block-page) was served)\n* **Anomaly count:** Measurements that provided **signs of potential blocking** (however, [false positives](https://ooni.org/support/faq/#what-are-false-positives) can occur) \n* **Failure count:** Failed experiments that should be discarded\n* **Measurement count:** Total volume of OONI measurements (pertaining to the selected country, resource, etc.)\n\nWhen trying to identify the blocking of a service (e.g. `twitter.com`), it's useful to check whether:\n\n* Measurements are annotated as `confirmed`, automatically confirming the blocking of websites\n* A large volume of measurements (in comparison to the overall measurement count) present `anomalies` (i.e. signs of potential censorship)\n\nYou can access the raw data by clicking on the bars of charts, and subsequently clicking on the relevant measurement links. \n\n# Website categories\n\n[OONI Probe](https://ooni.org/install/) users test a wide range of [websites](https://ooni.org/support/faq/#which-websites-will-i-test-for-censorship-with-ooni-probe) that fall under the following [30 standardized categories](https://github.com/citizenlab/test-lists/blob/master/lists/00-LEGEND-new_category_codes.csv).",
"MAT.Help.Content": "# What is the MAT?\n\nOONI's Measurement Aggregation Toolkit (MAT) is a tool that enables you to generate your own custom charts based on **aggregate views of real-time OONI data** collected from around the world.\n\nOONI data consists of network measurements collected by [OONI Probe](https://ooni.org/install/) users around the world. \n\nThese measurements contain information about various types of **internet censorship**, such as the [blocking of websites and apps](https://ooni.org/nettest/) around the world. \n\n# Who is the MAT for?\n\nThe MAT was built for researchers, journalists, and human rights defenders interested in examining internet censorship around the world.\n\n# Why use the MAT?\n\nWhen examining cases of internet censorship, it's important to **look at many measurements at once** (\"in aggregate\") in order to answer key questions like the following:\n\n* Does the testing of a service (e.g. Facebook) present **signs of blocking every time that it is tested** in a country? This can be helpful for ruling out [false positives](https://ooni.org/support/faq/#what-are-false-positives).\n* What types of websites (e.g. human rights websites) are blocked in each country?\n* In which countries is a specific website (e.g. `bbc.com`) blocked?\n* How does the blocking of different apps (e.g. WhatsApp or Telegram) vary across countries?\n* How does the blocking of a service vary across countries and [ASNs](https://ooni.org/support/glossary/#asn)?\n* How does the blocking of a service change over time?\n\nWhen trying to answer questions like the above, we normally perform relevant data analysis (instead of inspecting measurements one by one). \n\nThe MAT incorporates our data analysis techniques, enabling you to answer such questions without any data analysis skills, and with the click of a button!\n\n# How to use the MAT?\n\nThrough the filters at the start of the page, select the parameters you care about in order to plot charts based on aggregate views of OONI data.\n\nThe MAT includes the following filters:\n\n* **Countries:** Select a country through the drop-down menu (the \"All Countries\" option will show global coverage)\n* **Test Name:** Select an [OONI Probe test](https://ooni.org/nettest/) based on which you would like to get measurements (for example, select `Web Connectivity` to view the testing of websites)\n* **Domain:** Type the domain for the website you would like to get measurements (e.g. `twitter.com`)\n* **Website categories:** Select the [website category](https://github.com/citizenlab/test-lists/blob/master/lists/00-LEGEND-new_category_codes.csv) for which you would like to get measurements (e.g. `News Media` for news media websites)\n* **ASN:** Type the [ASN](https://ooni.org/support/glossary/#asn) of the network for which you would like to get measurements (e.g. `AS30722` for Vodafone Italia)\n* **Date range:** Select the date range of the measurements by adjusting the `Since` and `Until` filters\n* **Columns:** Select the values that you would like to appear on the horizontal axis of your chart\n* **Rows:** Select the values that you would like to appear on the vertical axis of your chart\n\nDepending on what you would like to explore, adjust the MAT filters accordingly and click `Show Chart`. \n\nFor example, if you would like to check the testing of BBC in all countries around the world:\n\n* Type `www.bbc.com` under `Domain`\n* Select `Countries` under the `Rows`\n* Click `Show Chart`\n\nThis will plot numerous charts based on the OONI Probe testing of `www.bbc.com` worldwide.\n\n# Interpreting MAT charts\n\nThe MAT charts (and associated tables) include the following values:\n\n* **OK count:** Successful measurements (i.e. NO sign of internet censorship)\n* **Confirmed count:** Measurements from automatically **confirmed blocked websites** (e.g. a [block page](https://ooni.org/support/glossary/#block-page) was served)\n* **Anomaly count:** Measurements that provided **signs of potential blocking** (however, [false positives](https://ooni.org/support/faq/#what-are-false-positives) can occur) \n* **Failure count:** Failed experiments that should be discarded\n* **Measurement count:** Total volume of OONI measurements (pertaining to the selected country, resource, etc.)\n\nWhen trying to identify the blocking of a service (e.g. `twitter.com`), it's useful to check whether:\n\n* Measurements are annotated as `confirmed`, automatically confirming the blocking of websites\n* A large volume of measurements (in comparison to the overall measurement count) present `anomalies` (i.e. signs of potential censorship)\n\nYou can access the raw data by clicking on the bars of charts, and subsequently clicking on the relevant measurement links. \n\n# Website categories\n\n[OONI Probe](https://ooni.org/install/) users test a wide range of [websites](https://ooni.org/support/faq/#which-websites-will-i-test-for-censorship-with-ooni-probe) that fall under the following [30 standardized categories](https://github.com/citizenlab/test-lists/blob/master/lists/00-LEGEND-new_category_codes.csv).",
"MAT.Help.Subtitle.Categories": "Categories",
"MAT.CustomTooltip.ViewMeasurements": "View measurements",
"ReachabilityDash.Heading.CircumventionTools": "Reachability of Censorship Circumvention Tools",
Expand Down

1 comment on commit 9c5dfdd

@vercel
Copy link

@vercel vercel bot commented on 9c5dfdd Dec 28, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

explorer – ./

explorer-ooni1.vercel.app
explorer-one.vercel.app
explorer-git-master-ooni1.vercel.app

Please sign in to comment.