add bubble chart for trends analysis

This commit is contained in:
MaysWind
2025-10-30 00:18:52 +08:00
parent 274fb8b4e2
commit 9f8dbf77df
20 changed files with 52 additions and 7 deletions
@@ -59,6 +59,7 @@ interface MonthlyTrendsChartDataItem {
type: string; type: string;
areaStyle?: object; areaStyle?: object;
stack?: string; stack?: string;
symbolSize?: (data: number) => number;
animation: boolean; animation: boolean;
data: number[]; data: number[];
} }
@@ -152,6 +153,7 @@ const allDisplayDateRanges = computed<string[]>(() => {
const allSeries = computed<MonthlyTrendsChartDataItem[]>(() => { const allSeries = computed<MonthlyTrendsChartDataItem[]>(() => {
const allSeries: MonthlyTrendsChartDataItem[] = []; const allSeries: MonthlyTrendsChartDataItem[] = [];
let maxAmount: number = 0;
for (const [item, index] of itemAndIndex(props.items)) { for (const [item, index] of itemAndIndex(props.items)) {
if (props.hiddenField && item[props.hiddenField]) { if (props.hiddenField && item[props.hiddenField]) {
@@ -208,6 +210,10 @@ const allSeries = computed<MonthlyTrendsChartDataItem[]>(() => {
} }
} }
if (amount > maxAmount) {
maxAmount = amount;
}
allAmounts.push(amount); allAmounts.push(amount);
} }
@@ -233,6 +239,11 @@ const allSeries = computed<MonthlyTrendsChartDataItem[]>(() => {
finalItem.areaStyle = {}; finalItem.areaStyle = {};
} else if (props.type === TrendChartType.Column.type) { } else if (props.type === TrendChartType.Column.type) {
finalItem.type = 'bar'; finalItem.type = 'bar';
} else if (props.type === TrendChartType.Bubble.type) {
finalItem.type = 'scatter';
finalItem.symbolSize = (data: number): number => {
return Math.sqrt(data) / Math.sqrt(maxAmount) * 80 + 5;
}
} }
allSeries.push(finalItem); allSeries.push(finalItem);
+13
View File
@@ -9,6 +9,7 @@ export enum StatisticsAnalysisType {
export class CategoricalChartType implements TypeAndName { export class CategoricalChartType implements TypeAndName {
private static readonly allInstancesForAll: CategoricalChartType[] = []; private static readonly allInstancesForAll: CategoricalChartType[] = [];
private static readonly allInstancesForDesktop: CategoricalChartType[] = []; private static readonly allInstancesForDesktop: CategoricalChartType[] = [];
private static readonly allInstancesByType: Record<number, CategoricalChartType> = {};
public static readonly Pie = new CategoricalChartType(0, 'Pie Chart', false); public static readonly Pie = new CategoricalChartType(0, 'Pie Chart', false);
public static readonly Bar = new CategoricalChartType(1, 'Bar Chart', false); public static readonly Bar = new CategoricalChartType(1, 'Bar Chart', false);
@@ -30,6 +31,11 @@ export class CategoricalChartType implements TypeAndName {
} }
CategoricalChartType.allInstancesForDesktop.push(this); CategoricalChartType.allInstancesForDesktop.push(this);
CategoricalChartType.allInstancesByType[type] = this;
}
public static isValidType(type: number): boolean {
return !!CategoricalChartType.allInstancesByType[type];
} }
public static values(withDesktopOnlyChart: boolean): CategoricalChartType[] { public static values(withDesktopOnlyChart: boolean): CategoricalChartType[] {
@@ -43,9 +49,11 @@ export class CategoricalChartType implements TypeAndName {
export class TrendChartType implements TypeAndName { export class TrendChartType implements TypeAndName {
private static readonly allInstances: TrendChartType[] = []; private static readonly allInstances: TrendChartType[] = [];
private static readonly allInstancesByType: Record<number, TrendChartType> = {};
public static readonly Area = new TrendChartType(0, 'Area Chart'); public static readonly Area = new TrendChartType(0, 'Area Chart');
public static readonly Column = new TrendChartType(1, 'Column Chart'); public static readonly Column = new TrendChartType(1, 'Column Chart');
public static readonly Bubble = new TrendChartType(2, 'Bubble Chart');
public static readonly Default = TrendChartType.Column; public static readonly Default = TrendChartType.Column;
@@ -57,6 +65,11 @@ export class TrendChartType implements TypeAndName {
this.name = name; this.name = name;
TrendChartType.allInstances.push(this); TrendChartType.allInstances.push(this);
TrendChartType.allInstancesByType[type] = this;
}
public static isValidType(type: number): boolean {
return !!TrendChartType.allInstancesByType[type];
} }
public static values(): TrendChartType[] { public static values(): TrendChartType[] {
+2 -1
View File
@@ -52,7 +52,7 @@ import 'vuetify/styles';
import * as echarts from 'echarts/core'; import * as echarts from 'echarts/core';
import { CanvasRenderer } from 'echarts/renderers'; import { CanvasRenderer } from 'echarts/renderers';
import { LineChart, BarChart, PieChart, CandlestickChart, RadarChart, SankeyChart } from 'echarts/charts'; import { LineChart, BarChart, PieChart, ScatterChart, CandlestickChart, RadarChart, SankeyChart } from 'echarts/charts';
import { import {
GridComponent, GridComponent,
TooltipComponent, TooltipComponent,
@@ -497,6 +497,7 @@ echarts.use([
LineChart, LineChart,
BarChart, BarChart,
PieChart, PieChart,
ScatterChart,
CandlestickChart, CandlestickChart,
RadarChart, RadarChart,
SankeyChart, SankeyChart,
+1
View File
@@ -1516,6 +1516,7 @@
"Radar Chart": "Radar Chart", "Radar Chart": "Radar Chart",
"Area Chart": "Flächendiagramm", "Area Chart": "Flächendiagramm",
"Column Chart": "Säulendiagramm", "Column Chart": "Säulendiagramm",
"Bubble Chart": "Bubble Chart",
"Candlestick Chart": "Candlestick Chart", "Candlestick Chart": "Candlestick Chart",
"Sankey Chart": "Sankey Chart", "Sankey Chart": "Sankey Chart",
"Sort by": "Sortieren nach", "Sort by": "Sortieren nach",
+1
View File
@@ -1516,6 +1516,7 @@
"Radar Chart": "Radar Chart", "Radar Chart": "Radar Chart",
"Area Chart": "Area Chart", "Area Chart": "Area Chart",
"Column Chart": "Column Chart", "Column Chart": "Column Chart",
"Bubble Chart": "Bubble Chart",
"Candlestick Chart": "Candlestick Chart", "Candlestick Chart": "Candlestick Chart",
"Sankey Chart": "Sankey Chart", "Sankey Chart": "Sankey Chart",
"Sort by": "Sort by", "Sort by": "Sort by",
+1
View File
@@ -1516,6 +1516,7 @@
"Radar Chart": "Radar Chart", "Radar Chart": "Radar Chart",
"Area Chart": "Gráfico de área", "Area Chart": "Gráfico de área",
"Column Chart": "Gráfico de columnas", "Column Chart": "Gráfico de columnas",
"Bubble Chart": "Bubble Chart",
"Candlestick Chart": "Candlestick Chart", "Candlestick Chart": "Candlestick Chart",
"Sankey Chart": "Sankey Chart", "Sankey Chart": "Sankey Chart",
"Sort by": "Ordenar por", "Sort by": "Ordenar por",
+1
View File
@@ -1516,6 +1516,7 @@
"Radar Chart": "Radar Chart", "Radar Chart": "Radar Chart",
"Area Chart": "Graphique en aires", "Area Chart": "Graphique en aires",
"Column Chart": "Graphique en colonnes", "Column Chart": "Graphique en colonnes",
"Bubble Chart": "Bubble Chart",
"Candlestick Chart": "Graphique en chandelier", "Candlestick Chart": "Graphique en chandelier",
"Sankey Chart": "Sankey Chart", "Sankey Chart": "Sankey Chart",
"Sort by": "Trier par", "Sort by": "Trier par",
+1
View File
@@ -1516,6 +1516,7 @@
"Radar Chart": "Radar Chart", "Radar Chart": "Radar Chart",
"Area Chart": "Grafico ad area", "Area Chart": "Grafico ad area",
"Column Chart": "Grafico a colonne", "Column Chart": "Grafico a colonne",
"Bubble Chart": "Bubble Chart",
"Candlestick Chart": "Candlestick Chart", "Candlestick Chart": "Candlestick Chart",
"Sankey Chart": "Sankey Chart", "Sankey Chart": "Sankey Chart",
"Sort by": "Ordina per", "Sort by": "Ordina per",
+1
View File
@@ -1516,6 +1516,7 @@
"Radar Chart": "Radar Chart", "Radar Chart": "Radar Chart",
"Area Chart": "エリアチャート", "Area Chart": "エリアチャート",
"Column Chart": "列チャート", "Column Chart": "列チャート",
"Bubble Chart": "Bubble Chart",
"Candlestick Chart": "Candlestick Chart", "Candlestick Chart": "Candlestick Chart",
"Sankey Chart": "Sankey Chart", "Sankey Chart": "Sankey Chart",
"Sort by": "ソート順", "Sort by": "ソート順",
+1
View File
@@ -1516,6 +1516,7 @@
"Radar Chart": "Radar Chart", "Radar Chart": "Radar Chart",
"Area Chart": "영역 차트", "Area Chart": "영역 차트",
"Column Chart": "세로 막대 차트", "Column Chart": "세로 막대 차트",
"Bubble Chart": "Bubble Chart",
"Candlestick Chart": "캠들스틱 차트", "Candlestick Chart": "캠들스틱 차트",
"Sankey Chart": "Sankey Chart", "Sankey Chart": "Sankey Chart",
"Sort by": "정렬 기준", "Sort by": "정렬 기준",
+1
View File
@@ -1516,6 +1516,7 @@
"Radar Chart": "Radar Chart", "Radar Chart": "Radar Chart",
"Area Chart": "Vlakdiagram", "Area Chart": "Vlakdiagram",
"Column Chart": "Kolomdiagram", "Column Chart": "Kolomdiagram",
"Bubble Chart": "Bubble Chart",
"Candlestick Chart": "Candlestickdiagram", "Candlestick Chart": "Candlestickdiagram",
"Sankey Chart": "Sankey Chart", "Sankey Chart": "Sankey Chart",
"Sort by": "Sorteren op", "Sort by": "Sorteren op",
+1
View File
@@ -1516,6 +1516,7 @@
"Radar Chart": "Radar Chart", "Radar Chart": "Radar Chart",
"Area Chart": "Gráfico de Área", "Area Chart": "Gráfico de Área",
"Column Chart": "Gráfico de Colunas", "Column Chart": "Gráfico de Colunas",
"Bubble Chart": "Bubble Chart",
"Candlestick Chart": "Candlestick Chart", "Candlestick Chart": "Candlestick Chart",
"Sankey Chart": "Sankey Chart", "Sankey Chart": "Sankey Chart",
"Sort by": "Ordenar por", "Sort by": "Ordenar por",
+1
View File
@@ -1516,6 +1516,7 @@
"Radar Chart": "Radar Chart", "Radar Chart": "Radar Chart",
"Area Chart": "Диаграмма с областями", "Area Chart": "Диаграмма с областями",
"Column Chart": "Столбчатая диаграмма", "Column Chart": "Столбчатая диаграмма",
"Bubble Chart": "Bubble Chart",
"Candlestick Chart": "Candlestick Chart", "Candlestick Chart": "Candlestick Chart",
"Sankey Chart": "Sankey Chart", "Sankey Chart": "Sankey Chart",
"Sort by": "Сортировать по", "Sort by": "Сортировать по",
+1
View File
@@ -1516,6 +1516,7 @@
"Radar Chart": "Radar Chart", "Radar Chart": "Radar Chart",
"Area Chart": "กราฟพื้นที่", "Area Chart": "กราฟพื้นที่",
"Column Chart": "กราฟคอลัมน์", "Column Chart": "กราฟคอลัมน์",
"Bubble Chart": "Bubble Chart",
"Candlestick Chart": "กราฟแท่งเทียน", "Candlestick Chart": "กราฟแท่งเทียน",
"Sankey Chart": "Sankey Chart", "Sankey Chart": "Sankey Chart",
"Sort by": "จัดเรียงตาม", "Sort by": "จัดเรียงตาม",
+1
View File
@@ -1516,6 +1516,7 @@
"Radar Chart": "Radar Chart", "Radar Chart": "Radar Chart",
"Area Chart": "Діаграма з областями", "Area Chart": "Діаграма з областями",
"Column Chart": "Стовпчикова діаграма", "Column Chart": "Стовпчикова діаграма",
"Bubble Chart": "Bubble Chart",
"Candlestick Chart": "Candlestick Chart", "Candlestick Chart": "Candlestick Chart",
"Sankey Chart": "Sankey Chart", "Sankey Chart": "Sankey Chart",
"Sort by": "Сортувати за", "Sort by": "Сортувати за",
+1
View File
@@ -1516,6 +1516,7 @@
"Radar Chart": "Radar Chart", "Radar Chart": "Radar Chart",
"Area Chart": "Biểu đồ diện tích", "Area Chart": "Biểu đồ diện tích",
"Column Chart": "Biểu đồ cột", "Column Chart": "Biểu đồ cột",
"Bubble Chart": "Bubble Chart",
"Candlestick Chart": "Candlestick Chart", "Candlestick Chart": "Candlestick Chart",
"Sankey Chart": "Sankey Chart", "Sankey Chart": "Sankey Chart",
"Sort by": "Sắp xếp theo", "Sort by": "Sắp xếp theo",
+1
View File
@@ -1516,6 +1516,7 @@
"Radar Chart": "雷达图", "Radar Chart": "雷达图",
"Area Chart": "面积图", "Area Chart": "面积图",
"Column Chart": "柱状图", "Column Chart": "柱状图",
"Bubble Chart": "气泡图",
"Candlestick Chart": "K线图", "Candlestick Chart": "K线图",
"Sankey Chart": "桑基图", "Sankey Chart": "桑基图",
"Sort by": "排序方式", "Sort by": "排序方式",
+1
View File
@@ -1516,6 +1516,7 @@
"Radar Chart": "雷達圖", "Radar Chart": "雷達圖",
"Area Chart": "面積圖", "Area Chart": "面積圖",
"Column Chart": "柱狀圖", "Column Chart": "柱狀圖",
"Bubble Chart": "氣泡圖",
"Candlestick Chart": "K線圖", "Candlestick Chart": "K線圖",
"Sankey Chart": "桑基圖", "Sankey Chart": "桑基圖",
"Sort by": "排序方式", "Sort by": "排序方式",
+2 -4
View File
@@ -812,9 +812,7 @@ export const useStatisticsStore = defineStore('statistics', () => {
transactionStatisticsFilter.value.categoricalChartType = settingsStore.appSettings.statistics.defaultCategoricalChartType; transactionStatisticsFilter.value.categoricalChartType = settingsStore.appSettings.statistics.defaultCategoricalChartType;
} }
if (transactionStatisticsFilter.value.categoricalChartType !== CategoricalChartType.Pie.type && if (!CategoricalChartType.isValidType(transactionStatisticsFilter.value.categoricalChartType)) {
transactionStatisticsFilter.value.categoricalChartType !== CategoricalChartType.Bar.type &&
transactionStatisticsFilter.value.categoricalChartType !== CategoricalChartType.Radar.type) {
transactionStatisticsFilter.value.categoricalChartType = CategoricalChartType.Default.type; transactionStatisticsFilter.value.categoricalChartType = CategoricalChartType.Default.type;
} }
@@ -859,7 +857,7 @@ export const useStatisticsStore = defineStore('statistics', () => {
transactionStatisticsFilter.value.trendChartType = settingsStore.appSettings.statistics.defaultTrendChartType; transactionStatisticsFilter.value.trendChartType = settingsStore.appSettings.statistics.defaultTrendChartType;
} }
if (transactionStatisticsFilter.value.trendChartType !== TrendChartType.Area.type && transactionStatisticsFilter.value.trendChartType !== TrendChartType.Column.type) { if (!TrendChartType.isValidType(transactionStatisticsFilter.value.trendChartType)) {
transactionStatisticsFilter.value.trendChartType = TrendChartType.Default.type; transactionStatisticsFilter.value.trendChartType = TrendChartType.Default.type;
} }
@@ -9,7 +9,13 @@ import { type TransactionStatisticsFilter, useStatisticsStore } from '@/stores/s
import type { TypeAndDisplayName } from '@/core/base.ts'; import type { TypeAndDisplayName } from '@/core/base.ts';
import { type LocalizedDateRange, type WeekDayValue, DateRangeScene, DateRange } from '@/core/datetime.ts'; import { type LocalizedDateRange, type WeekDayValue, DateRangeScene, DateRange } from '@/core/datetime.ts';
import type { ColorStyleValue } from '@/core/color.ts'; import type { ColorStyleValue } from '@/core/color.ts';
import { StatisticsAnalysisType, ChartDataType, ChartSortingType, ChartDateAggregationType } from '@/core/statistics.ts'; import {
StatisticsAnalysisType,
ChartDataType,
ChartSortingType,
ChartDateAggregationType,
TrendChartType
} from '@/core/statistics.ts';
import { DISPLAY_HIDDEN_AMOUNT } from '@/consts/numeral.ts'; import { DISPLAY_HIDDEN_AMOUNT } from '@/consts/numeral.ts';
@@ -229,7 +235,8 @@ export function useStatisticsTransactionPageBase() {
}); });
const showStackedInTrendsChart = computed<boolean>(() => { const showStackedInTrendsChart = computed<boolean>(() => {
return query.value.chartDataType !== ChartDataType.OutflowsByAccount.type && return (query.value.trendChartType === TrendChartType.Area.type || query.value.trendChartType === TrendChartType.Column.type) &&
query.value.chartDataType !== ChartDataType.OutflowsByAccount.type &&
query.value.chartDataType !== ChartDataType.InflowsByAccount.type; query.value.chartDataType !== ChartDataType.InflowsByAccount.type;
}); });