diff --git a/i18n/en.pot b/i18n/en.pot
index ec2d6dac34..0bddcb4f2a 100644
--- a/i18n/en.pot
+++ b/i18n/en.pot
@@ -5,8 +5,8 @@ msgstr ""
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
-"POT-Creation-Date: 2023-11-13T12:11:28.959Z\n"
-"PO-Revision-Date: 2023-11-13T12:11:28.959Z\n"
+"POT-Creation-Date: 2023-12-19T14:19:00.918Z\n"
+"PO-Revision-Date: 2023-12-19T14:19:00.918Z\n"
msgid "All items"
msgstr "All items"
@@ -1107,6 +1107,9 @@ msgstr ""
"View the relationship between two data items at a place or time. "
"Recommended for finding outliers."
+msgid "Automatically identify extreme outliers in the data"
+msgstr "Automatically identify extreme outliers in the data"
+
msgid "Weeks per year"
msgstr "Weeks per year"
diff --git a/src/assets/OutliersTableIcon.js b/src/assets/OutliersTableIcon.js
new file mode 100644
index 0000000000..4a9367739b
--- /dev/null
+++ b/src/assets/OutliersTableIcon.js
@@ -0,0 +1,30 @@
+import PropTypes from 'prop-types'
+import React from 'react'
+
+const OutliersTableIcon = ({
+ style = { paddingRight: '8px', width: 24, height: 24 },
+}) => (
+
+)
+
+OutliersTableIcon.propTypes = {
+ style: PropTypes.object,
+}
+
+export default OutliersTableIcon
diff --git a/src/components/Layout/Layout.js b/src/components/Layout/Layout.js
index dc9793b30c..a8abc19e06 100644
--- a/src/components/Layout/Layout.js
+++ b/src/components/Layout/Layout.js
@@ -3,14 +3,16 @@ import {
LAYOUT_TYPE_PIE,
LAYOUT_TYPE_YEAR_OVER_YEAR,
LAYOUT_TYPE_PIVOT_TABLE,
- getLayoutTypeByVisType,
LAYOUT_TYPE_SCATTER,
+ LAYOUT_TYPE_OUTLIERS_TABLE,
+ getLayoutTypeByVisType,
} from '@dhis2/analytics'
import PropTypes from 'prop-types'
import React from 'react'
import { connect } from 'react-redux'
import { sGetUiType } from '../../reducers/ui.js'
import DefaultLayout from './DefaultLayout/DefaultLayout.js'
+import OutliersTableLayout from './OutliersTable/OutliersTableLayout.js'
import PieLayout from './PieLayout/PieLayout.js'
import PivotTableLayout from './PivotTableLayout/PivotTableLayout.js'
import ScatterLayout from './ScatterLayout/ScatterLayout.js'
@@ -22,6 +24,7 @@ const componentMap = {
[LAYOUT_TYPE_YEAR_OVER_YEAR]: YearOverYearLayout,
[LAYOUT_TYPE_PIVOT_TABLE]: PivotTableLayout,
[LAYOUT_TYPE_SCATTER]: ScatterLayout,
+ [LAYOUT_TYPE_OUTLIERS_TABLE]: OutliersTableLayout,
}
const Layout = ({ visType }) => {
diff --git a/src/components/Layout/OutliersTable/OutliersTableLayout.js b/src/components/Layout/OutliersTable/OutliersTableLayout.js
new file mode 100644
index 0000000000..ebe296fe6c
--- /dev/null
+++ b/src/components/Layout/OutliersTable/OutliersTableLayout.js
@@ -0,0 +1,30 @@
+import { AXIS_ID_COLUMNS } from '@dhis2/analytics'
+import React from 'react'
+import DefaultAxis from '../DefaultLayout/DefaultAxis.js'
+import defaultAxisStyles from '../DefaultLayout/styles/DefaultAxis.style.js'
+import defaultLayoutStyles from '../DefaultLayout/styles/DefaultLayout.style.js'
+import outliersTableLayoutStyles from './styles/OutliersTableLayout.style.js'
+
+const Layout = () => (
+
+)
+
+Layout.displayName = 'Layout'
+
+export default Layout
diff --git a/src/components/Layout/OutliersTable/styles/OutliersTableLayout.style.js b/src/components/Layout/OutliersTable/styles/OutliersTableLayout.style.js
new file mode 100644
index 0000000000..c8c3cbabf5
--- /dev/null
+++ b/src/components/Layout/OutliersTable/styles/OutliersTableLayout.style.js
@@ -0,0 +1,5 @@
+export default {
+ axisGroupLeft: {
+ flexBasis: '100%',
+ },
+}
diff --git a/src/components/VisualizationTypeSelector/ListItemIcon.js b/src/components/VisualizationTypeSelector/ListItemIcon.js
index 7599c6f048..51ed9be3f6 100644
--- a/src/components/VisualizationTypeSelector/ListItemIcon.js
+++ b/src/components/VisualizationTypeSelector/ListItemIcon.js
@@ -14,6 +14,7 @@ import {
VIS_TYPE_SINGLE_VALUE,
VIS_TYPE_PIVOT_TABLE,
VIS_TYPE_SCATTER,
+ VIS_TYPE_OUTLIERS_TABLE,
} from '@dhis2/analytics'
import PropTypes from 'prop-types'
import React from 'react'
@@ -23,6 +24,7 @@ import ColumnIcon from '../../assets/ColumnIcon.js'
import GaugeIcon from '../../assets/GaugeIcon.js'
import GlobeIcon from '../../assets/GlobeIcon.js'
import LineIcon from '../../assets/LineIcon.js'
+import OutliersTableIcon from '../../assets/OutliersTableIcon.js'
import PieIcon from '../../assets/PieIcon.js'
import PivotTableIcon from '../../assets/PivotTableIcon.js'
import RadarIcon from '../../assets/RadarIcon.js'
@@ -66,6 +68,8 @@ const ListItemIcon = ({ iconType, style }) => {
return
case VIS_TYPE_SCATTER:
return
+ case VIS_TYPE_OUTLIERS_TABLE:
+ return
case VIS_TYPE_COLUMN:
default:
return
diff --git a/src/modules/layoutValidation.js b/src/modules/layoutValidation.js
index c2d9776abb..82953c2530 100644
--- a/src/modules/layoutValidation.js
+++ b/src/modules/layoutValidation.js
@@ -8,6 +8,7 @@ import {
VIS_TYPE_SINGLE_VALUE,
VIS_TYPE_PIVOT_TABLE,
VIS_TYPE_SCATTER,
+ VIS_TYPE_OUTLIERS_TABLE,
getPredefinedDimensionProp,
dimensionIsValid,
layoutGetDimension,
@@ -128,6 +129,18 @@ const validateScatterLayout = (layout) => {
)
}
+const validateOutliersTableLayout = (layout) => {
+ validateDimension(
+ layoutGetDimension(layout, DIMENSION_ID_DATA),
+ new NoDataError(layout.type)
+ )
+
+ validateDimension(
+ layoutGetDimension(layout, DIMENSION_ID_PERIOD),
+ new NoPeriodError(layout.type)
+ )
+}
+
export const validateLayout = (layout) => {
switch (layout.type) {
case VIS_TYPE_PIE:
@@ -142,6 +155,8 @@ export const validateLayout = (layout) => {
return validatePivotTableLayout(layout)
case VIS_TYPE_SCATTER:
return validateScatterLayout(layout)
+ case VIS_TYPE_OUTLIERS_TABLE:
+ return validateOutliersTableLayout(layout)
default:
return validateDefaultLayout(layout)
}
diff --git a/src/modules/visualization.js b/src/modules/visualization.js
index a762cbc9b1..811eb6c550 100644
--- a/src/modules/visualization.js
+++ b/src/modules/visualization.js
@@ -14,6 +14,7 @@ import {
VIS_TYPE_YEAR_OVER_YEAR_COLUMN,
VIS_TYPE_SINGLE_VALUE,
VIS_TYPE_SCATTER,
+ VIS_TYPE_OUTLIERS_TABLE,
} from '@dhis2/analytics'
import i18n from '@dhis2/d2-i18n'
import { DEFAULT_CURRENT } from '../reducers/current.js'
@@ -36,6 +37,7 @@ export const visTypes = [
VIS_TYPE_YEAR_OVER_YEAR_COLUMN,
VIS_TYPE_SINGLE_VALUE,
VIS_TYPE_SCATTER,
+ VIS_TYPE_OUTLIERS_TABLE,
]
export const getVisTypeDescriptions = () => ({
@@ -84,6 +86,9 @@ export const getVisTypeDescriptions = () => ({
[VIS_TYPE_SCATTER]: i18n.t(
'View the relationship between two data items at a place or time. Recommended for finding outliers.'
),
+ [VIS_TYPE_OUTLIERS_TABLE]: i18n.t(
+ 'Automatically identify extreme outliers in the data'
+ ),
})
export const getVisualizationFromCurrent = (current) => {