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

54 lines (47 loc) 2.67 kB
import { isArray } from "@visactor/vutils"; import clustering from "density-clustering"; import normalize from "array-normalize"; import { InsightType } from "../../type"; import { ChartType, ROLE } from "../../../../types"; const isMeasureField = (field, fieldInfo) => { const fieldInfoItem = fieldInfo.find((v => v.fieldName === field)); return fieldInfoItem && fieldInfoItem.role === ROLE.MEASURE; }, dbscanAlgo = (context, options) => { const {seriesDataMap: seriesDataMap, cell: cell, fieldInfo: fieldInfo} = context, {eps: eps = .2, minPts: minPts = 5} = options || {}, {y: celly, x: cellx, color: color, size: size} = cell, yField = isArray(celly) ? celly.flat() : [ celly ], xField = isArray(cellx) ? cellx[0] : cellx, allMeasureFields = [ isArray(color) ? color[0] : color, isArray(size) ? size[0] : size ].filter((v => !!v && isMeasureField(v, fieldInfo))), result = []; return Object.keys(seriesDataMap).forEach((series => { const seriesDataset = seriesDataMap[series]; if (seriesDataset.length <= minPts || seriesDataset.length < 5) return; const flatDataset = seriesDataset.reduce(((prev, cur) => { var _a, _b; return [ ...prev, null !== (_a = cur.dataItem[xField]) && void 0 !== _a ? _a : 0, null !== (_b = cur.dataItem[yField[0]]) && void 0 !== _b ? _b : 0, ...allMeasureFields.map((v => { var _a; return null !== (_a = cur.dataItem[v]) && void 0 !== _a ? _a : 0; })) ]; }), []), dimensionCount = 2 + allMeasureFields.length, normalizedDataset = normalize(flatDataset, dimensionCount), clusterDataset = []; for (let index = 0; index < normalizedDataset.length; index += dimensionCount) { const item = normalizedDataset.slice(index, index + dimensionCount); clusterDataset.push(item); } const dbscan = new clustering.DBSCAN, insights = (dbscan.run(clusterDataset, eps, minPts), dbscan.noise.map((noiseIndex => { const d = seriesDataset[noiseIndex]; return { type: InsightType.Outlier, data: [ d ], fieldId: [ xField, yField[0] ], value: [ d.dataItem[xField], d.dataItem[yField[0]] ], significant: 1, seriesName: series }; }))); result.push(...insights); })), result; }; export const DBSCANOutlier = { name: "dbscan", chartType: [ ChartType.ScatterPlot ], forceChartType: [ ChartType.ScatterPlot ], insightType: InsightType.Outlier, algorithmFunction: dbscanAlgo }; //# sourceMappingURL=dbscan.js.map