UNPKG

@visactor/vmind

Version:

<div align="center"> <a href="https://github.com/VisActor#gh-light-mode-only" target="_blank"> <img alt="VisActor Logo" width="200" src="https://github.com/VisActor/.github/blob/main/profile/logo_500_200_light.svg"/> </a> <a href="https://githu

92 lines (83 loc) 4.64 kB
import { isArray } from "@visactor/vutils"; import { originalMKTest, TrendType } from "../statistics"; import { InsightType } from "../../type"; import { ChartType } from "../../../../types"; import { overallTrendingAlgo } from "../overallTrending"; import { isValidData } from "../.../../../../../utils/common"; import { isPercenSeries, isStackSeries } from "../../utils"; const abnormalTrendAlgo = (context, options) => { const result = [], {threshold: threshold = .2} = options || {}, {insights: insights, seriesDataMap: seriesDataMap, cell: cell, spec: spec} = context, {y: celly, color: color} = cell, yField = isArray(celly) ? celly.flat() : [ celly ]; if (!(isArray(color) ? color[0] : color)) return []; const seriesTrendInfo = []; Object.keys(seriesDataMap).forEach((series => { yField.forEach((measureId => { if (isStackSeries(spec, measureId) || isPercenSeries(spec, measureId)) return; const seriesDataset = seriesDataMap[series].map((d => Number(d.dataItem[measureId]))).filter((v => isValidData(v) && !isNaN(v))), {trend: trend, pValue: pValue, zScore: zScore} = originalMKTest(seriesDataset, .05, !1); if (trend !== TrendType.NO_TREND) { const startValue = seriesDataset[0], endValue = seriesDataset[seriesDataset.length - 1]; seriesTrendInfo.push({ trend: trend, pValue: pValue, zScore: zScore, measureId: measureId, series: series, info: { startValue: startValue, endValue: endValue, change: endValue / startValue - 1 } }); } })); })); let overallTrendInsights = insights.filter((v => v.type === InsightType.OverallTrend)); return 0 === overallTrendInsights.length && (overallTrendInsights = overallTrendingAlgo(context, {})), yField.forEach((measureId => { const measureOverallTrend = insights.find((i => i.type === InsightType.OverallTrend && (null == i ? void 0 : i.fieldId) === measureId)); if (measureOverallTrend) { const seriesInsights = seriesTrendInfo.filter((t => t.measureId === measureId && t.trend !== measureOverallTrend.value)).map((seriesTrend => ({ type: InsightType.AbnormalTrend, data: [], fieldId: measureId, value: seriesTrend.trend, significant: 1 - seriesTrend.pValue, seriesName: seriesTrend.series, info: seriesTrend.info }))); result.push(...seriesInsights); } else { const increaseTrends = seriesTrendInfo.filter((t => t.trend === TrendType.INCREASING && t.measureId === measureId)), decreasedTrends = seriesTrendInfo.filter((t => t.trend === TrendType.DECREASING && t.measureId === measureId)); if (increaseTrends.length > 0 && decreasedTrends.length > 0) if (increaseTrends.length > decreasedTrends.length && (decreasedTrends.length / (increaseTrends.length + decreasedTrends.length) <= threshold || 1 === decreasedTrends.length)) { const decreaseInsights = decreasedTrends.map((dt => ({ type: InsightType.AbnormalTrend, data: [], fieldId: measureId, value: dt.trend, significant: 1 - dt.pValue, seriesName: dt.series, info: dt.info }))); result.push(...decreaseInsights); } else if (increaseTrends.length < decreasedTrends.length && (increaseTrends.length / (increaseTrends.length + decreasedTrends.length) <= threshold || 1 === increaseTrends.length)) { const increaseInsights = increaseTrends.map((it => ({ type: InsightType.AbnormalTrend, fieldId: measureId, value: it.trend, significant: 1 - it.pValue, seriesName: it.series, info: it.info }))); result.push(...increaseInsights); } } })), result; }; export const AbnormalTrend = { name: "abnormalTrend", chartType: [ ChartType.DualAxisChart, ChartType.LineChart, ChartType.BarChart, ChartType.AreaChart ], insightType: InsightType.AbnormalTrend, algorithmFunction: abnormalTrendAlgo, supportPercent: !1, supportStack: !1 }; //# sourceMappingURL=index.js.map