@electrolux-oss/plugin-infrawallet 0.1.11 → 0.1.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api/InfraWalletApiClient.esm.js +4 -2
- package/dist/api/InfraWalletApiClient.esm.js.map +1 -1
- package/dist/api/functions.esm.js +15 -3
- package/dist/api/functions.esm.js.map +1 -1
- package/dist/components/ColumnsChartComponent/ColumnsChartComponent.esm.js +142 -173
- package/dist/components/ColumnsChartComponent/ColumnsChartComponent.esm.js.map +1 -1
- package/dist/components/CostReportsTableComponent/CostReportsTableComponent.esm.js +147 -91
- package/dist/components/CostReportsTableComponent/CostReportsTableComponent.esm.js.map +1 -1
- package/dist/components/EntityInfraWalletCard/EntityInfraWalletCard.esm.js +254 -0
- package/dist/components/EntityInfraWalletCard/EntityInfraWalletCard.esm.js.map +1 -0
- package/dist/components/EntityInfraWalletCard/index.esm.js +2 -0
- package/dist/components/EntityInfraWalletCard/index.esm.js.map +1 -0
- package/dist/components/ErrorsAlertComponent/ErrorsAlertComponent.esm.js +4 -4
- package/dist/components/ErrorsAlertComponent/ErrorsAlertComponent.esm.js.map +1 -1
- package/dist/components/FiltersComponent/FiltersComponent.esm.js +27 -27
- package/dist/components/FiltersComponent/FiltersComponent.esm.js.map +1 -1
- package/dist/components/InfraWalletAppData.esm.js +9 -0
- package/dist/components/InfraWalletAppData.esm.js.map +1 -0
- package/dist/components/MetricConfigurationComponent/MetricConfigurationComponent.esm.js +22 -10
- package/dist/components/MetricConfigurationComponent/MetricConfigurationComponent.esm.js.map +1 -1
- package/dist/components/PieChartComponent/PieChartComponent.esm.js +63 -59
- package/dist/components/PieChartComponent/PieChartComponent.esm.js.map +1 -1
- package/dist/components/ProviderIcons/ProviderIcons.esm.js +8 -8
- package/dist/components/ProviderIcons/ProviderIcons.esm.js.map +1 -1
- package/dist/components/ReportsComponent/ReportsComponent.esm.js +24 -20
- package/dist/components/ReportsComponent/ReportsComponent.esm.js.map +1 -1
- package/dist/components/SettingsComponent/SettingsComponent.esm.js +4 -4
- package/dist/components/SettingsComponent/SettingsComponent.esm.js.map +1 -1
- package/dist/components/index.esm.js +36 -0
- package/dist/components/index.esm.js.map +1 -0
- package/dist/index.d.ts +5 -1
- package/dist/index.esm.js +2 -1
- package/dist/index.esm.js.map +1 -1
- package/dist/plugin.esm.js +10 -2
- package/dist/plugin.esm.js.map +1 -1
- package/package.json +9 -11
|
@@ -38,7 +38,7 @@ class InfraWalletApiClient {
|
|
|
38
38
|
}
|
|
39
39
|
async getCostReports(filters, tags, groups, granularity, startTime, endTime) {
|
|
40
40
|
const tagsString = tagsToString(tags);
|
|
41
|
-
const url = `api/infrawallet/reports
|
|
41
|
+
const url = `api/infrawallet/reports?granularity=${granularity}&groups=${groups}&filters=${filters}&tags=${tagsString}&startTime=${startTime.getTime()}&endTime=${endTime.getTime()}`;
|
|
42
42
|
return await this.request(url);
|
|
43
43
|
}
|
|
44
44
|
async getTagKeys(provider, startTime, endTime) {
|
|
@@ -46,7 +46,9 @@ class InfraWalletApiClient {
|
|
|
46
46
|
return await this.request(url);
|
|
47
47
|
}
|
|
48
48
|
async getTagValues(tag, startTime, endTime) {
|
|
49
|
-
const
|
|
49
|
+
const provider = tag.provider;
|
|
50
|
+
const tagKey = tag.key;
|
|
51
|
+
const url = `api/infrawallet/tag-values?provider=${provider}&tag=${tagKey}&startTime=${startTime.getTime()}&endTime=${endTime.getTime()}`;
|
|
50
52
|
return await this.request(url);
|
|
51
53
|
}
|
|
52
54
|
async getWalletByName(walletName) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"InfraWalletApiClient.esm.js","sources":["../../src/api/InfraWalletApiClient.ts"],"sourcesContent":["import { ConfigApi, IdentityApi } from '@backstage/core-plugin-api';\nimport fetch from 'node-fetch';\nimport { InfraWalletApi } from './InfraWalletApi';\nimport {\n CostReportsResponse,\n GetWalletResponse,\n MetricConfigsResponse,\n MetricSetting,\n MetricsResponse,\n MetricsSettingResponse,\n Tag,\n TagResponse,\n} from './types';\nimport { tagsToString } from './functions';\n\n/** @public */\nexport class InfraWalletApiClient implements InfraWalletApi {\n private readonly identityApi: IdentityApi;\n private readonly backendUrl: string;\n\n constructor(options: { identityApi: IdentityApi; configApi: ConfigApi }) {\n this.identityApi = options.identityApi;\n this.backendUrl = options.configApi.getString('backend.baseUrl');\n }\n\n async request(path: string, method?: string, payload?: Record<string, string | undefined>) {\n const url = `${this.backendUrl}/${path}`;\n const { token: idToken } = await this.identityApi.getCredentials();\n const headers: Record<string, string> = idToken ? { Authorization: `Bearer ${idToken}` } : {};\n\n if (method !== undefined && method !== 'GET') {\n headers['Content-Type'] = 'application/json';\n }\n\n const request: any = {\n headers: headers,\n method: method ?? 'GET',\n };\n\n if (payload) {\n request.body = JSON.stringify(payload);\n }\n\n const response = await fetch(url, request);\n\n if (!response.ok) {\n const res = await response.text();\n const message = `Request failed with ${response.status} ${response.statusText}, ${res}`;\n throw new Error(message);\n }\n\n return await response.json();\n }\n\n async getCostReports(\n filters: string,\n tags: Tag[],\n groups: string,\n granularity: string,\n startTime: Date,\n endTime: Date,\n ): Promise<CostReportsResponse> {\n const tagsString = tagsToString(tags);\n const url = `api/infrawallet/reports
|
|
1
|
+
{"version":3,"file":"InfraWalletApiClient.esm.js","sources":["../../src/api/InfraWalletApiClient.ts"],"sourcesContent":["import { ConfigApi, IdentityApi } from '@backstage/core-plugin-api';\nimport fetch from 'node-fetch';\nimport { InfraWalletApi } from './InfraWalletApi';\nimport {\n CostReportsResponse,\n GetWalletResponse,\n MetricConfigsResponse,\n MetricSetting,\n MetricsResponse,\n MetricsSettingResponse,\n Tag,\n TagResponse,\n} from './types';\nimport { tagsToString } from './functions';\n\n/** @public */\nexport class InfraWalletApiClient implements InfraWalletApi {\n private readonly identityApi: IdentityApi;\n private readonly backendUrl: string;\n\n constructor(options: { identityApi: IdentityApi; configApi: ConfigApi }) {\n this.identityApi = options.identityApi;\n this.backendUrl = options.configApi.getString('backend.baseUrl');\n }\n\n async request(path: string, method?: string, payload?: Record<string, string | undefined>) {\n const url = `${this.backendUrl}/${path}`;\n const { token: idToken } = await this.identityApi.getCredentials();\n const headers: Record<string, string> = idToken ? { Authorization: `Bearer ${idToken}` } : {};\n\n if (method !== undefined && method !== 'GET') {\n headers['Content-Type'] = 'application/json';\n }\n\n const request: any = {\n headers: headers,\n method: method ?? 'GET',\n };\n\n if (payload) {\n request.body = JSON.stringify(payload);\n }\n\n const response = await fetch(url, request);\n\n if (!response.ok) {\n const res = await response.text();\n const message = `Request failed with ${response.status} ${response.statusText}, ${res}`;\n throw new Error(message);\n }\n\n return await response.json();\n }\n\n async getCostReports(\n filters: string,\n tags: Tag[],\n groups: string,\n granularity: string,\n startTime: Date,\n endTime: Date,\n ): Promise<CostReportsResponse> {\n const tagsString = tagsToString(tags);\n const url = `api/infrawallet/reports?granularity=${granularity}&groups=${groups}&filters=${filters}&tags=${tagsString}&startTime=${startTime.getTime()}&endTime=${endTime.getTime()}`;\n\n return await this.request(url);\n }\n async getTagKeys(provider: string, startTime: Date, endTime: Date): Promise<TagResponse> {\n const url = `api/infrawallet/tag-keys?provider=${provider}&startTime=${startTime.getTime()}&endTime=${endTime.getTime()}`;\n return await this.request(url);\n }\n\n async getTagValues(tag: Tag, startTime: Date, endTime: Date): Promise<TagResponse> {\n const provider = tag.provider;\n const tagKey = tag.key;\n const url = `api/infrawallet/tag-values?provider=${provider}&tag=${tagKey}&startTime=${startTime.getTime()}&endTime=${endTime.getTime()}`;\n return await this.request(url);\n }\n\n async getWalletByName(walletName: string): Promise<GetWalletResponse> {\n const url = `api/infrawallet/${walletName}`;\n return await this.request(url);\n }\n\n async getMetrics(walletName: string, granularity: string, startTime: Date, endTime: Date): Promise<MetricsResponse> {\n const url = `api/infrawallet/${walletName}/metrics?&granularity=${granularity}&startTime=${startTime.getTime()}&endTime=${endTime.getTime()}`;\n return await this.request(url);\n }\n\n async getMetricConfigs(): Promise<MetricConfigsResponse> {\n const url = 'api/infrawallet/metric/metric_configs';\n return await this.request(url);\n }\n\n async getWalletMetricsSetting(walletName: string): Promise<MetricsSettingResponse> {\n const url = `api/infrawallet/${walletName}/metrics_setting`;\n return await this.request(url);\n }\n async updateWalletMetricSetting(\n walletName: string,\n metricSetting: MetricSetting,\n ): Promise<{ updated: boolean; status: number }> {\n const url = `api/infrawallet/${walletName}/metrics_setting`;\n return await this.request(url, 'PUT', metricSetting);\n }\n\n async deleteWalletMetricSetting(\n walletName: string,\n metricSetting: MetricSetting,\n ): Promise<{ deleted: boolean; status: number }> {\n const url = `api/infrawallet/${walletName}/metrics_setting`;\n return await this.request(url, 'DELETE', metricSetting);\n }\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { parse, subMonths, format } from 'date-fns';
|
|
1
|
+
import { parse, subMonths, format, subDays } from 'date-fns';
|
|
2
2
|
import { reduce } from 'lodash';
|
|
3
3
|
import moment from 'moment';
|
|
4
4
|
|
|
@@ -16,7 +16,7 @@ const mergeCostReports = (reports, threshold) => {
|
|
|
16
16
|
const mergedReports = reduce(
|
|
17
17
|
reports,
|
|
18
18
|
(accumulator, report) => {
|
|
19
|
-
let keyName = "
|
|
19
|
+
let keyName = "Others";
|
|
20
20
|
if (idsToBeKept.includes(report.id)) {
|
|
21
21
|
keyName = report.id;
|
|
22
22
|
}
|
|
@@ -149,6 +149,11 @@ const getPreviousMonth = (month) => {
|
|
|
149
149
|
const previousMonth = subMonths(date, 1);
|
|
150
150
|
return format(previousMonth, "yyyy-MM");
|
|
151
151
|
};
|
|
152
|
+
const getPreviousDay = (day) => {
|
|
153
|
+
const date = parse(day, "yyyy-MM-dd", /* @__PURE__ */ new Date());
|
|
154
|
+
const previousDay = subDays(date, 1);
|
|
155
|
+
return format(previousDay, "yyyy-MM-dd");
|
|
156
|
+
};
|
|
152
157
|
const getPeriodStrings = (granularity, startTime, endTime) => {
|
|
153
158
|
const result = [];
|
|
154
159
|
const current = moment(startTime);
|
|
@@ -163,6 +168,13 @@ const getPeriodStrings = (granularity, startTime, endTime) => {
|
|
|
163
168
|
}
|
|
164
169
|
return result;
|
|
165
170
|
};
|
|
171
|
+
const formatCurrency = (number, currency) => {
|
|
172
|
+
return new Intl.NumberFormat("en-US", {
|
|
173
|
+
style: "currency",
|
|
174
|
+
currency: "USD",
|
|
175
|
+
notation: "compact"
|
|
176
|
+
}).format(number);
|
|
177
|
+
};
|
|
166
178
|
|
|
167
|
-
export { aggregateCostReports, extractAccountInfo, extractProvider, filterCostReports, getAllReportTags, getPeriodStrings, getPreviousMonth, getReportKeyAndValues, mergeCostReports, tagExists, tagsToString };
|
|
179
|
+
export { aggregateCostReports, extractAccountInfo, extractProvider, filterCostReports, formatCurrency, getAllReportTags, getPeriodStrings, getPreviousDay, getPreviousMonth, getReportKeyAndValues, mergeCostReports, tagExists, tagsToString };
|
|
168
180
|
//# sourceMappingURL=functions.esm.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"functions.esm.js","sources":["../../src/api/functions.ts"],"sourcesContent":["import { format, parse, subMonths } from 'date-fns';\nimport { reduce } from 'lodash';\nimport moment from 'moment';\nimport { Report, Filters, Tag } from './types';\n\nexport const mergeCostReports = (reports: Report[], threshold: number): Report[] => {\n const totalCosts: { id: string; total: number }[] = [];\n reports.forEach(report => {\n let total = 0;\n Object.values(report.reports).forEach(v => {\n total += v as number;\n });\n totalCosts.push({ id: report.id, total: total });\n });\n const sortedTotalCosts = totalCosts.sort((a, b) => b.total - a.total);\n const idsToBeKept = sortedTotalCosts.slice(0, threshold).map(v => v.id);\n\n const mergedReports = reduce(\n reports,\n (accumulator: { [key: string]: Report }, report) => {\n let keyName = 'others';\n if (idsToBeKept.includes(report.id)) {\n keyName = report.id;\n }\n if (!accumulator[keyName]) {\n accumulator[keyName] = {\n id: keyName,\n reports: {},\n };\n }\n\n Object.keys(report.reports).forEach(key => {\n if (accumulator[keyName].reports[key]) {\n accumulator[keyName].reports[key] += report.reports[key];\n } else {\n accumulator[keyName].reports[key] = report.reports[key];\n }\n });\n return accumulator;\n },\n {},\n );\n\n return Object.values(mergedReports);\n};\n\nexport const filterCostReports = (reports: Report[], filters: Filters): Report[] => {\n const filteredReports = reports.filter(report => {\n let match = true;\n Object.keys(filters).forEach(key => {\n if (filters[key].length > 0 && !filters[key].includes(report[key] as string)) {\n match = false;\n }\n });\n return match;\n });\n\n return filteredReports;\n};\n\nexport const aggregateCostReports = (reports: Report[], aggregatedBy?: string): Report[] => {\n const aggregatedReports: { [key: string]: Report } = reduce(\n reports,\n (accumulator, report) => {\n let keyName: string = 'no value';\n if (aggregatedBy && aggregatedBy in report) {\n keyName = report[aggregatedBy] as string;\n } else if (aggregatedBy === 'none') {\n keyName = 'Total';\n }\n\n if (!accumulator[keyName]) {\n accumulator[keyName] = {\n id: keyName,\n provider: report.provider,\n reports: {},\n } as {\n id: string;\n reports: { [key: string]: number };\n [key: string]: any;\n };\n\n if (aggregatedBy !== undefined) {\n accumulator[keyName][aggregatedBy] = keyName;\n }\n }\n\n Object.keys(report.reports).forEach(key => {\n if (accumulator[keyName].reports[key]) {\n accumulator[keyName].reports[key] += report.reports[key];\n } else {\n accumulator[keyName].reports[key] = report.reports[key];\n }\n });\n return accumulator;\n },\n {} as { [key: string]: Report },\n );\n return Object.values(aggregatedReports);\n};\n\nexport const getReportKeyAndValues = (reports: Report[]): { [key: string]: string[] } => {\n const excludedKeys = ['id', 'reports'];\n const keyValueSets: { [key: string]: Set<string> } = {};\n reports.forEach(report => {\n Object.keys(report).forEach(key => {\n if (!excludedKeys.includes(key)) {\n if (keyValueSets[key] === undefined) {\n keyValueSets[key] = new Set<string>();\n }\n\n keyValueSets[key].add(report[key] as string);\n }\n });\n });\n\n const keyValues: { [key: string]: string[] } = {};\n Object.keys(keyValueSets).forEach((key: string) => {\n keyValues[key] = Array.from(keyValueSets[key]);\n });\n return keyValues;\n};\n\nexport const extractProvider = (input: string): string | undefined => {\n let provider = undefined;\n if (input && input.indexOf('/') !== -1) {\n provider = input.split('/')[0];\n }\n\n return provider;\n};\n\nexport const extractAccountInfo = (input: string): { accountName: string; accountId?: string } => {\n // try to match format: accountName (accountId), e.g. aws-dev (123456789012)\n const regex = /^(.*?)\\s*\\(([^)]+)\\)$/;\n const match = input.match(regex);\n\n if (match) {\n const accountName = match[1];\n const accountId = match[2];\n return { accountName: accountName, accountId: accountId };\n }\n\n return { accountName: input };\n};\n\n// check if targetTag exists in tags\nexport function tagExists(tags: Tag[], targetTag: Tag): boolean {\n return tags.some(\n tag => tag.provider === targetTag.provider && tag.key === targetTag.key && tag.value === targetTag.value,\n );\n}\n\n// convert Tag array to (provider1:key1=value1 OR provider2:key2=value2) format\nexport const tagsToString = (tags: Tag[]): string => {\n if (tags.length === 0) {\n return '()';\n }\n\n const keyValuePairs = tags.map(tag => `${tag.provider}:${tag.key}=${tag.value}`);\n return `(${keyValuePairs.join(' OR ')})`;\n};\n\nexport const getAllReportTags = (reports: Report[]): string[] => {\n const tags = new Set<string>();\n const reservedKeys = ['id', 'account', 'service', 'category', 'provider', 'reports'];\n reports.forEach(report => {\n Object.keys(report).forEach(key => {\n if (reservedKeys.indexOf(key) === -1) {\n tags.add(key);\n }\n });\n });\n return Array.from(tags);\n};\n\nexport const getPreviousMonth = (month: string): string => {\n const date = parse(month, 'yyyy-MM', new Date());\n const previousMonth = subMonths(date, 1);\n return format(previousMonth, 'yyyy-MM');\n};\n\nexport const getPeriodStrings = (granularity: string, startTime: Date, endTime: Date): string[] => {\n const result: string[] = [];\n const current = moment(startTime);\n\n while (current.isSameOrBefore(endTime) && current.isSameOrBefore(moment())) {\n if (granularity === 'monthly') {\n result.push(current.format('YYYY-MM'));\n current.add(1, 'months');\n } else {\n result.push(current.format('YYYY-MM-DD'));\n current.add(1, 'days');\n }\n }\n\n return result;\n};\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"functions.esm.js","sources":["../../src/api/functions.ts"],"sourcesContent":["import { format, parse, subDays, subMonths } from 'date-fns';\nimport { reduce } from 'lodash';\nimport moment from 'moment';\nimport { Filters, Report, Tag } from './types';\n\nexport const mergeCostReports = (reports: Report[], threshold: number): Report[] => {\n const totalCosts: { id: string; total: number }[] = [];\n reports.forEach(report => {\n let total = 0;\n Object.values(report.reports).forEach(v => {\n total += v as number;\n });\n totalCosts.push({ id: report.id, total: total });\n });\n const sortedTotalCosts = totalCosts.sort((a, b) => b.total - a.total);\n const idsToBeKept = sortedTotalCosts.slice(0, threshold).map(v => v.id);\n\n const mergedReports = reduce(\n reports,\n (accumulator: { [key: string]: Report }, report) => {\n let keyName = 'Others';\n if (idsToBeKept.includes(report.id)) {\n keyName = report.id;\n }\n if (!accumulator[keyName]) {\n accumulator[keyName] = {\n id: keyName,\n reports: {},\n };\n }\n\n Object.keys(report.reports).forEach(key => {\n if (accumulator[keyName].reports[key]) {\n accumulator[keyName].reports[key] += report.reports[key];\n } else {\n accumulator[keyName].reports[key] = report.reports[key];\n }\n });\n return accumulator;\n },\n {},\n );\n\n return Object.values(mergedReports);\n};\n\nexport const filterCostReports = (reports: Report[], filters: Filters): Report[] => {\n const filteredReports = reports.filter(report => {\n let match = true;\n Object.keys(filters).forEach(key => {\n if (filters[key].length > 0 && !filters[key].includes(report[key] as string)) {\n match = false;\n }\n });\n return match;\n });\n\n return filteredReports;\n};\n\nexport const aggregateCostReports = (reports: Report[], aggregatedBy?: string): Report[] => {\n const aggregatedReports: { [key: string]: Report } = reduce(\n reports,\n (accumulator, report) => {\n let keyName: string = 'no value';\n if (aggregatedBy && aggregatedBy in report) {\n keyName = report[aggregatedBy] as string;\n } else if (aggregatedBy === 'none') {\n keyName = 'Total';\n }\n\n if (!accumulator[keyName]) {\n accumulator[keyName] = {\n id: keyName,\n provider: report.provider,\n reports: {},\n } as {\n id: string;\n reports: { [key: string]: number };\n [key: string]: any;\n };\n\n if (aggregatedBy !== undefined) {\n accumulator[keyName][aggregatedBy] = keyName;\n }\n }\n\n Object.keys(report.reports).forEach(key => {\n if (accumulator[keyName].reports[key]) {\n accumulator[keyName].reports[key] += report.reports[key];\n } else {\n accumulator[keyName].reports[key] = report.reports[key];\n }\n });\n return accumulator;\n },\n {} as { [key: string]: Report },\n );\n return Object.values(aggregatedReports);\n};\n\nexport const getReportKeyAndValues = (reports: Report[]): { [key: string]: string[] } => {\n const excludedKeys = ['id', 'reports'];\n const keyValueSets: { [key: string]: Set<string> } = {};\n reports.forEach(report => {\n Object.keys(report).forEach(key => {\n if (!excludedKeys.includes(key)) {\n if (keyValueSets[key] === undefined) {\n keyValueSets[key] = new Set<string>();\n }\n\n keyValueSets[key].add(report[key] as string);\n }\n });\n });\n\n const keyValues: { [key: string]: string[] } = {};\n Object.keys(keyValueSets).forEach((key: string) => {\n keyValues[key] = Array.from(keyValueSets[key]);\n });\n return keyValues;\n};\n\nexport const extractProvider = (input: string): string | undefined => {\n let provider = undefined;\n if (input && input.indexOf('/') !== -1) {\n provider = input.split('/')[0];\n }\n\n return provider;\n};\n\nexport const extractAccountInfo = (input: string): { accountName: string; accountId?: string } => {\n // try to match format: accountName (accountId), e.g. aws-dev (123456789012)\n const regex = /^(.*?)\\s*\\(([^)]+)\\)$/;\n const match = input.match(regex);\n\n if (match) {\n const accountName = match[1];\n const accountId = match[2];\n return { accountName: accountName, accountId: accountId };\n }\n\n return { accountName: input };\n};\n\n// check if targetTag exists in tags\nexport function tagExists(tags: Tag[], targetTag: Tag): boolean {\n return tags.some(\n tag => tag.provider === targetTag.provider && tag.key === targetTag.key && tag.value === targetTag.value,\n );\n}\n\n// convert Tag array to (provider1:key1=value1 OR provider2:key2=value2) format\nexport const tagsToString = (tags: Tag[]): string => {\n if (tags.length === 0) {\n return '()';\n }\n\n const keyValuePairs = tags.map(tag => `${tag.provider}:${tag.key}=${tag.value}`);\n return `(${keyValuePairs.join(' OR ')})`;\n};\n\nexport const getAllReportTags = (reports: Report[]): string[] => {\n const tags = new Set<string>();\n const reservedKeys = ['id', 'account', 'service', 'category', 'provider', 'reports'];\n reports.forEach(report => {\n Object.keys(report).forEach(key => {\n if (reservedKeys.indexOf(key) === -1) {\n tags.add(key);\n }\n });\n });\n return Array.from(tags);\n};\n\nexport const getPreviousMonth = (month: string): string => {\n const date = parse(month, 'yyyy-MM', new Date());\n const previousMonth = subMonths(date, 1);\n return format(previousMonth, 'yyyy-MM');\n};\n\nexport const getPreviousDay = (day: string): string => {\n const date = parse(day, 'yyyy-MM-dd', new Date());\n const previousDay = subDays(date, 1);\n return format(previousDay, 'yyyy-MM-dd');\n};\n\nexport const getPeriodStrings = (granularity: string, startTime: Date, endTime: Date): string[] => {\n const result: string[] = [];\n const current = moment(startTime);\n\n while (current.isSameOrBefore(endTime) && current.isSameOrBefore(moment())) {\n if (granularity === 'monthly') {\n result.push(current.format('YYYY-MM'));\n current.add(1, 'months');\n } else {\n result.push(current.format('YYYY-MM-DD'));\n current.add(1, 'days');\n }\n }\n\n return result;\n};\n\nexport const formatCurrency = (number: number, currency?: string): string => {\n return new Intl.NumberFormat('en-US', {\n style: 'currency',\n currency: currency || 'USD',\n notation: 'compact',\n }).format(number);\n};\n"],"names":[],"mappings":"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"}
|
|
@@ -1,196 +1,165 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import
|
|
3
|
-
import
|
|
1
|
+
import { Grid, Switch } from '@material-ui/core';
|
|
2
|
+
import Paper from '@mui/material/Paper';
|
|
3
|
+
import Skeleton from '@mui/material/Skeleton';
|
|
4
|
+
import { ResponsiveChartContainer, ChartsGrid, BarPlot, LinePlot, LineHighlightPlot, MarkPlot, ChartsXAxis, ChartsYAxis, ChartsTooltip, ChartsLegend, DefaultChartsLegend } from '@mui/x-charts';
|
|
4
5
|
import React, { useState, useCallback, useEffect } from 'react';
|
|
5
|
-
import
|
|
6
|
+
import { formatCurrency } from '../../api/functions.esm.js';
|
|
6
7
|
import { colorList } from '../constants.esm.js';
|
|
7
8
|
|
|
8
9
|
const ColumnsChartComponent = ({
|
|
10
|
+
granularity,
|
|
9
11
|
granularitySetter,
|
|
10
12
|
categories,
|
|
11
|
-
|
|
13
|
+
costs,
|
|
12
14
|
metrics,
|
|
13
15
|
height,
|
|
14
|
-
|
|
15
|
-
|
|
16
|
+
highlightedItem,
|
|
17
|
+
highlightedItemSetter
|
|
16
18
|
}) => {
|
|
17
|
-
const
|
|
18
|
-
const
|
|
19
|
-
fixedHeightPaper: {
|
|
20
|
-
padding: "16px",
|
|
21
|
-
display: "flex",
|
|
22
|
-
flexDirection: "column",
|
|
23
|
-
height: height ? height : 300
|
|
24
|
-
},
|
|
25
|
-
thumbnailPaper: {
|
|
26
|
-
display: "flex",
|
|
27
|
-
overflow: "hidden",
|
|
28
|
-
flexDirection: "column",
|
|
29
|
-
height: height ? height - 70 : 80
|
|
30
|
-
}
|
|
31
|
-
});
|
|
32
|
-
const classes = useStyles();
|
|
19
|
+
const [costsSeries, setCostsSeries] = useState(void 0);
|
|
20
|
+
const [metricsSeries, setMetricsSeries] = useState(void 0);
|
|
33
21
|
const [showMetrics, setShowMetrics] = useState(false);
|
|
34
|
-
const [
|
|
35
|
-
const
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
enabled: false
|
|
47
|
-
},
|
|
48
|
-
stacked: true,
|
|
49
|
-
toolbar: {
|
|
50
|
-
show: false
|
|
51
|
-
},
|
|
52
|
-
sparkline: {
|
|
53
|
-
enabled: true
|
|
22
|
+
const [maxCostsYaxis, setMaxCostsYaxis] = useState(void 0);
|
|
23
|
+
const initChartCallback = useCallback(async () => {
|
|
24
|
+
setCostsSeries(void 0);
|
|
25
|
+
setMetricsSeries(void 0);
|
|
26
|
+
if (costs) {
|
|
27
|
+
const sums = [];
|
|
28
|
+
for (const s of costs) {
|
|
29
|
+
for (let i = 0; i < s.data.length; i++) {
|
|
30
|
+
if (sums[i] === void 0) {
|
|
31
|
+
sums[i] = 0;
|
|
32
|
+
}
|
|
33
|
+
sums[i] += s.data[i];
|
|
54
34
|
}
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
35
|
+
}
|
|
36
|
+
setMaxCostsYaxis(Math.max(...sums));
|
|
37
|
+
setCostsSeries(
|
|
38
|
+
costs.map((s) => {
|
|
39
|
+
return {
|
|
40
|
+
id: s.name,
|
|
41
|
+
data: s.data,
|
|
42
|
+
type: "bar",
|
|
43
|
+
label: s.name,
|
|
44
|
+
yAxisId: "costsAxis",
|
|
45
|
+
valueFormatter: (value) => {
|
|
46
|
+
return formatCurrency(value ? value : 0);
|
|
47
|
+
},
|
|
48
|
+
highlightScope: { highlight: "series", fade: "global" },
|
|
49
|
+
stack: "total",
|
|
50
|
+
stackOrder: "descending"
|
|
51
|
+
};
|
|
52
|
+
})
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
if (metrics && showMetrics) {
|
|
56
|
+
setMetricsSeries(
|
|
57
|
+
metrics.map((s) => {
|
|
58
|
+
return {
|
|
59
|
+
data: s.data,
|
|
60
|
+
type: "line",
|
|
61
|
+
label: s.name,
|
|
62
|
+
curve: "natural",
|
|
63
|
+
yAxisId: "metricsAxis",
|
|
64
|
+
highlightScope: { highlight: "series", fade: "global" },
|
|
65
|
+
showMark: granularity === "monthly"
|
|
66
|
+
};
|
|
67
|
+
})
|
|
68
|
+
);
|
|
69
|
+
}
|
|
70
|
+
}, [costs, metrics, showMetrics, granularity]);
|
|
71
|
+
useEffect(() => {
|
|
72
|
+
initChartCallback();
|
|
73
|
+
}, [initChartCallback]);
|
|
74
|
+
return /* @__PURE__ */ React.createElement(
|
|
75
|
+
Paper,
|
|
76
|
+
{
|
|
77
|
+
sx: {
|
|
78
|
+
padding: "16px",
|
|
79
|
+
display: "flex",
|
|
80
|
+
flexDirection: "column",
|
|
81
|
+
height: height ? height : 300
|
|
61
82
|
}
|
|
62
83
|
},
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
},
|
|
70
|
-
stacked: true,
|
|
71
|
-
toolbar: {
|
|
72
|
-
show: false
|
|
84
|
+
/* @__PURE__ */ React.createElement(Grid, { container: true, justifyContent: "flex-end", spacing: 1 }, /* @__PURE__ */ React.createElement(Grid, { item: true }, "Monthly"), /* @__PURE__ */ React.createElement(Grid, { item: true }, /* @__PURE__ */ React.createElement(Switch, { size: "small", onChange: (event) => granularitySetter(event.target.checked ? "daily" : "monthly") })), /* @__PURE__ */ React.createElement(Grid, { item: true }, "Daily"), /* @__PURE__ */ React.createElement(Grid, { item: true }, " | "), /* @__PURE__ */ React.createElement(Grid, { item: true }, /* @__PURE__ */ React.createElement(Switch, { size: "small", checked: showMetrics, onChange: (_) => setShowMetrics((ori) => !ori) })), /* @__PURE__ */ React.createElement(Grid, { item: true }, "Show Metrics")),
|
|
85
|
+
costs && costsSeries ? /* @__PURE__ */ React.createElement(
|
|
86
|
+
ResponsiveChartContainer,
|
|
87
|
+
{
|
|
88
|
+
margin: {
|
|
89
|
+
bottom: 80
|
|
73
90
|
},
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
categories
|
|
80
|
-
},
|
|
81
|
-
stroke: {
|
|
82
|
-
width: strokeWidthArray,
|
|
83
|
-
dashArray: strokeDashArray,
|
|
84
|
-
curve: "smooth"
|
|
85
|
-
},
|
|
86
|
-
yaxis: yaxisArray,
|
|
87
|
-
dataLabels: {
|
|
88
|
-
enabled: false
|
|
89
|
-
},
|
|
90
|
-
tooltip: {
|
|
91
|
-
y: {
|
|
92
|
-
formatter: (value, { seriesIndex }) => {
|
|
93
|
-
if (!value) {
|
|
94
|
-
return "";
|
|
95
|
-
}
|
|
96
|
-
const prefix = seriesIndex <= series.length - 1 ? "$" : "";
|
|
97
|
-
return `${prefix}${humanFormat(value, {
|
|
98
|
-
scale: customScale,
|
|
99
|
-
separator: ""
|
|
100
|
-
})}`;
|
|
91
|
+
series: [...costsSeries, ...metricsSeries ? metricsSeries : []],
|
|
92
|
+
xAxis: [
|
|
93
|
+
{
|
|
94
|
+
data: categories,
|
|
95
|
+
scaleType: "band"
|
|
101
96
|
}
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
97
|
+
],
|
|
98
|
+
yAxis: [
|
|
99
|
+
{
|
|
100
|
+
id: "costsAxis",
|
|
101
|
+
max: maxCostsYaxis,
|
|
102
|
+
valueFormatter: (value) => formatCurrency(value)
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
id: "metricsAxis"
|
|
106
|
+
}
|
|
107
|
+
],
|
|
108
|
+
colors: colorList,
|
|
109
|
+
highlightedItem: highlightedItem ? { seriesId: highlightedItem } : null,
|
|
110
|
+
onHighlightChange: (highlighted) => {
|
|
111
|
+
highlightedItemSetter(highlighted == null ? void 0 : highlighted.seriesId);
|
|
106
112
|
}
|
|
107
113
|
},
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
separator: ""
|
|
128
|
-
})}`;
|
|
129
|
-
};
|
|
130
|
-
const strokeWidth = Array(series.length).fill(0);
|
|
131
|
-
const seriesResult = series.map((s) => s);
|
|
132
|
-
const yaxisResult = [
|
|
133
|
-
{
|
|
134
|
-
seriesName: series.map((s) => s.name),
|
|
135
|
-
decimalsInFloat: 2,
|
|
136
|
-
title: {
|
|
137
|
-
text: "Costs in USD"
|
|
138
|
-
},
|
|
139
|
-
labels: {
|
|
140
|
-
formatter: labelFormatter
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
];
|
|
144
|
-
if (metrics && showMetrics) {
|
|
145
|
-
const metricGroups = {};
|
|
146
|
-
metrics.forEach((metric) => {
|
|
147
|
-
strokeWidth.push(3);
|
|
148
|
-
seriesResult.push(metric);
|
|
149
|
-
if (metric.group) {
|
|
150
|
-
if (!metricGroups[metric.group]) {
|
|
151
|
-
metricGroups[metric.group] = {
|
|
152
|
-
seriesName: [metric.name],
|
|
153
|
-
decimalsInFloat: 2,
|
|
154
|
-
opposite: true,
|
|
155
|
-
forceNiceScale: true,
|
|
156
|
-
title: {
|
|
157
|
-
text: metric.group
|
|
158
|
-
},
|
|
159
|
-
labels: {
|
|
160
|
-
formatter: labelFormatter
|
|
114
|
+
/* @__PURE__ */ React.createElement(ChartsGrid, { horizontal: true }),
|
|
115
|
+
/* @__PURE__ */ React.createElement(BarPlot, null),
|
|
116
|
+
/* @__PURE__ */ React.createElement(LinePlot, null),
|
|
117
|
+
/* @__PURE__ */ React.createElement(LineHighlightPlot, null),
|
|
118
|
+
/* @__PURE__ */ React.createElement(MarkPlot, null),
|
|
119
|
+
/* @__PURE__ */ React.createElement(ChartsXAxis, null),
|
|
120
|
+
/* @__PURE__ */ React.createElement(ChartsYAxis, null),
|
|
121
|
+
/* @__PURE__ */ React.createElement(ChartsTooltip, { trigger: "item" }),
|
|
122
|
+
/* @__PURE__ */ React.createElement(
|
|
123
|
+
ChartsLegend,
|
|
124
|
+
{
|
|
125
|
+
slots: {
|
|
126
|
+
legend: (props) => {
|
|
127
|
+
var _a;
|
|
128
|
+
const seriesToDisplay = [];
|
|
129
|
+
for (const s of props.seriesToDisplay) {
|
|
130
|
+
if (((_a = props.series.bar) == null ? void 0 : _a.seriesOrder) && props.series.bar.seriesOrder.indexOf(s.id) !== -1) {
|
|
131
|
+
seriesToDisplay.push(s);
|
|
132
|
+
}
|
|
161
133
|
}
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
134
|
+
return /* @__PURE__ */ React.createElement(
|
|
135
|
+
DefaultChartsLegend,
|
|
136
|
+
{
|
|
137
|
+
series: props.series,
|
|
138
|
+
seriesToDisplay,
|
|
139
|
+
drawingArea: props.drawingArea,
|
|
140
|
+
direction: "row",
|
|
141
|
+
position: { vertical: "bottom", horizontal: "middle" },
|
|
142
|
+
itemMarkHeight: 10,
|
|
143
|
+
itemMarkWidth: 10,
|
|
144
|
+
labelStyle: {
|
|
145
|
+
fontSize: "0.9em"
|
|
146
|
+
},
|
|
147
|
+
onItemClick: (_, legendItem) => {
|
|
148
|
+
const clickedLegend = legendItem.seriesId;
|
|
149
|
+
if (clickedLegend === highlightedItem) {
|
|
150
|
+
highlightedItemSetter(void 0);
|
|
151
|
+
} else {
|
|
152
|
+
highlightedItemSetter(clickedLegend);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
);
|
|
177
157
|
}
|
|
178
|
-
}
|
|
158
|
+
}
|
|
179
159
|
}
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
});
|
|
184
|
-
}
|
|
185
|
-
setSeriesArray(seriesResult);
|
|
186
|
-
setYaxisArray(yaxisResult);
|
|
187
|
-
setStrokeWidthArray(strokeWidth);
|
|
188
|
-
setStrokeDashArray(Array(seriesResult.length).fill(0));
|
|
189
|
-
}, [metrics, series, showMetrics]);
|
|
190
|
-
useEffect(() => {
|
|
191
|
-
initChartCallback();
|
|
192
|
-
}, [initChartCallback]);
|
|
193
|
-
return /* @__PURE__ */ React.createElement(Paper, { className: thumbnail ? classes.thumbnailPaper : classes.fixedHeightPaper }, /* @__PURE__ */ React.createElement(Grid, { container: true, justifyContent: "flex-end", spacing: 1 }, /* @__PURE__ */ React.createElement(Grid, { item: true }, "Monthly"), /* @__PURE__ */ React.createElement(Grid, { item: true }, /* @__PURE__ */ React.createElement(Switch, { size: "small", onChange: (event) => granularitySetter(event.target.checked ? "daily" : "monthly") })), /* @__PURE__ */ React.createElement(Grid, { item: true }, "Daily"), /* @__PURE__ */ React.createElement(Grid, { item: true }, " | "), /* @__PURE__ */ React.createElement(Grid, { item: true }, /* @__PURE__ */ React.createElement(Switch, { size: "small", checked: showMetrics, onChange: (_) => setShowMetrics((ori) => !ori) })), /* @__PURE__ */ React.createElement(Grid, { item: true }, "Show Metrics")), seriesArray && /* @__PURE__ */ React.createElement(Chart, { options: state.options, series: state.series, type: "line", height: height ? height - 70 : 230 }));
|
|
160
|
+
)
|
|
161
|
+
) : /* @__PURE__ */ React.createElement("div", { style: { width: "60%", margin: "auto" } }, /* @__PURE__ */ React.createElement(Skeleton, null), /* @__PURE__ */ React.createElement(Skeleton, null), /* @__PURE__ */ React.createElement(Skeleton, null))
|
|
162
|
+
);
|
|
194
163
|
};
|
|
195
164
|
|
|
196
165
|
export { ColumnsChartComponent };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ColumnsChartComponent.esm.js","sources":["../../../src/components/ColumnsChartComponent/ColumnsChartComponent.tsx"],"sourcesContent":["import { Grid, Paper, Switch } from '@material-ui/core';\nimport { makeStyles, useTheme } from '@material-ui/core/styles';\nimport humanFormat from 'human-format';\nimport React, { FC, useCallback, useEffect, useState } from 'react';\nimport Chart from 'react-apexcharts';\nimport { colorList } from '../constants';\nimport { ColumnsChartComponentProps } from '../types';\n\ntype CurveType =\n | 'smooth'\n | 'straight'\n | 'stepline'\n | 'linestep'\n | 'monotoneCubic'\n | ('smooth' | 'straight' | 'stepline' | 'linestep' | 'monotoneCubic')[]\n | undefined;\n\nexport const ColumnsChartComponent: FC<ColumnsChartComponentProps> = ({\n granularitySetter,\n categories,\n series,\n metrics,\n height,\n thumbnail,\n dataPointSelectionHandler,\n}) => {\n const defaultTheme = useTheme();\n const useStyles = makeStyles({\n fixedHeightPaper: {\n padding: '16px',\n display: 'flex',\n flexDirection: 'column',\n height: height ? height : 300,\n },\n thumbnailPaper: {\n display: 'flex',\n overflow: 'hidden',\n flexDirection: 'column',\n height: height ? height - 70 : 80,\n },\n });\n const classes = useStyles();\n const [showMetrics, setShowMetrics] = useState<boolean>(false);\n const [seriesArray, setSeriesArray] = useState<any[]>([]);\n const [yaxisArray, setYaxisArray] = useState<any[]>([]);\n const [strokeWidthArray, setStrokeWidthArray] = useState<number[]>([]);\n const [strokeDashArray, setStrokeDashArray] = useState<number[]>([]);\n const customScale = humanFormat.Scale.create(['', 'K', 'M', 'B'], 1000);\n\n const state = thumbnail\n ? {\n options: {\n chart: {\n animations: {\n enabled: false,\n },\n zoom: {\n enabled: false,\n },\n stacked: true,\n toolbar: {\n show: false,\n },\n sparkline: {\n enabled: true,\n },\n },\n xaxis: {\n categories: categories,\n },\n theme: {\n mode: defaultTheme.palette.type,\n },\n },\n series: series,\n }\n : {\n options: {\n chart: {\n animations: {\n enabled: false,\n },\n stacked: true,\n toolbar: {\n show: false,\n },\n events: {\n dataPointSelection: dataPointSelectionHandler,\n },\n },\n xaxis: {\n categories: categories,\n },\n stroke: {\n width: strokeWidthArray,\n dashArray: strokeDashArray,\n curve: 'smooth' as CurveType,\n },\n yaxis: yaxisArray,\n dataLabels: {\n enabled: false,\n },\n tooltip: {\n y: {\n formatter: (value: number, { seriesIndex }: { seriesIndex: number }) => {\n if (!value) {\n return '';\n }\n const prefix = seriesIndex <= series.length - 1 ? '$' : '';\n return `${prefix}${humanFormat(value, {\n scale: customScale,\n separator: '',\n })}`;\n },\n },\n fixed: {\n enabled: true,\n position: 'topRight',\n },\n },\n legend: {\n showForSingleSeries: true,\n },\n theme: {\n mode: defaultTheme.palette.type,\n },\n // there are only 5 colors by default, here we extend it to 50 different colors\n colors: colorList,\n },\n series: seriesArray,\n };\n\n const initChartCallback = useCallback(async () => {\n const labelFormatter = (value: number): string => {\n const scale = humanFormat.Scale.create(['', 'K', 'M', 'B'], 1000);\n if (typeof value !== 'number' || isNaN(value)) {\n return '';\n }\n return `$${humanFormat(value, {\n scale: scale,\n separator: '',\n })}`;\n };\n\n const strokeWidth = Array<number>(series.length).fill(0);\n const seriesResult = series.map(s => s);\n const yaxisResult: any[] = [\n {\n seriesName: series.map(s => s.name),\n decimalsInFloat: 2,\n title: {\n text: 'Costs in USD',\n },\n labels: {\n formatter: labelFormatter,\n },\n },\n ];\n\n if (metrics && showMetrics) {\n const metricGroups: any = {};\n metrics.forEach(metric => {\n strokeWidth.push(3);\n seriesResult.push(metric);\n\n if (metric.group) {\n if (!metricGroups[metric.group]) {\n metricGroups[metric.group] = {\n seriesName: [metric.name],\n decimalsInFloat: 2,\n opposite: true,\n forceNiceScale: true,\n title: {\n text: metric.group,\n },\n labels: {\n formatter: labelFormatter,\n },\n };\n } else {\n // yaxis already exists, add the series to the existing one\n metricGroups[metric.group].seriesName.push(metric.name);\n }\n } else {\n // the metric does not have a group, create a separate yaxis for it\n yaxisResult.push({\n seriesName: [metric.name],\n decimalsInFloat: 2,\n opposite: true,\n forceNiceScale: true,\n title: {\n text: metric.name,\n },\n labels: {\n formatter: labelFormatter,\n },\n });\n }\n });\n Object.values(metricGroups).forEach((group: any) => {\n yaxisResult.push(group);\n });\n }\n\n setSeriesArray(seriesResult);\n setYaxisArray(yaxisResult);\n setStrokeWidthArray(strokeWidth);\n setStrokeDashArray(Array<number>(seriesResult.length).fill(0));\n }, [metrics, series, showMetrics]);\n\n useEffect(() => {\n initChartCallback();\n }, [initChartCallback]);\n\n return (\n <Paper className={thumbnail ? classes.thumbnailPaper : classes.fixedHeightPaper}>\n <Grid container justifyContent=\"flex-end\" spacing={1}>\n <Grid item>Monthly</Grid>\n <Grid item>\n <Switch size=\"small\" onChange={event => granularitySetter(event.target.checked ? 'daily' : 'monthly')} />\n </Grid>\n <Grid item>Daily</Grid>\n <Grid item> | </Grid>\n <Grid item>\n <Switch size=\"small\" checked={showMetrics} onChange={_ => setShowMetrics((ori: boolean) => !ori)} />\n </Grid>\n <Grid item>Show Metrics</Grid>\n </Grid>\n {seriesArray && (\n <Chart options={state.options} series={state.series} type=\"line\" height={height ? height - 70 : 230} />\n )}\n </Paper>\n );\n};\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ColumnsChartComponent.esm.js","sources":["../../../src/components/ColumnsChartComponent/ColumnsChartComponent.tsx"],"sourcesContent":["import { Grid, Switch } from '@material-ui/core';\nimport Paper from '@mui/material/Paper';\nimport Skeleton from '@mui/material/Skeleton';\nimport {\n BarPlot,\n ChartsGrid,\n ChartsLegend,\n ChartsTooltip,\n ChartsXAxis,\n ChartsYAxis,\n DefaultChartsLegend,\n LineHighlightPlot,\n LinePlot,\n MarkPlot,\n ResponsiveChartContainer,\n} from '@mui/x-charts';\nimport React, { FC, useCallback, useEffect, useState } from 'react';\nimport { formatCurrency } from '../../api/functions';\nimport { colorList } from '../constants';\nimport { ColumnsChartComponentProps } from '../types';\n\nexport const ColumnsChartComponent: FC<ColumnsChartComponentProps> = ({\n granularity,\n granularitySetter,\n categories,\n costs,\n metrics,\n height,\n highlightedItem,\n highlightedItemSetter,\n}) => {\n const [costsSeries, setCostsSeries] = useState<any[] | undefined>(undefined);\n const [metricsSeries, setMetricsSeries] = useState<any[] | undefined>(undefined);\n const [showMetrics, setShowMetrics] = useState<boolean>(false);\n const [maxCostsYaxis, setMaxCostsYaxis] = useState<number | undefined>(undefined);\n\n const initChartCallback = useCallback(async () => {\n setCostsSeries(undefined);\n setMetricsSeries(undefined);\n\n if (costs) {\n const sums = [];\n for (const s of costs) {\n for (let i = 0; i < s.data.length; i++) {\n if (sums[i] === undefined) {\n sums[i] = 0;\n }\n sums[i] += s.data[i];\n }\n }\n setMaxCostsYaxis(Math.max(...sums));\n\n setCostsSeries(\n costs.map(s => {\n return {\n id: s.name,\n data: s.data,\n type: 'bar',\n label: s.name,\n yAxisId: 'costsAxis',\n valueFormatter: (value: number) => {\n return formatCurrency(value ? value : 0);\n },\n highlightScope: { highlight: 'series', fade: 'global' },\n stack: 'total',\n stackOrder: 'descending',\n };\n }),\n );\n }\n\n if (metrics && showMetrics) {\n setMetricsSeries(\n metrics.map(s => {\n return {\n data: s.data,\n type: 'line',\n label: s.name,\n curve: 'natural',\n yAxisId: 'metricsAxis',\n highlightScope: { highlight: 'series', fade: 'global' },\n showMark: granularity === 'monthly',\n };\n }),\n );\n }\n }, [costs, metrics, showMetrics, granularity]);\n\n useEffect(() => {\n initChartCallback();\n }, [initChartCallback]);\n\n return (\n <Paper\n sx={{\n padding: '16px',\n display: 'flex',\n flexDirection: 'column',\n height: height ? height : 300,\n }}\n >\n <Grid container justifyContent=\"flex-end\" spacing={1}>\n <Grid item>Monthly</Grid>\n <Grid item>\n <Switch size=\"small\" onChange={event => granularitySetter(event.target.checked ? 'daily' : 'monthly')} />\n </Grid>\n <Grid item>Daily</Grid>\n <Grid item> | </Grid>\n <Grid item>\n <Switch size=\"small\" checked={showMetrics} onChange={_ => setShowMetrics((ori: boolean) => !ori)} />\n </Grid>\n <Grid item>Show Metrics</Grid>\n </Grid>\n {costs && costsSeries ? (\n <ResponsiveChartContainer\n margin={{\n bottom: 80,\n }}\n series={[...costsSeries, ...(metricsSeries ? metricsSeries : [])]}\n xAxis={[\n {\n data: categories,\n scaleType: 'band',\n },\n ]}\n yAxis={[\n {\n id: 'costsAxis',\n max: maxCostsYaxis,\n valueFormatter: value => formatCurrency(value),\n },\n {\n id: 'metricsAxis',\n },\n ]}\n colors={colorList}\n highlightedItem={highlightedItem ? { seriesId: highlightedItem } : null}\n onHighlightChange={highlighted => {\n highlightedItemSetter(highlighted?.seriesId);\n }}\n >\n <ChartsGrid horizontal />\n <BarPlot />\n <LinePlot />\n <LineHighlightPlot />\n <MarkPlot />\n <ChartsXAxis />\n <ChartsYAxis />\n <ChartsTooltip trigger=\"item\" />\n <ChartsLegend\n slots={{\n legend: props => {\n // keep legend items for costs only (from bar chart)\n const seriesToDisplay = [];\n for (const s of props.seriesToDisplay) {\n if (props.series.bar?.seriesOrder && props.series.bar.seriesOrder.indexOf(s.id) !== -1) {\n seriesToDisplay.push(s);\n }\n }\n\n return (\n <DefaultChartsLegend\n series={props.series}\n seriesToDisplay={seriesToDisplay}\n drawingArea={props.drawingArea}\n direction=\"row\"\n position={{ vertical: 'bottom', horizontal: 'middle' }}\n itemMarkHeight={10}\n itemMarkWidth={10}\n labelStyle={{\n fontSize: '0.9em',\n }}\n onItemClick={(_, legendItem) => {\n // highlight the clicked item\n const clickedLegend = legendItem.seriesId;\n if (clickedLegend === highlightedItem) {\n highlightedItemSetter(undefined);\n } else {\n highlightedItemSetter(clickedLegend);\n }\n }}\n />\n );\n },\n }}\n />\n </ResponsiveChartContainer>\n ) : (\n <div style={{ width: '60%', margin: 'auto' }}>\n <Skeleton />\n <Skeleton />\n <Skeleton />\n </div>\n )}\n </Paper>\n );\n};\n"],"names":[],"mappings":";;;;;;;;AAqBO,MAAM,wBAAwD,CAAC;AAAA,EACpE,WAAA;AAAA,EACA,iBAAA;AAAA,EACA,UAAA;AAAA,EACA,KAAA;AAAA,EACA,OAAA;AAAA,EACA,MAAA;AAAA,EACA,eAAA;AAAA,EACA,qBAAA;AACF,CAAM,KAAA;AACJ,EAAA,MAAM,CAAC,WAAA,EAAa,cAAc,CAAA,GAAI,SAA4B,KAAS,CAAA,CAAA,CAAA;AAC3E,EAAA,MAAM,CAAC,aAAA,EAAe,gBAAgB,CAAA,GAAI,SAA4B,KAAS,CAAA,CAAA,CAAA;AAC/E,EAAA,MAAM,CAAC,WAAA,EAAa,cAAc,CAAA,GAAI,SAAkB,KAAK,CAAA,CAAA;AAC7D,EAAA,MAAM,CAAC,aAAA,EAAe,gBAAgB,CAAA,GAAI,SAA6B,KAAS,CAAA,CAAA,CAAA;AAEhF,EAAM,MAAA,iBAAA,GAAoB,YAAY,YAAY;AAChD,IAAA,cAAA,CAAe,KAAS,CAAA,CAAA,CAAA;AACxB,IAAA,gBAAA,CAAiB,KAAS,CAAA,CAAA,CAAA;AAE1B,IAAA,IAAI,KAAO,EAAA;AACT,MAAA,MAAM,OAAO,EAAC,CAAA;AACd,MAAA,KAAA,MAAW,KAAK,KAAO,EAAA;AACrB,QAAA,KAAA,IAAS,IAAI,CAAG,EAAA,CAAA,GAAI,CAAE,CAAA,IAAA,CAAK,QAAQ,CAAK,EAAA,EAAA;AACtC,UAAI,IAAA,IAAA,CAAK,CAAC,CAAA,KAAM,KAAW,CAAA,EAAA;AACzB,YAAA,IAAA,CAAK,CAAC,CAAI,GAAA,CAAA,CAAA;AAAA,WACZ;AACA,UAAA,IAAA,CAAK,CAAC,CAAA,IAAK,CAAE,CAAA,IAAA,CAAK,CAAC,CAAA,CAAA;AAAA,SACrB;AAAA,OACF;AACA,MAAA,gBAAA,CAAiB,IAAK,CAAA,GAAA,CAAI,GAAG,IAAI,CAAC,CAAA,CAAA;AAElC,MAAA,cAAA;AAAA,QACE,KAAA,CAAM,IAAI,CAAK,CAAA,KAAA;AACb,UAAO,OAAA;AAAA,YACL,IAAI,CAAE,CAAA,IAAA;AAAA,YACN,MAAM,CAAE,CAAA,IAAA;AAAA,YACR,IAAM,EAAA,KAAA;AAAA,YACN,OAAO,CAAE,CAAA,IAAA;AAAA,YACT,OAAS,EAAA,WAAA;AAAA,YACT,cAAA,EAAgB,CAAC,KAAkB,KAAA;AACjC,cAAO,OAAA,cAAA,CAAe,KAAQ,GAAA,KAAA,GAAQ,CAAC,CAAA,CAAA;AAAA,aACzC;AAAA,YACA,cAAgB,EAAA,EAAE,SAAW,EAAA,QAAA,EAAU,MAAM,QAAS,EAAA;AAAA,YACtD,KAAO,EAAA,OAAA;AAAA,YACP,UAAY,EAAA,YAAA;AAAA,WACd,CAAA;AAAA,SACD,CAAA;AAAA,OACH,CAAA;AAAA,KACF;AAEA,IAAA,IAAI,WAAW,WAAa,EAAA;AAC1B,MAAA,gBAAA;AAAA,QACE,OAAA,CAAQ,IAAI,CAAK,CAAA,KAAA;AACf,UAAO,OAAA;AAAA,YACL,MAAM,CAAE,CAAA,IAAA;AAAA,YACR,IAAM,EAAA,MAAA;AAAA,YACN,OAAO,CAAE,CAAA,IAAA;AAAA,YACT,KAAO,EAAA,SAAA;AAAA,YACP,OAAS,EAAA,aAAA;AAAA,YACT,cAAgB,EAAA,EAAE,SAAW,EAAA,QAAA,EAAU,MAAM,QAAS,EAAA;AAAA,YACtD,UAAU,WAAgB,KAAA,SAAA;AAAA,WAC5B,CAAA;AAAA,SACD,CAAA;AAAA,OACH,CAAA;AAAA,KACF;AAAA,KACC,CAAC,KAAA,EAAO,OAAS,EAAA,WAAA,EAAa,WAAW,CAAC,CAAA,CAAA;AAE7C,EAAA,SAAA,CAAU,MAAM;AACd,IAAkB,iBAAA,EAAA,CAAA;AAAA,GACpB,EAAG,CAAC,iBAAiB,CAAC,CAAA,CAAA;AAEtB,EACE,uBAAA,KAAA,CAAA,aAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,EAAI,EAAA;AAAA,QACF,OAAS,EAAA,MAAA;AAAA,QACT,OAAS,EAAA,MAAA;AAAA,QACT,aAAe,EAAA,QAAA;AAAA,QACf,MAAA,EAAQ,SAAS,MAAS,GAAA,GAAA;AAAA,OAC5B;AAAA,KAAA;AAAA,oBAEC,KAAA,CAAA,aAAA,CAAA,IAAA,EAAA,EAAK,SAAS,EAAA,IAAA,EAAC,gBAAe,UAAW,EAAA,OAAA,EAAS,CACjD,EAAA,kBAAA,KAAA,CAAA,aAAA,CAAC,IAAK,EAAA,EAAA,IAAA,EAAI,IAAC,EAAA,EAAA,SAAO,mBACjB,KAAA,CAAA,aAAA,CAAA,IAAA,EAAA,EAAK,IAAI,EAAA,IAAA,EAAA,kBACP,KAAA,CAAA,aAAA,CAAA,MAAA,EAAA,EAAO,IAAK,EAAA,OAAA,EAAQ,UAAU,CAAS,KAAA,KAAA,iBAAA,CAAkB,KAAM,CAAA,MAAA,CAAO,UAAU,OAAU,GAAA,SAAS,CAAG,EAAA,CACzG,mBACC,KAAA,CAAA,aAAA,CAAA,IAAA,EAAA,EAAK,IAAI,EAAA,IAAA,EAAA,EAAC,OAAK,CAAA,kBACf,KAAA,CAAA,aAAA,CAAA,IAAA,EAAA,EAAK,MAAI,IAAC,EAAA,EAAA,KAAG,CACd,kBAAA,KAAA,CAAA,aAAA,CAAC,IAAK,EAAA,EAAA,IAAA,EAAI,IACR,EAAA,kBAAA,KAAA,CAAA,aAAA,CAAC,UAAO,IAAK,EAAA,OAAA,EAAQ,OAAS,EAAA,WAAA,EAAa,QAAU,EAAA,CAAA,CAAA,KAAK,cAAe,CAAA,CAAC,QAAiB,CAAC,GAAG,CAAG,EAAA,CACpG,mBACC,KAAA,CAAA,aAAA,CAAA,IAAA,EAAA,EAAK,IAAI,EAAA,IAAA,EAAA,EAAC,cAAY,CACzB,CAAA;AAAA,IACC,SAAS,WACR,mBAAA,KAAA,CAAA,aAAA;AAAA,MAAC,wBAAA;AAAA,MAAA;AAAA,QACC,MAAQ,EAAA;AAAA,UACN,MAAQ,EAAA,EAAA;AAAA,SACV;AAAA,QACA,MAAA,EAAQ,CAAC,GAAG,WAAA,EAAa,GAAI,aAAgB,GAAA,aAAA,GAAgB,EAAG,CAAA;AAAA,QAChE,KAAO,EAAA;AAAA,UACL;AAAA,YACE,IAAM,EAAA,UAAA;AAAA,YACN,SAAW,EAAA,MAAA;AAAA,WACb;AAAA,SACF;AAAA,QACA,KAAO,EAAA;AAAA,UACL;AAAA,YACE,EAAI,EAAA,WAAA;AAAA,YACJ,GAAK,EAAA,aAAA;AAAA,YACL,cAAA,EAAgB,CAAS,KAAA,KAAA,cAAA,CAAe,KAAK,CAAA;AAAA,WAC/C;AAAA,UACA;AAAA,YACE,EAAI,EAAA,aAAA;AAAA,WACN;AAAA,SACF;AAAA,QACA,MAAQ,EAAA,SAAA;AAAA,QACR,eAAiB,EAAA,eAAA,GAAkB,EAAE,QAAA,EAAU,iBAAoB,GAAA,IAAA;AAAA,QACnE,mBAAmB,CAAe,WAAA,KAAA;AAChC,UAAA,qBAAA,CAAsB,2CAAa,QAAQ,CAAA,CAAA;AAAA,SAC7C;AAAA,OAAA;AAAA,sBAEA,KAAA,CAAA,aAAA,CAAC,UAAW,EAAA,EAAA,UAAA,EAAU,IAAC,EAAA,CAAA;AAAA,0CACtB,OAAQ,EAAA,IAAA,CAAA;AAAA,0CACR,QAAS,EAAA,IAAA,CAAA;AAAA,0CACT,iBAAkB,EAAA,IAAA,CAAA;AAAA,0CAClB,QAAS,EAAA,IAAA,CAAA;AAAA,0CACT,WAAY,EAAA,IAAA,CAAA;AAAA,0CACZ,WAAY,EAAA,IAAA,CAAA;AAAA,sBACb,KAAA,CAAA,aAAA,CAAC,aAAc,EAAA,EAAA,OAAA,EAAQ,MAAO,EAAA,CAAA;AAAA,sBAC9B,KAAA,CAAA,aAAA;AAAA,QAAC,YAAA;AAAA,QAAA;AAAA,UACC,KAAO,EAAA;AAAA,YACL,QAAQ,CAAS,KAAA,KAAA;AAvJ/B,cAAA,IAAA,EAAA,CAAA;AAyJgB,cAAA,MAAM,kBAAkB,EAAC,CAAA;AACzB,cAAW,KAAA,MAAA,CAAA,IAAK,MAAM,eAAiB,EAAA;AACrC,gBAAA,IAAA,CAAA,CAAI,EAAM,GAAA,KAAA,CAAA,MAAA,CAAO,GAAb,KAAA,IAAA,GAAA,KAAA,CAAA,GAAA,EAAA,CAAkB,WAAe,KAAA,KAAA,CAAM,MAAO,CAAA,GAAA,CAAI,WAAY,CAAA,OAAA,CAAQ,CAAE,CAAA,EAAE,MAAM,CAAI,CAAA,EAAA;AACtF,kBAAA,eAAA,CAAgB,KAAK,CAAC,CAAA,CAAA;AAAA,iBACxB;AAAA,eACF;AAEA,cACE,uBAAA,KAAA,CAAA,aAAA;AAAA,gBAAC,mBAAA;AAAA,gBAAA;AAAA,kBACC,QAAQ,KAAM,CAAA,MAAA;AAAA,kBACd,eAAA;AAAA,kBACA,aAAa,KAAM,CAAA,WAAA;AAAA,kBACnB,SAAU,EAAA,KAAA;AAAA,kBACV,QAAU,EAAA,EAAE,QAAU,EAAA,QAAA,EAAU,YAAY,QAAS,EAAA;AAAA,kBACrD,cAAgB,EAAA,EAAA;AAAA,kBAChB,aAAe,EAAA,EAAA;AAAA,kBACf,UAAY,EAAA;AAAA,oBACV,QAAU,EAAA,OAAA;AAAA,mBACZ;AAAA,kBACA,WAAA,EAAa,CAAC,CAAA,EAAG,UAAe,KAAA;AAE9B,oBAAA,MAAM,gBAAgB,UAAW,CAAA,QAAA,CAAA;AACjC,oBAAA,IAAI,kBAAkB,eAAiB,EAAA;AACrC,sBAAA,qBAAA,CAAsB,KAAS,CAAA,CAAA,CAAA;AAAA,qBAC1B,MAAA;AACL,sBAAA,qBAAA,CAAsB,aAAa,CAAA,CAAA;AAAA,qBACrC;AAAA,mBACF;AAAA,iBAAA;AAAA,eACF,CAAA;AAAA,aAEJ;AAAA,WACF;AAAA,SAAA;AAAA,OACF;AAAA,wBAGD,KAAA,CAAA,aAAA,CAAA,KAAA,EAAA,EAAI,OAAO,EAAE,KAAA,EAAO,OAAO,MAAQ,EAAA,MAAA,EAClC,EAAA,kBAAA,KAAA,CAAA,aAAA,CAAC,cAAS,CACV,kBAAA,KAAA,CAAA,aAAA,CAAC,cAAS,CACV,kBAAA,KAAA,CAAA,aAAA,CAAC,cAAS,CACZ,CAAA;AAAA,GAEJ,CAAA;AAEJ;;;;"}
|