mirror of
https://github.com/mayswind/ezbookkeeping.git
synced 2026-05-19 17:24:26 +08:00
heat map and calendar heat map charts support data export in insights explorer
This commit is contained in:
@@ -26,6 +26,7 @@ const props = defineProps<{
|
|||||||
class?: string;
|
class?: string;
|
||||||
skeleton?: boolean;
|
skeleton?: boolean;
|
||||||
showValue?: boolean;
|
showValue?: boolean;
|
||||||
|
categoryTypeName: string;
|
||||||
allCategoryNames: string[];
|
allCategoryNames: string[];
|
||||||
items: Record<string, unknown>[];
|
items: Record<string, unknown>[];
|
||||||
nameField: string;
|
nameField: string;
|
||||||
@@ -44,6 +45,7 @@ const {
|
|||||||
tt,
|
tt,
|
||||||
getCurrentLanguageTextDirection,
|
getCurrentLanguageTextDirection,
|
||||||
formatAmountToLocalizedNumeralsWithCurrency,
|
formatAmountToLocalizedNumeralsWithCurrency,
|
||||||
|
formatAmountToWesternArabicNumeralsWithoutDigitGrouping,
|
||||||
formatNumberToLocalizedNumerals,
|
formatNumberToLocalizedNumerals,
|
||||||
formatPercentToLocalizedNumerals
|
formatPercentToLocalizedNumerals
|
||||||
} = useI18n();
|
} = useI18n();
|
||||||
@@ -265,6 +267,42 @@ function getDisplayValue(value: number): string {
|
|||||||
|
|
||||||
return formatNumberToLocalizedNumerals(value, 2);
|
return formatNumberToLocalizedNumerals(value, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function exportData(): { headers: string[], data: string[][] } {
|
||||||
|
const headers: string[] = [];
|
||||||
|
const data: string[][] = [];
|
||||||
|
|
||||||
|
headers.push(props.categoryTypeName);
|
||||||
|
|
||||||
|
for (const categoryName of props.allCategoryNames) {
|
||||||
|
headers.push(categoryName);
|
||||||
|
}
|
||||||
|
|
||||||
|
const allData: Record<string, number> = {};
|
||||||
|
|
||||||
|
for (const item of heatMapData.value.data) {
|
||||||
|
allData[`${item[0]}-${item[1]}`] = item[2];
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const [seriesName, seriesKey] of itemAndIndex(heatMapData.value.allSeriesNames)) {
|
||||||
|
const row: string[] = [];
|
||||||
|
row.push(seriesName);
|
||||||
|
for (let categoryIndex = 0; categoryIndex < props.allCategoryNames.length; categoryIndex++) {
|
||||||
|
const value = allData[`${categoryIndex}-${seriesKey}`];
|
||||||
|
row.push(formatAmountToWesternArabicNumeralsWithoutDigitGrouping(value ?? 0, props.defaultCurrency));
|
||||||
|
}
|
||||||
|
data.push(row);
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
headers: headers,
|
||||||
|
data: data
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
exportData
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
|||||||
@@ -187,12 +187,15 @@
|
|||||||
:all-category-names="[]"
|
:all-category-names="[]"
|
||||||
:items="[]"
|
:items="[]"
|
||||||
:value-type-name="tt(TransactionExplorerValueMetric.valueOf(currentExplorer.valueMetric)?.name ?? 'Value')"
|
:value-type-name="tt(TransactionExplorerValueMetric.valueOf(currentExplorer.valueMetric)?.name ?? 'Value')"
|
||||||
|
category-type-name=""
|
||||||
name-field="name"
|
name-field="name"
|
||||||
values-field="values"
|
values-field="values"
|
||||||
v-if="loading"
|
v-if="loading"
|
||||||
/>
|
/>
|
||||||
<heat-map-chart
|
<heat-map-chart
|
||||||
|
ref="heatmapChart"
|
||||||
:show-value="true"
|
:show-value="true"
|
||||||
|
:category-type-name="currentTransactionExplorerCategoryDimensionName"
|
||||||
:all-category-names="categoriedNamesSortedByDisplayOrder"
|
:all-category-names="categoriedNamesSortedByDisplayOrder"
|
||||||
:items="seriesDimensionTransactionExplorerData"
|
:items="seriesDimensionTransactionExplorerData"
|
||||||
:value-type-name="tt(TransactionExplorerValueMetric.valueOf(currentExplorer.valueMetric)?.name ?? 'Value')"
|
:value-type-name="tt(TransactionExplorerValueMetric.valueOf(currentExplorer.valueMetric)?.name ?? 'Value')"
|
||||||
@@ -229,6 +232,7 @@
|
|||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import AxisChart, { type AxisChartDisplayType } from '@/components/desktop/AxisChart.vue';
|
import AxisChart, { type AxisChartDisplayType } from '@/components/desktop/AxisChart.vue';
|
||||||
|
import HeatMapChart from '@/components/desktop/HeatMapChart.vue';
|
||||||
|
|
||||||
import { computed, useTemplateRef } from 'vue';
|
import { computed, useTemplateRef } from 'vue';
|
||||||
import { useRouter } from 'vue-router';
|
import { useRouter } from 'vue-router';
|
||||||
@@ -265,6 +269,7 @@ import { getCurrentDateTime, parseDateTimeFromString } from '@/lib/datetime.ts';
|
|||||||
import { sortStatisticsItems } from '@/lib/statistics.ts';
|
import { sortStatisticsItems } from '@/lib/statistics.ts';
|
||||||
|
|
||||||
type AxisChartType = InstanceType<typeof AxisChart>;
|
type AxisChartType = InstanceType<typeof AxisChart>;
|
||||||
|
type HeatMapChartType = InstanceType<typeof HeatMapChart>;
|
||||||
|
|
||||||
interface InsightsExplorerDataTableTabProps {
|
interface InsightsExplorerDataTableTabProps {
|
||||||
loading?: boolean;
|
loading?: boolean;
|
||||||
@@ -327,6 +332,7 @@ const userStore = useUserStore();
|
|||||||
const explorersStore = useExplorersStore();
|
const explorersStore = useExplorersStore();
|
||||||
|
|
||||||
const axisChart = useTemplateRef<AxisChartType>('axisChart');
|
const axisChart = useTemplateRef<AxisChartType>('axisChart');
|
||||||
|
const heatmapChart = useTemplateRef<HeatMapChartType>('heatmapChart');
|
||||||
|
|
||||||
const numeralSystem = computed<NumeralSystem>(() => getCurrentNumeralSystemType());
|
const numeralSystem = computed<NumeralSystem>(() => getCurrentNumeralSystemType());
|
||||||
const defaultCurrency = computed<string>(() => userStore.currentUserDefaultCurrency);
|
const defaultCurrency = computed<string>(() => userStore.currentUserDefaultCurrency);
|
||||||
@@ -876,7 +882,7 @@ function onClickTrendChartItem(itemId: string, categoryIndex: number): void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function buildExportResults(): { headers: string[], data: string[][], supportedMermaidCharts?: ExportMermaidChartType[] } | undefined {
|
function buildExportResults(): { headers: string[], data: string[][], supportedMermaidCharts?: ExportMermaidChartType[] } | undefined {
|
||||||
if (currentExplorer.value.chartType === TransactionExplorerChartType.Pie.value || currentExplorer.value.chartType === TransactionExplorerChartType.Radar.value) {
|
if (currentExplorer.value.chartType === TransactionExplorerChartType.Pie.value || currentExplorer.value.chartType === TransactionExplorerChartType.Radar.value || currentExplorer.value.chartType === TransactionExplorerChartType.CalendarHeatmap.value) {
|
||||||
const valueMetric = TransactionExplorerValueMetric.valueOf(currentExplorer.value.valueMetric);
|
const valueMetric = TransactionExplorerValueMetric.valueOf(currentExplorer.value.valueMetric);
|
||||||
let supportedMermaidCharts: ExportMermaidChartType[] | undefined = undefined;
|
let supportedMermaidCharts: ExportMermaidChartType[] | undefined = undefined;
|
||||||
|
|
||||||
@@ -928,6 +934,18 @@ function buildExportResults(): { headers: string[], data: string[][], supportedM
|
|||||||
data: results.data,
|
data: results.data,
|
||||||
supportedMermaidCharts: supportedMermaidCharts
|
supportedMermaidCharts: supportedMermaidCharts
|
||||||
};
|
};
|
||||||
|
} else if (TransactionExplorerChartType.valueOf(currentExplorer.value.chartType)?.seriesDimensionRequired && currentExplorer.value.chartType === TransactionExplorerChartType.Heatmap.value) {
|
||||||
|
const results = heatmapChart.value?.exportData();
|
||||||
|
|
||||||
|
if (!results) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
headers: results.headers,
|
||||||
|
data: results.data,
|
||||||
|
supportedMermaidCharts: undefined
|
||||||
|
};
|
||||||
} else {
|
} else {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user