diff --git a/src/components/AdvanceAnalyticsV2/data/utils.js b/src/components/AdvanceAnalyticsV2/data/utils.js index d7bfb0250d..e08bc36c2c 100644 --- a/src/components/AdvanceAnalyticsV2/data/utils.js +++ b/src/components/AdvanceAnalyticsV2/data/utils.js @@ -1,4 +1,5 @@ import { CHART_TYPES } from './constants'; +import messages from '../messages'; const simulateURL = (activeTab, chartType) => { if (!Object.values(CHART_TYPES).includes(chartType)) { @@ -7,4 +8,17 @@ const simulateURL = (activeTab, chartType) => { return `${activeTab}/stats`; }; +/** + * Constructs a chart hover template. + * + * @param {Object} intl - Internationalization object. + * @param {Object} hoverInfo - Object containing hover information to show over chart data points. + * @returns {string} The constructed chart hover template. + */ +export function constructChartHoverTemplate(intl, hoverInfo) { + return Object.entries(hoverInfo) + .map(([key, value]) => `${intl.formatMessage(messages[key])}: ${value}`) + .join('
'); +} + export default simulateURL; diff --git a/src/components/AdvanceAnalyticsV2/data/utils.test.js b/src/components/AdvanceAnalyticsV2/data/utils.test.js new file mode 100644 index 0000000000..7733b401f4 --- /dev/null +++ b/src/components/AdvanceAnalyticsV2/data/utils.test.js @@ -0,0 +1,15 @@ +import { createIntl } from '@edx/frontend-platform/i18n'; +import { constructChartHoverTemplate } from './utils'; + +describe('constructChartHoverTemplate', () => { + const intl = createIntl({ + locale: 'en', + messages: {}, + }); + + it('should construct a hover template', () => { + const hoverInfo = { skill: 'value1', enrollments: 'value2' }; + const result = constructChartHoverTemplate(intl, hoverInfo); + expect(result).toBe('Skill: value1
Enrollments: value2'); + }); +}); diff --git a/src/components/AdvanceAnalyticsV2/messages.js b/src/components/AdvanceAnalyticsV2/messages.js new file mode 100644 index 0000000000..1fefaa0d48 --- /dev/null +++ b/src/components/AdvanceAnalyticsV2/messages.js @@ -0,0 +1,34 @@ +import { defineMessages } from '@edx/frontend-platform/i18n'; + +const messages = defineMessages({ + skill: { + id: 'advance.analytics.skill.label', + defaultMessage: 'Skill', + }, + enrollments: { + id: 'advance.analytics.enrollments.label', + defaultMessage: 'Enrollments', + }, + completions: { + id: 'advance.analytics.completions.label', + defaultMessage: 'Completions', + }, + date: { + id: 'advance.analytics.date.label', + defaultMessage: 'Date', + }, + course: { + id: 'advance.analytics.course.label', + defaultMessage: 'Course', + }, + subject: { + id: 'advance.analytics.subject.label', + defaultMessage: 'Subject', + }, + learningHours: { + id: 'advance.analytics.learning.hours.label', + defaultMessage: 'Learning Hours', + }, +}); + +export default messages; diff --git a/src/components/AdvanceAnalyticsV2/tabs/Completions.jsx b/src/components/AdvanceAnalyticsV2/tabs/Completions.jsx index 58a02fbdbe..a5eb6ff885 100644 --- a/src/components/AdvanceAnalyticsV2/tabs/Completions.jsx +++ b/src/components/AdvanceAnalyticsV2/tabs/Completions.jsx @@ -6,6 +6,7 @@ import { ANALYTICS_TABS, CHART_TYPES, chartColorMap } from '../data/constants'; import AnalyticsTable from './AnalyticsTable'; import ChartWrapper from '../charts/ChartWrapper'; import { useEnterpriseAnalyticsData } from '../data/hooks'; +import { constructChartHoverTemplate } from '../data/utils'; const Completions = ({ startDate, endDate, granularity, calculation, enterpriseId, @@ -58,7 +59,10 @@ const Completions = ({ colorMap: chartColorMap, xAxisTitle: '', yAxisTitle: 'Number of Completions', - hovertemplate: 'Date: %{x}
Number of Completions: %{y}', + hovertemplate: constructChartHoverTemplate(intl, { + date: '%{x}', + completions: '%{y}', + }), }} loadingMessage={intl.formatMessage({ id: 'advance.analytics.completions.tab.chart.top.courses.by.completions.loading.message', @@ -103,7 +107,10 @@ const Completions = ({ defaultMessage: 'Number of Completions', description: 'Y-axis title for the top courses by completions chart.', }), - hovertemplate: 'Course: %{x}
Number of Completions: %{y}', + hovertemplate: constructChartHoverTemplate(intl, { + course: '%{x}', + completions: '%{y}', + }), }} loadingMessage={intl.formatMessage({ id: 'advance.analytics.completions.tab.chart.top.10.courses.by.completions.loading.message', @@ -148,7 +155,10 @@ const Completions = ({ defaultMessage: 'Number of Completions', description: 'Y-axis title for the top subjects by completions chart.', }), - hovertemplate: 'Subject: %{x}
Number of Completions: %{y}', + hovertemplate: constructChartHoverTemplate(intl, { + subject: '%{x}', + completions: '%{y}', + }), }} loadingMessage={intl.formatMessage({ id: 'advance.analytics.completions.tab.chart.top.subjects.by.completions.loading.message', diff --git a/src/components/AdvanceAnalyticsV2/tabs/Engagements.jsx b/src/components/AdvanceAnalyticsV2/tabs/Engagements.jsx index 6d933e48c7..d6268933c2 100644 --- a/src/components/AdvanceAnalyticsV2/tabs/Engagements.jsx +++ b/src/components/AdvanceAnalyticsV2/tabs/Engagements.jsx @@ -6,6 +6,7 @@ import { ANALYTICS_TABS, CHART_TYPES, chartColorMap } from '../data/constants'; import AnalyticsTable from './AnalyticsTable'; import ChartWrapper from '../charts/ChartWrapper'; import { useEnterpriseAnalyticsData } from '../data/hooks'; +import { constructChartHoverTemplate } from '../data/utils'; const Engagements = ({ startDate, endDate, granularity, calculation, enterpriseId, @@ -55,7 +56,10 @@ const Engagements = ({ colorMap: chartColorMap, xAxisTitle: '', yAxisTitle: 'Number of Learning Hours', - hovertemplate: 'Date: %{x}
Learning Hours: %{y}', + hovertemplate: constructChartHoverTemplate(intl, { + date: '%{x}', + learningHours: '%{y}', + }), }} loadingMessage={intl.formatMessage({ id: 'advance.analytics.engagements.tab.chart.learning.hours.over.time.loading.message', @@ -98,7 +102,10 @@ const Engagements = ({ defaultMessage: 'Number of Learning Hours', description: 'Y-axis title for the top 10 courses by learning hours chart.', }), - hovertemplate: 'Course: %{x}
Learning Hours: %{y}', + hovertemplate: constructChartHoverTemplate(intl, { + course: '%{x}', + learningHours: '%{y}', + }), }} loadingMessage={intl.formatMessage({ id: 'advance.analytics.engagements.tab.chart.top.10.courses.by.learning.hours.loading.message', @@ -141,7 +148,10 @@ const Engagements = ({ defaultMessage: 'Number of Learning Hours', description: 'Y-axis title for the top 10 subjects by learning hours chart.', }), - hovertemplate: 'Subject: %{x}
Learning Hours: %{y}', + hovertemplate: constructChartHoverTemplate(intl, { + subject: '%{x}', + learningHours: '%{y}', + }), }} loadingMessage={intl.formatMessage({ id: 'advance.analytics.engagements.tab.chart.top.10.subjects.by.learning.hours.loading.message', diff --git a/src/components/AdvanceAnalyticsV2/tabs/Enrollments.jsx b/src/components/AdvanceAnalyticsV2/tabs/Enrollments.jsx index 02df8747f0..36cb9a24c5 100644 --- a/src/components/AdvanceAnalyticsV2/tabs/Enrollments.jsx +++ b/src/components/AdvanceAnalyticsV2/tabs/Enrollments.jsx @@ -6,6 +6,7 @@ import { ANALYTICS_TABS, CHART_TYPES, chartColorMap } from '../data/constants'; import AnalyticsTable from './AnalyticsTable'; import ChartWrapper from '../charts/ChartWrapper'; import { useEnterpriseAnalyticsData } from '../data/hooks'; +import { constructChartHoverTemplate } from '../data/utils'; const Enrollments = ({ startDate, endDate, granularity, calculation, enterpriseId, @@ -57,7 +58,10 @@ const Enrollments = ({ colorMap: chartColorMap, xAxisTitle: '', yAxisTitle: 'Number of Enrollments', - hovertemplate: 'Date: %{x}
Enrolls: %{y}', + hovertemplate: constructChartHoverTemplate(intl, { + date: '%{x}', + enrollments: '%{y}', + }), }} loadingMessage={intl.formatMessage({ id: 'advance.analytics.enrollments.tab.chart.enrollments.over.time.loading.message', @@ -93,13 +97,16 @@ const Enrollments = ({ chartType="BarChart" chartProps={{ data: data?.topCoursesByEnrollments, - xKey: 'courseKey', + xKey: 'courseTitle', yKey: 'count', colorKey: 'enrollType', colorMap: chartColorMap, xAxisTitle: '', yAxisTitle: 'Number of Enrollments', - hovertemplate: 'Course: %{x}
Enrolls: %{y}', + hovertemplate: constructChartHoverTemplate(intl, { + course: '%{x}', + enrollments: '%{y}', + }), }} loadingMessage={intl.formatMessage({ id: 'advance.analytics.enrollments.tab.chart.top.courses.by.enrollments.loading.message', @@ -142,6 +149,10 @@ const Enrollments = ({ xAxisTitle: '', yAxisTitle: 'Number of Enrollments', hovertemplate: 'Subject: %{x}
Enrolls: %{y}', + hovertemplate: constructChartHoverTemplate(intl, { + subject: '%{x}', + enrollments: '%{y}', + }), }} loadingMessage={intl.formatMessage({ id: 'advance.analytics.enrollments.tab.chart.top.subjects.by.enrollments.loading.message', diff --git a/src/components/AdvanceAnalyticsV2/tabs/Skills.jsx b/src/components/AdvanceAnalyticsV2/tabs/Skills.jsx index 1cd58463ff..c37c93e0a4 100644 --- a/src/components/AdvanceAnalyticsV2/tabs/Skills.jsx +++ b/src/components/AdvanceAnalyticsV2/tabs/Skills.jsx @@ -7,6 +7,7 @@ import { } from '../data/constants'; import { useEnterpriseAnalyticsData } from '../data/hooks'; import ChartWrapper from '../charts/ChartWrapper'; +import { constructChartHoverTemplate } from '../data/utils'; const Skills = ({ startDate, endDate, enterpriseId }) => { const intl = useIntl(); @@ -64,7 +65,11 @@ const Skills = ({ startDate, endDate, enterpriseId }) => { }), markerSizeKey: 'completions', customDataKeys: ['skillName', 'skillType'], - hovertemplate: 'Skill: %{customdata[0]}
Enrolls: %{x}
Completions: %{y}', + hovertemplate: constructChartHoverTemplate(intl, { + skill: '%{customdata[0]}', + enrollments: '%{x}', + completions: '%{y}', + }), }} loadingMessage={intl.formatMessage({ id: 'advance.analytics.skills.tab.chart.top.skills.loading.message', @@ -98,7 +103,10 @@ const Skills = ({ startDate, endDate, enterpriseId }) => { defaultMessage: 'Number of Enrollments', description: 'Y-axis title for the top skills by enrollment chart.', }), - hovertemplate: 'Skill: %{x}
Enrolls: %{y}', + hovertemplate: constructChartHoverTemplate(intl, { + skill: '%{x}', + enrollments: '%{y}', + }), }} loadingMessage={intl.formatMessage({ id: 'advance.analytics.skills.tab.chart.top.skills.by.enrollment.loading.message', @@ -132,7 +140,10 @@ const Skills = ({ startDate, endDate, enterpriseId }) => { defaultMessage: 'Number of Completions', description: 'Y-axis title for the top skills by completion chart.', }), - hovertemplate: 'Skill: %{x}
Completions: %{y}', + hovertemplate: constructChartHoverTemplate(intl, { + skill: '%{x}', + completions: '%{y}', + }), }} loadingMessage={intl.formatMessage({ id: 'advance.analytics.skills.tab.chart.top.skills.by.completion.loading.message',