ecStat.js 67 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998
  1. (function webpackUniversalModuleDefinition(root, factory) {
  2. if(typeof exports === 'object' && typeof module === 'object')
  3. module.exports = factory();
  4. else if(typeof define === 'function' && define.amd)
  5. define([], factory);
  6. else if(typeof exports === 'object')
  7. exports["ecStat"] = factory();
  8. else
  9. root["ecStat"] = factory();
  10. })(this, function() {
  11. return /******/ (function(modules) { // webpackBootstrap
  12. /******/ // The module cache
  13. /******/ var installedModules = {};
  14. /******/ // The require function
  15. /******/ function __webpack_require__(moduleId) {
  16. /******/ // Check if module is in cache
  17. /******/ if(installedModules[moduleId])
  18. /******/ return installedModules[moduleId].exports;
  19. /******/ // Create a new module (and put it into the cache)
  20. /******/ var module = installedModules[moduleId] = {
  21. /******/ exports: {},
  22. /******/ id: moduleId,
  23. /******/ loaded: false
  24. /******/ };
  25. /******/ // Execute the module function
  26. /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
  27. /******/ // Flag the module as loaded
  28. /******/ module.loaded = true;
  29. /******/ // Return the exports of the module
  30. /******/ return module.exports;
  31. /******/ }
  32. /******/ // expose the modules object (__webpack_modules__)
  33. /******/ __webpack_require__.m = modules;
  34. /******/ // expose the module cache
  35. /******/ __webpack_require__.c = installedModules;
  36. /******/ // __webpack_public_path__
  37. /******/ __webpack_require__.p = "";
  38. /******/ // Load entry module and return exports
  39. /******/ return __webpack_require__(0);
  40. /******/ })
  41. /************************************************************************/
  42. /******/ ([
  43. /* 0 */
  44. /***/ (function(module, exports, __webpack_require__) {
  45. var __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_RESULT__ = function (require) {
  46. return {
  47. clustering: __webpack_require__(1),
  48. regression: __webpack_require__(5),
  49. statistics: __webpack_require__(6),
  50. histogram: __webpack_require__(15),
  51. transform: {
  52. regression: __webpack_require__(18),
  53. histogram: __webpack_require__(21),
  54. clustering: __webpack_require__(22)
  55. }
  56. };
  57. }.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
  58. /***/ }),
  59. /* 1 */
  60. /***/ (function(module, exports, __webpack_require__) {
  61. var __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_RESULT__ = function (require) {
  62. var dataProcess = __webpack_require__(2);
  63. var dataPreprocess = dataProcess.dataPreprocess;
  64. var normalizeDimensions = dataProcess.normalizeDimensions;
  65. var arrayUtil = __webpack_require__(3);
  66. var numberUtil = __webpack_require__(4);
  67. var arraySize = arrayUtil.size;
  68. var sumOfColumn = arrayUtil.sumOfColumn;
  69. var arraySum = arrayUtil.sum;
  70. var zeros = arrayUtil.zeros;
  71. // var isArray = arrayUtil.isArray;
  72. var numberUtil = __webpack_require__(4);
  73. var isNumber = numberUtil.isNumber;
  74. var mathPow = Math.pow;
  75. var OutputType = {
  76. /**
  77. * Data are all in one. Cluster info are added as an attribute of data.
  78. * ```ts
  79. * type OutputDataSingle = {
  80. * // Each index of `data` is the index of the input data.
  81. * data: OutputDataItem[];
  82. * // The index of `centroids` is the cluster index.
  83. * centroids: [ValueOnX, ValueOnY][];
  84. * };
  85. * type InputDataItem = (ValueOnX | ValueOnY | OtherValue)[];
  86. * type OutputDataItem = (...InputDataItem | ClusterIndex | SquareDistanceToCentroid)[];
  87. * ```
  88. */
  89. SINGLE: 'single',
  90. /**
  91. * Data are separated by cluster. Suitable for retrieving data form each cluster.
  92. * ```ts
  93. * type OutputDataMultiple = {
  94. * // Each index of `clusterAssment` is the index of the input data.
  95. * clusterAssment: [ClusterIndex, SquareDistanceToCentroid][];
  96. * // The index of `centroids` is the cluster index.
  97. * centroids: [ValueOnX, ValueOnY][];
  98. * // The index of `pointsInCluster` is the cluster index.
  99. * pointsInCluster: DataItemListInOneCluster[];
  100. * }
  101. * type DataItemListInOneCluster = InputDataItem[];
  102. * type InputDataItem = (ValueOnX | ValueOnY | OtherValue)[];
  103. * type SquareDistanceToCentroid = number;
  104. * type ClusterIndex = number;
  105. * type ValueOnX = number;
  106. * type ValueOnY = number;
  107. * type OtherValue = unknown;
  108. * ```
  109. */
  110. MULTIPLE: 'multiple'
  111. }
  112. /**
  113. * KMeans of clustering algorithm.
  114. * @param {Array.<Array.<number>>} data two-dimension array
  115. * @param {number} k the number of clusters in a dataset
  116. * @return {Object}
  117. */
  118. function kMeans(data, k, dataMeta) {
  119. // create array to assign data points to centroids, also holds SE of each point
  120. var clusterAssigned = zeros(data.length, 2);
  121. var centroids = createRandCent(k, calcExtents(data, dataMeta.dimensions));
  122. var clusterChanged = true;
  123. var minDist;
  124. var minIndex;
  125. var distIJ;
  126. var ptsInClust;
  127. while (clusterChanged) {
  128. clusterChanged = false;
  129. for (var i = 0; i < data.length; i++) {
  130. minDist = Infinity;
  131. minIndex = -1;
  132. for (var j = 0; j < k; j++) {
  133. distIJ = distEuclid(data[i], centroids[j], dataMeta);
  134. if (distIJ < minDist) {
  135. minDist = distIJ;
  136. minIndex = j;
  137. }
  138. }
  139. if (clusterAssigned[i][0] !== minIndex) {
  140. clusterChanged = true;
  141. }
  142. clusterAssigned[i][0] = minIndex;
  143. clusterAssigned[i][1] = minDist;
  144. }
  145. //recalculate centroids
  146. for (var i = 0; i < k; i++) {
  147. ptsInClust = [];
  148. for (var j = 0; j < clusterAssigned.length; j++) {
  149. if (clusterAssigned[j][0] === i) {
  150. ptsInClust.push(data[j]);
  151. }
  152. }
  153. centroids[i] = meanInColumns(ptsInClust, dataMeta);
  154. }
  155. }
  156. var clusterWithKmeans = {
  157. centroids: centroids,
  158. clusterAssigned: clusterAssigned
  159. };
  160. return clusterWithKmeans;
  161. }
  162. /**
  163. * Calculate the average of each column in a two-dimensional array
  164. * and returns the values as an array.
  165. */
  166. function meanInColumns(dataList, dataMeta) {
  167. var meanArray = [];
  168. var sum;
  169. var mean;
  170. for (var j = 0; j < dataMeta.dimensions.length; j++) {
  171. var dimIdx = dataMeta.dimensions[j];
  172. sum = 0;
  173. for (var i = 0; i < dataList.length; i++) {
  174. sum += dataList[i][dimIdx];
  175. }
  176. mean = sum / dataList.length;
  177. meanArray.push(mean);
  178. }
  179. return meanArray;
  180. }
  181. /**
  182. * The combine of hierarchical clustering and k-means.
  183. * @param {Array} data two-dimension array.
  184. * @param {Object|number} [clusterCountOrConfig] config or clusterCountOrConfig.
  185. * @param {number} clusterCountOrConfig.clusterCount Mandatory.
  186. * The number of clusters in a dataset. It has to be greater than 1.
  187. * @param {boolean} [clusterCountOrConfig.stepByStep=false] Optional.
  188. * @param {OutputType} [clusterCountOrConfig.outputType='multiple'] Optional.
  189. * See `OutputType`.
  190. * @param {number} [clusterCountOrConfig.outputClusterIndexDimension] Mandatory.
  191. * Only work in `OutputType.SINGLE`.
  192. * @param {number} [clusterCountOrConfig.outputCentroidDimensions] Optional.
  193. * If specified, the centroid will be set to those dimensions of the result data one by one.
  194. * By default not set centroid to result.
  195. * Only work in `OutputType.SINGLE`.
  196. * @param {Array.<number>} [clusterCountOrConfig.dimensions] Optional.
  197. * Target dimensions to calculate the regression.
  198. * By default: use all of the data.
  199. * @return {Array} See `OutputType`.
  200. */
  201. function hierarchicalKMeans(data, clusterCountOrConfig, stepByStep) {
  202. var config = (
  203. isNumber(clusterCountOrConfig)
  204. ? {clusterCount: clusterCountOrConfig, stepByStep: stepByStep}
  205. : clusterCountOrConfig
  206. ) || {clusterCount: 2};
  207. var k = config.clusterCount;
  208. if (k < 2) {
  209. return;
  210. }
  211. var dataMeta = parseDataMeta(data, config);
  212. var isOutputTypeSingle = dataMeta.outputType === OutputType.SINGLE;
  213. var dataSet = dataPreprocess(data, {dimensions: dataMeta.dimensions});
  214. var clusterAssment = zeros(dataSet.length, 2);
  215. var outputSingleData;
  216. var setClusterIndex;
  217. var getClusterIndex;
  218. function setDistance(dataIndex, dist) {
  219. clusterAssment[dataIndex][1] = dist;
  220. }
  221. function getDistance(dataIndex) {
  222. return clusterAssment[dataIndex][1];
  223. };
  224. if (isOutputTypeSingle) {
  225. outputSingleData = [];
  226. var outputClusterIndexDimension = dataMeta.outputClusterIndexDimension;
  227. setClusterIndex = function (dataIndex, clusterIndex) {
  228. outputSingleData[dataIndex][outputClusterIndexDimension] = clusterIndex;
  229. };
  230. getClusterIndex = function (dataIndex) {
  231. return outputSingleData[dataIndex][outputClusterIndexDimension];
  232. };
  233. for (var i = 0; i < dataSet.length; i++) {
  234. outputSingleData.push(dataSet[i].slice());
  235. setDistance(i, 0);
  236. setClusterIndex(i, 0);
  237. }
  238. }
  239. else {
  240. setClusterIndex = function (dataIndex, clusterIndex) {
  241. clusterAssment[dataIndex][0] = clusterIndex;
  242. };
  243. getClusterIndex = function (dataIndex) {
  244. return clusterAssment[dataIndex][0];
  245. };
  246. }
  247. // initial center point.
  248. var centroid0 = meanInColumns(dataSet, dataMeta);
  249. var centList = [centroid0];
  250. for (var i = 0; i < dataSet.length; i++) {
  251. var dist = distEuclid(dataSet[i], centroid0, dataMeta);
  252. setDistance(i, dist);
  253. }
  254. var lowestSSE;
  255. var ptsInClust;
  256. var ptsNotClust;
  257. var clusterInfo;
  258. var sseSplit;
  259. var sseNotSplit;
  260. var index = 1;
  261. var result = {
  262. data: outputSingleData,
  263. centroids: centList,
  264. isEnd: false
  265. };
  266. if (!isOutputTypeSingle) {
  267. // Only for backward compat.
  268. result.clusterAssment = clusterAssment;
  269. }
  270. function oneStep() {
  271. //the existing clusters are continuously divided
  272. //until the number of clusters is k
  273. if (index < k) {
  274. lowestSSE = Infinity;
  275. var centSplit;
  276. var newCentroid;
  277. var newClusterAss;
  278. for (var j = 0; j < centList.length; j++) {
  279. ptsInClust = [];
  280. ptsNotClust = [];
  281. for (var i = 0; i < dataSet.length; i++) {
  282. if (getClusterIndex(i) === j) {
  283. ptsInClust.push(dataSet[i]);
  284. }
  285. else {
  286. ptsNotClust.push(getDistance(i));
  287. }
  288. }
  289. clusterInfo = kMeans(ptsInClust, 2, dataMeta);
  290. sseSplit = sumOfColumn(clusterInfo.clusterAssigned, 1);
  291. sseNotSplit = arraySum(ptsNotClust);
  292. if (sseSplit + sseNotSplit < lowestSSE) {
  293. lowestSSE = sseNotSplit + sseSplit;
  294. centSplit = j;
  295. newCentroid = clusterInfo.centroids;
  296. newClusterAss = clusterInfo.clusterAssigned;
  297. }
  298. }
  299. for (var i = 0; i < newClusterAss.length; i++) {
  300. if (newClusterAss[i][0] === 0) {
  301. newClusterAss[i][0] = centSplit;
  302. }
  303. else if (newClusterAss[i][0] === 1) {
  304. newClusterAss[i][0] = centList.length;
  305. }
  306. }
  307. centList[centSplit] = newCentroid[0];
  308. centList.push(newCentroid[1]);
  309. for (var i = 0, j = 0; i < dataSet.length && j < newClusterAss.length; i++) {
  310. if (getClusterIndex(i) === centSplit) {
  311. setClusterIndex(i, newClusterAss[j][0]);
  312. setDistance(i, newClusterAss[j++][1]);
  313. }
  314. }
  315. var pointInClust = [];
  316. if (!isOutputTypeSingle) {
  317. for (var i = 0; i < centList.length; i++) {
  318. pointInClust[i] = [];
  319. for (var j = 0; j < dataSet.length; j++) {
  320. if (getClusterIndex(j) === i) {
  321. pointInClust[i].push(dataSet[j]);
  322. }
  323. }
  324. }
  325. result.pointsInCluster = pointInClust;
  326. }
  327. index++;
  328. }
  329. else {
  330. result.isEnd = true;
  331. }
  332. }
  333. if (!config.stepByStep) {
  334. while (oneStep(), !result.isEnd);
  335. }
  336. else {
  337. result.next = function () {
  338. oneStep();
  339. setCentroidToResultData(result, dataMeta);
  340. return result;
  341. };
  342. }
  343. setCentroidToResultData(result, dataMeta);
  344. return result;
  345. }
  346. function setCentroidToResultData(result, dataMeta) {
  347. var outputCentroidDimensions = dataMeta.outputCentroidDimensions;
  348. if (dataMeta.outputType !== OutputType.SINGLE || outputCentroidDimensions == null) {
  349. return;
  350. }
  351. var outputSingleData = result.data;
  352. var centroids = result.centroids;
  353. for (var i = 0; i < outputSingleData.length; i++) {
  354. var line = outputSingleData[i];
  355. var clusterIndex = line[dataMeta.outputClusterIndexDimension];
  356. var centroid = centroids[clusterIndex];
  357. var dimLen = Math.min(centroid.length, outputCentroidDimensions.length);
  358. for (var j = 0; j < dimLen; j++) {
  359. line[outputCentroidDimensions[j]] = centroid[j];
  360. }
  361. }
  362. }
  363. /**
  364. * Create random centroid of kmeans.
  365. */
  366. function createRandCent(k, extents) {
  367. //constructs a two-dimensional array with all values 0
  368. var centroids = zeros(k, extents.length);
  369. //create random cluster centers, within bounds of each dimension
  370. for (var j = 0; j < extents.length; j++) {
  371. var extentItem = extents[j];
  372. for (var i = 0; i < k; i++) {
  373. centroids[i][j] = extentItem.min + extentItem.span * Math.random();
  374. }
  375. }
  376. return centroids;
  377. }
  378. /**
  379. * Distance method for calculating similarity
  380. */
  381. function distEuclid(dataItem, centroid, dataMeta) {
  382. // The distance should be normalized between different dimensions,
  383. // otherwise they may provide different weight in the final distance.
  384. // The greater weight offers more effect in the cluster determination.
  385. var powerSum = 0;
  386. var dimensions = dataMeta.dimensions;
  387. var extents = dataMeta.rawExtents;
  388. //subtract the corresponding elements in the vectors
  389. for (var i = 0; i < dimensions.length; i++) {
  390. var span = extents[i].span;
  391. // If span is 0, do not count.
  392. if (span) {
  393. var dimIdx = dimensions[i];
  394. var dist = (dataItem[dimIdx] - centroid[i]) / span;
  395. powerSum += mathPow(dist, 2);
  396. }
  397. }
  398. return powerSum;
  399. }
  400. function parseDataMeta(dataSet, config) {
  401. var size = arraySize(dataSet);
  402. if (size.length < 1) {
  403. throw new Error('The input data of clustering should be two-dimension array.');
  404. }
  405. var colCount = size[1];
  406. var defaultDimensions = [];
  407. for (var i = 0; i < colCount; i++) {
  408. defaultDimensions.push(i);
  409. }
  410. var dimensions = normalizeDimensions(config.dimensions, defaultDimensions);
  411. var outputType = config.outputType || OutputType.MULTIPLE;
  412. var outputClusterIndexDimension = config.outputClusterIndexDimension;
  413. if (outputType === OutputType.SINGLE && !numberUtil.isNumber(outputClusterIndexDimension)) {
  414. throw new Error('outputClusterIndexDimension is required as a number.');
  415. }
  416. var extents = calcExtents(dataSet, dimensions);
  417. return {
  418. dimensions: dimensions,
  419. rawExtents: extents,
  420. outputType: outputType,
  421. outputClusterIndexDimension: outputClusterIndexDimension,
  422. outputCentroidDimensions: config.outputCentroidDimensions,
  423. };
  424. }
  425. function calcExtents(dataSet, dimensions) {
  426. var extents = [];
  427. var dimLen = dimensions.length;
  428. for (var i = 0; i < dimLen; i++) {
  429. extents.push({ min: Infinity, max: -Infinity });
  430. }
  431. for (var i = 0; i < dataSet.length; i++) {
  432. var line = dataSet[i];
  433. for (var j = 0; j < dimLen; j++) {
  434. var extentItem = extents[j];
  435. var val = line[dimensions[j]];
  436. extentItem.min > val && (extentItem.min = val);
  437. extentItem.max < val && (extentItem.max = val);
  438. }
  439. }
  440. for (var i = 0; i < dimLen; i++) {
  441. extents[i].span = extents[i].max - extents[i].min;
  442. }
  443. return extents;
  444. }
  445. return {
  446. OutputType: OutputType,
  447. hierarchicalKMeans: hierarchicalKMeans
  448. };
  449. }.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
  450. /***/ }),
  451. /* 2 */
  452. /***/ (function(module, exports, __webpack_require__) {
  453. var __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_RESULT__ = function (require) {
  454. var array = __webpack_require__(3);
  455. var isArray = array.isArray;
  456. var size = array.size;
  457. var number = __webpack_require__(4);
  458. var isNumber = number.isNumber;
  459. /**
  460. * @param {Array.<number>|number} dimensions like `[2, 4]` or `4`
  461. * @param {Array.<number>} [defaultDimensions=undefined] By default `undefined`.
  462. * @return {Array.<number>} number like `4` is normalized to `[4]`,
  463. * `null`/`undefined` is normalized to `defaultDimensions`.
  464. */
  465. function normalizeDimensions(dimensions, defaultDimensions) {
  466. return typeof dimensions === 'number'
  467. ? [dimensions]
  468. : dimensions == null
  469. ? defaultDimensions
  470. : dimensions;
  471. }
  472. /**
  473. * Data preprocessing, filter the wrong data object.
  474. * for example [12,] --- missing y value
  475. * [,12] --- missing x value
  476. * [12, b] --- incorrect y value
  477. * ['a', 12] --- incorrect x value
  478. * @param {Array.<Array>} data
  479. * @param {Object?} [opt]
  480. * @param {Array.<number>} [opt.dimensions] Optional. Like [2, 4],
  481. * means that dimension index 2 and dimension index 4 need to be number.
  482. * If null/undefined (by default), all dimensions need to be number.
  483. * @param {boolean} [opt.toOneDimensionArray] Convert to one dimension array.
  484. * Each value is from `opt.dimensions[0]` or dimension 0.
  485. * @return {Array.<Array.<number>>}
  486. */
  487. function dataPreprocess(data, opt) {
  488. opt = opt || {};
  489. var dimensions = opt.dimensions;
  490. var numberDimensionMap = {};
  491. if (dimensions != null) {
  492. for (var i = 0; i < dimensions.length; i++) {
  493. numberDimensionMap[dimensions[i]] = true;
  494. }
  495. }
  496. var targetOneDim = opt.toOneDimensionArray
  497. ? (dimensions ? dimensions[0] : 0)
  498. : null;
  499. function shouldBeNumberDimension(dimIdx) {
  500. return !dimensions || numberDimensionMap.hasOwnProperty(dimIdx);
  501. }
  502. if (!isArray(data)) {
  503. throw new Error('Invalid data type, you should input an array');
  504. }
  505. var predata = [];
  506. var arraySize = size(data);
  507. if (arraySize.length === 1) {
  508. for (var i = 0; i < arraySize[0]; i++) {
  509. var item = data[i];
  510. if (isNumber(item)) {
  511. predata.push(item);
  512. }
  513. }
  514. }
  515. else if (arraySize.length === 2) {
  516. for (var i = 0; i < arraySize[0]; i++) {
  517. var isCorrect = true;
  518. var item = data[i];
  519. for (var j = 0; j < arraySize[1]; j++) {
  520. if (shouldBeNumberDimension(j) && !isNumber(item[j])) {
  521. isCorrect = false;
  522. }
  523. }
  524. if (isCorrect) {
  525. predata.push(
  526. targetOneDim != null
  527. ? item[targetOneDim]
  528. : item
  529. );
  530. }
  531. }
  532. }
  533. return predata;
  534. }
  535. /**
  536. * @param {string|number} val
  537. * @return {number}
  538. */
  539. function getPrecision(val) {
  540. var str = val.toString();
  541. // scientific notation is not considered
  542. var dotIndex = str.indexOf('.');
  543. return dotIndex < 0 ? 0 : str.length - 1 - dotIndex;
  544. }
  545. return {
  546. normalizeDimensions: normalizeDimensions,
  547. dataPreprocess: dataPreprocess,
  548. getPrecision: getPrecision
  549. };
  550. }.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
  551. /***/ }),
  552. /* 3 */
  553. /***/ (function(module, exports, __webpack_require__) {
  554. var __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_RESULT__ = function (require) {
  555. var objToString = Object.prototype.toString;
  556. var arrayProto = Array.prototype;
  557. var nativeMap = arrayProto.map;
  558. /**
  559. * Get the size of a array
  560. * @param {Array} data
  561. * @return {Array}
  562. */
  563. function size(data) {
  564. var s = [];
  565. while (isArray(data)) {
  566. s.push(data.length);
  567. data = data[0];
  568. }
  569. return s;
  570. }
  571. /**
  572. * @param {*} value
  573. * @return {boolean}
  574. */
  575. function isArray(value) {
  576. return objToString.call(value) === '[object Array]';
  577. }
  578. /**
  579. * constructs a (m x n) array with all values 0
  580. * @param {number} m the row
  581. * @param {number} n the column
  582. * @return {Array}
  583. */
  584. function zeros(m, n) {
  585. var zeroArray = [];
  586. for (var i = 0; i < m ; i++) {
  587. zeroArray[i] = [];
  588. for (var j = 0; j < n; j++) {
  589. zeroArray[i][j] = 0;
  590. }
  591. }
  592. return zeroArray;
  593. }
  594. /**
  595. * Sums each element in the array.
  596. * Internal use, for performance considerations, to avoid
  597. * unnecessary judgments and calculations.
  598. * @param {Array} vector
  599. * @return {number}
  600. */
  601. function sum(vector) {
  602. var sum = 0;
  603. for (var i = 0; i < vector.length; i++) {
  604. sum += vector[i];
  605. }
  606. return sum;
  607. }
  608. /**
  609. * Computes the sum of the specified column elements in a two-dimensional array
  610. * @param {Array.<Array>} dataList two-dimensional array
  611. * @param {number} n the specified column, zero-based
  612. * @return {number}
  613. */
  614. function sumOfColumn(dataList, n) {
  615. var sum = 0;
  616. for (var i = 0; i < dataList.length; i++) {
  617. sum += dataList[i][n];
  618. }
  619. return sum;
  620. }
  621. function ascending(a, b) {
  622. return a > b ? 1 : a < b ? -1 : a === b ? 0 : NaN;
  623. }
  624. /**
  625. * Binary search algorithm --- this bisector is specidfied to histogram, which every bin like that [a, b),
  626. * so the return value use to add 1.
  627. * @param {Array.<number>} array
  628. * @param {number} value
  629. * @param {number} start
  630. * @param {number} end
  631. * @return {number}
  632. */
  633. function bisect(array, value, start, end) { //移出去
  634. if (start == null) {
  635. start = 0;
  636. }
  637. if (end == null) {
  638. end = array.length;
  639. }
  640. while (start < end) {
  641. var mid = Math.floor((start + end) / 2);
  642. var compare = ascending(array[mid], value);
  643. if (compare > 0) {
  644. end = mid;
  645. }
  646. else if (compare < 0) {
  647. start = mid + 1;
  648. }
  649. else {
  650. return mid + 1;
  651. }
  652. }
  653. return start;
  654. }
  655. /**
  656. * 数组映射
  657. * @memberOf module:zrender/core/util
  658. * @param {Array} obj
  659. * @param {Function} cb
  660. * @param {*} [context]
  661. * @return {Array}
  662. */
  663. function map(obj, cb, context) {
  664. if (!(obj && cb)) {
  665. return;
  666. }
  667. if (obj.map && obj.map === nativeMap) {
  668. return obj.map(cb, context);
  669. }
  670. else {
  671. var result = [];
  672. for (var i = 0, len = obj.length; i < len; i++) {
  673. result.push(cb.call(context, obj[i], i, obj));
  674. }
  675. return result;
  676. }
  677. }
  678. return {
  679. size: size,
  680. isArray: isArray,
  681. zeros: zeros,
  682. sum: sum,
  683. sumOfColumn: sumOfColumn,
  684. ascending: ascending,
  685. bisect: bisect,
  686. map: map
  687. };
  688. }.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
  689. /***/ }),
  690. /* 4 */
  691. /***/ (function(module, exports, __webpack_require__) {
  692. var __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_RESULT__ = function (require) {
  693. /**
  694. * Test whether value is a number.
  695. * @param {*} value
  696. * @return {boolean}
  697. */
  698. function isNumber(value) {
  699. value = value === null ? NaN : +value;
  700. return typeof value === 'number' && !isNaN(value);
  701. }
  702. /**
  703. * Test if a number is integer.
  704. * @param {number} value
  705. * @return {boolean}
  706. */
  707. function isInteger(value) {
  708. return isFinite(value) && value === Math.round(value);
  709. }
  710. function quantityExponent(val) {
  711. if (val === 0) {
  712. return 0;
  713. }
  714. var exp = Math.floor(Math.log(val) / Math.LN10);
  715. // Fix pricision loss.
  716. if (val / Math.pow(10, exp) >= 10) {
  717. exp++;
  718. }
  719. return exp;
  720. }
  721. return {
  722. isNumber: isNumber,
  723. isInteger: isInteger,
  724. quantityExponent: quantityExponent
  725. };
  726. }.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
  727. /***/ }),
  728. /* 5 */
  729. /***/ (function(module, exports, __webpack_require__) {
  730. var __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_RESULT__ = function (require) {
  731. var dataProcess = __webpack_require__(2);
  732. var dataPreprocess = dataProcess.dataPreprocess;
  733. var normalizeDimensions = dataProcess.normalizeDimensions;
  734. var regreMethods = {
  735. /**
  736. * Common linear regression algorithm
  737. */
  738. linear: function (predata, opt) {
  739. var xDimIdx = opt.dimensions[0];
  740. var yDimIdx = opt.dimensions[1];
  741. var sumX = 0;
  742. var sumY = 0;
  743. var sumXY = 0;
  744. var sumXX = 0;
  745. var len = predata.length;
  746. for (var i = 0; i < len; i++) {
  747. var rawItem = predata[i];
  748. sumX += rawItem[xDimIdx];
  749. sumY += rawItem[yDimIdx];
  750. sumXY += rawItem[xDimIdx] * rawItem[yDimIdx];
  751. sumXX += rawItem[xDimIdx] * rawItem[xDimIdx];
  752. }
  753. var gradient = ((len * sumXY) - (sumX * sumY)) / ((len * sumXX) - (sumX * sumX));
  754. var intercept = (sumY / len) - ((gradient * sumX) / len);
  755. var result = [];
  756. for (var j = 0; j < predata.length; j++) {
  757. var rawItem = predata[j];
  758. var resultItem = rawItem.slice();
  759. resultItem[xDimIdx] = rawItem[xDimIdx];
  760. resultItem[yDimIdx] = gradient * rawItem[xDimIdx] + intercept;
  761. result.push(resultItem);
  762. }
  763. var expression = 'y = ' + Math.round(gradient * 100) / 100 + 'x + ' + Math.round(intercept * 100) / 100;
  764. return {
  765. points: result,
  766. parameter: {
  767. gradient: gradient,
  768. intercept: intercept
  769. },
  770. expression: expression
  771. };
  772. },
  773. /**
  774. * If the raw data include [0,0] point, we should choose linearThroughOrigin
  775. * instead of linear.
  776. */
  777. linearThroughOrigin: function (predata, opt) {
  778. var xDimIdx = opt.dimensions[0];
  779. var yDimIdx = opt.dimensions[1];
  780. var sumXX = 0;
  781. var sumXY = 0;
  782. for (var i = 0; i < predata.length; i++) {
  783. var rawItem = predata[i];
  784. sumXX += rawItem[xDimIdx] * rawItem[xDimIdx];
  785. sumXY += rawItem[xDimIdx] * rawItem[yDimIdx];
  786. }
  787. var gradient = sumXY / sumXX;
  788. var result = [];
  789. for (var j = 0; j < predata.length; j++) {
  790. var rawItem = predata[j];
  791. var resultItem = rawItem.slice();
  792. resultItem[xDimIdx] = rawItem[xDimIdx];
  793. resultItem[yDimIdx] = rawItem[xDimIdx] * gradient;
  794. result.push(resultItem);
  795. }
  796. var expression = 'y = ' + Math.round(gradient * 100) / 100 + 'x';
  797. return {
  798. points: result,
  799. parameter: {
  800. gradient: gradient
  801. },
  802. expression: expression
  803. };
  804. },
  805. /**
  806. * Exponential regression
  807. */
  808. exponential: function (predata, opt) {
  809. var xDimIdx = opt.dimensions[0];
  810. var yDimIdx = opt.dimensions[1];
  811. var sumX = 0;
  812. var sumY = 0;
  813. var sumXXY = 0;
  814. var sumYlny = 0;
  815. var sumXYlny = 0;
  816. var sumXY = 0;
  817. for (var i = 0; i < predata.length; i++) {
  818. var rawItem = predata[i];
  819. sumX += rawItem[xDimIdx];
  820. sumY += rawItem[yDimIdx];
  821. sumXY += rawItem[xDimIdx] * rawItem[yDimIdx];
  822. sumXXY += rawItem[xDimIdx] * rawItem[xDimIdx] * rawItem[yDimIdx];
  823. sumYlny += rawItem[yDimIdx] * Math.log(rawItem[yDimIdx]);
  824. sumXYlny += rawItem[xDimIdx] * rawItem[yDimIdx] * Math.log(rawItem[yDimIdx]);
  825. }
  826. var denominator = (sumY * sumXXY) - (sumXY * sumXY);
  827. var coefficient = Math.pow(Math.E, (sumXXY * sumYlny - sumXY * sumXYlny) / denominator);
  828. var index = (sumY * sumXYlny - sumXY * sumYlny) / denominator;
  829. var result = [];
  830. for (var j = 0; j < predata.length; j++) {
  831. var rawItem = predata[j];
  832. var resultItem = rawItem.slice();
  833. resultItem[xDimIdx] = rawItem[xDimIdx];
  834. resultItem[yDimIdx] = coefficient * Math.pow(Math.E, index * rawItem[xDimIdx]);
  835. result.push(resultItem);
  836. }
  837. var expression = 'y = ' + Math.round(coefficient * 100) / 100 + 'e^(' + Math.round(index * 100) / 100 + 'x)';
  838. return {
  839. points: result,
  840. parameter: {
  841. coefficient: coefficient,
  842. index: index
  843. },
  844. expression: expression
  845. };
  846. },
  847. /**
  848. * Logarithmic regression
  849. */
  850. logarithmic: function (predata, opt) {
  851. var xDimIdx = opt.dimensions[0];
  852. var yDimIdx = opt.dimensions[1];
  853. var sumlnx = 0;
  854. var sumYlnx = 0;
  855. var sumY = 0;
  856. var sumlnxlnx = 0;
  857. for (var i = 0; i < predata.length; i++) {
  858. var rawItem = predata[i];
  859. sumlnx += Math.log(rawItem[xDimIdx]);
  860. sumYlnx += rawItem[yDimIdx] * Math.log(rawItem[xDimIdx]);
  861. sumY += rawItem[yDimIdx];
  862. sumlnxlnx += Math.pow(Math.log(rawItem[xDimIdx]), 2);
  863. }
  864. var gradient = (i * sumYlnx - sumY * sumlnx) / (i * sumlnxlnx - sumlnx * sumlnx);
  865. var intercept = (sumY - gradient * sumlnx) / i;
  866. var result = [];
  867. for (var j = 0; j < predata.length; j++) {
  868. var rawItem = predata[j];
  869. var resultItem = rawItem.slice();
  870. resultItem[xDimIdx] = rawItem[xDimIdx];
  871. resultItem[yDimIdx] = gradient * Math.log(rawItem[xDimIdx]) + intercept;
  872. result.push(resultItem);
  873. }
  874. var expression =
  875. 'y = '
  876. + Math.round(intercept * 100) / 100
  877. + ' + '
  878. + Math.round(gradient * 100) / 100 + 'ln(x)';
  879. return {
  880. points: result,
  881. parameter: {
  882. gradient: gradient,
  883. intercept: intercept
  884. },
  885. expression: expression
  886. };
  887. },
  888. /**
  889. * Polynomial regression
  890. */
  891. polynomial: function (predata, opt) {
  892. var xDimIdx = opt.dimensions[0];
  893. var yDimIdx = opt.dimensions[1];
  894. var order = opt.order;
  895. if (order == null) {
  896. order = 2;
  897. }
  898. //coefficient matrix
  899. var coeMatrix = [];
  900. var lhs = [];
  901. var k = order + 1;
  902. for (var i = 0; i < k; i++) {
  903. var sumA = 0;
  904. for (var n = 0; n < predata.length; n++) {
  905. var rawItem = predata[n];
  906. sumA += rawItem[yDimIdx] * Math.pow(rawItem[xDimIdx], i);
  907. }
  908. lhs.push(sumA);
  909. var temp = [];
  910. for (var j = 0; j < k; j++) {
  911. var sumB = 0;
  912. for (var m = 0; m < predata.length; m++) {
  913. sumB += Math.pow(predata[m][xDimIdx], i + j);
  914. }
  915. temp.push(sumB);
  916. }
  917. coeMatrix.push(temp);
  918. }
  919. coeMatrix.push(lhs);
  920. var coeArray = gaussianElimination(coeMatrix, k);
  921. var result = [];
  922. for (var i = 0; i < predata.length; i++) {
  923. var value = 0;
  924. var rawItem = predata[i];
  925. for (var n = 0; n < coeArray.length; n++) {
  926. value += coeArray[n] * Math.pow(rawItem[xDimIdx], n);
  927. }
  928. var resultItem = rawItem.slice();
  929. resultItem[xDimIdx] = rawItem[xDimIdx];
  930. resultItem[yDimIdx] = value;
  931. result.push(resultItem);
  932. }
  933. var expression = 'y = ';
  934. for (var i = coeArray.length - 1; i >= 0; i--) {
  935. if (i > 1) {
  936. expression += Math.round(coeArray[i] * Math.pow(10, i + 1)) / Math.pow(10, i + 1) + 'x^' + i + ' + ';
  937. }
  938. else if (i === 1) {
  939. expression += Math.round(coeArray[i] * 100) / 100 + 'x' + ' + ';
  940. }
  941. else {
  942. expression += Math.round(coeArray[i] * 100) / 100;
  943. }
  944. }
  945. return {
  946. points: result,
  947. parameter: coeArray,
  948. expression: expression
  949. };
  950. }
  951. };
  952. /**
  953. * Gaussian elimination
  954. * @param {Array.<Array.<number>>} matrix two-dimensional number array
  955. * @param {number} number
  956. * @return {Array}
  957. */
  958. function gaussianElimination(matrix, number) {
  959. for (var i = 0; i < matrix.length - 1; i++) {
  960. var maxColumn = i;
  961. for (var j = i + 1; j < matrix.length - 1; j++) {
  962. if (Math.abs(matrix[i][j]) > Math.abs(matrix[i][maxColumn])) {
  963. maxColumn = j;
  964. }
  965. }
  966. // the matrix here is the transpose of the common Augmented matrix.
  967. // so the can perform the primary column transform, in fact, equivalent
  968. // to the primary line changes
  969. for (var k = i; k < matrix.length; k++) {
  970. var temp = matrix[k][i];
  971. matrix[k][i] = matrix[k][maxColumn];
  972. matrix[k][maxColumn] = temp;
  973. }
  974. for (var n = i + 1; n < matrix.length - 1; n++) {
  975. for (var m = matrix.length - 1; m >= i; m--) {
  976. matrix[m][n] -= matrix[m][i] / matrix[i][i] * matrix[i][n];
  977. }
  978. }
  979. }
  980. var data = new Array(number);
  981. var len = matrix.length - 1;
  982. for (var j = matrix.length - 2; j >= 0; j--) {
  983. var temp = 0;
  984. for (var i = j + 1; i < matrix.length - 1; i++) {
  985. temp += matrix[i][j] * data[i];
  986. }
  987. data[j] = (matrix[len][j] - temp) / matrix[j][j];
  988. }
  989. return data;
  990. }
  991. /**
  992. * @param {string} regreMethod
  993. * @param {Array.<Array.<number>>} data two-dimensional number array
  994. * @param {Object|number} [optOrOrder] opt or order
  995. * @param {number} [optOrOrder.order] order of polynomials
  996. * @param {Array.<number>|number} [optOrOrder.dimensions=[0, 1]] Target dimensions to calculate the regression.
  997. * By defualt: use [0, 1] as [x, y].
  998. * @return {Array}
  999. */
  1000. var regression = function (regreMethod, data, optOrOrder) {
  1001. var opt = typeof optOrOrder === 'number'
  1002. ? { order: optOrOrder }
  1003. : (optOrOrder || {});
  1004. var dimensions = normalizeDimensions(opt.dimensions, [0, 1]);
  1005. var predata = dataPreprocess(data, { dimensions: dimensions });
  1006. var result = regreMethods[regreMethod](predata, {
  1007. order: opt.order,
  1008. dimensions: dimensions
  1009. });
  1010. // Sort for line chart.
  1011. var xDimIdx = dimensions[0];
  1012. result.points.sort(function (itemA, itemB) {
  1013. return itemA[xDimIdx] - itemB[xDimIdx];
  1014. });
  1015. return result;
  1016. };
  1017. return regression;
  1018. }.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
  1019. /***/ }),
  1020. /* 6 */
  1021. /***/ (function(module, exports, __webpack_require__) {
  1022. var __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_RESULT__ = function (require) {
  1023. var statistics = {};
  1024. statistics.max = __webpack_require__(7);
  1025. statistics.deviation = __webpack_require__(8);
  1026. statistics.mean = __webpack_require__(10);
  1027. statistics.median = __webpack_require__(12);
  1028. statistics.min = __webpack_require__(14);
  1029. statistics.quantile = __webpack_require__(13);
  1030. statistics.sampleVariance = __webpack_require__(9);
  1031. statistics.sum = __webpack_require__(11);
  1032. return statistics;
  1033. }.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
  1034. /***/ }),
  1035. /* 7 */
  1036. /***/ (function(module, exports, __webpack_require__) {
  1037. var __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_RESULT__ = function (require) {
  1038. var number = __webpack_require__(4);
  1039. var isNumber = number.isNumber;
  1040. /**
  1041. * Is a method for computing the max value of a list of numbers,
  1042. * which will filter other data types.
  1043. * @param {Array.<number>} data
  1044. * @return {number}
  1045. */
  1046. function max(data) {
  1047. var maxData = -Infinity;
  1048. for (var i = 0; i < data.length; i++) {
  1049. if (isNumber(data[i]) && data[i] > maxData) {
  1050. maxData = data[i];
  1051. }
  1052. }
  1053. return maxData;
  1054. }
  1055. return max;
  1056. }.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
  1057. /***/ }),
  1058. /* 8 */
  1059. /***/ (function(module, exports, __webpack_require__) {
  1060. var __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_RESULT__ = function (require) {
  1061. var variance = __webpack_require__(9);
  1062. /**
  1063. * Computing the deviation
  1064. * @param {Array.<number>} data
  1065. * @return {number}
  1066. */
  1067. return function (data) {
  1068. var squaredDeviation = variance(data);
  1069. return squaredDeviation ? Math.sqrt(squaredDeviation) : squaredDeviation;
  1070. };
  1071. }.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
  1072. /***/ }),
  1073. /* 9 */
  1074. /***/ (function(module, exports, __webpack_require__) {
  1075. var __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_RESULT__ = function (require) {
  1076. var number = __webpack_require__(4);
  1077. var isNumber = number.isNumber;
  1078. var mean = __webpack_require__(10);
  1079. /**
  1080. * Computing the variance of list of sample
  1081. * @param {Array.<number>} data
  1082. * @return {number}
  1083. */
  1084. function sampleVariance(data) {
  1085. var len = data.length;
  1086. if (!len || len < 2) {
  1087. return 0;
  1088. }
  1089. if (data.length >= 2) {
  1090. var meanValue = mean(data);
  1091. var sum = 0;
  1092. var temple;
  1093. for (var i = 0; i < data.length; i++) {
  1094. if (isNumber(data[i])) {
  1095. temple = data[i] - meanValue;
  1096. sum += temple * temple;
  1097. }
  1098. }
  1099. return sum / (data.length - 1);
  1100. }
  1101. }
  1102. return sampleVariance;
  1103. }.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
  1104. /***/ }),
  1105. /* 10 */
  1106. /***/ (function(module, exports, __webpack_require__) {
  1107. var __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_RESULT__ = function (require) {
  1108. var sum = __webpack_require__(11);
  1109. /**
  1110. * Is a method for computing the mean value of a list of numbers,
  1111. * which will filter other data types.
  1112. * @param {Array.<number>} data
  1113. * @return {number}
  1114. */
  1115. function mean(data) {
  1116. var len = data.length;
  1117. if (!len) {
  1118. return 0;
  1119. }
  1120. return sum(data) / data.length;
  1121. }
  1122. return mean;
  1123. }.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
  1124. /***/ }),
  1125. /* 11 */
  1126. /***/ (function(module, exports, __webpack_require__) {
  1127. var __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_RESULT__ = function (require) {
  1128. var number = __webpack_require__(4);
  1129. var isNumber = number.isNumber;
  1130. /**
  1131. * Is a method for computing the sum of a list of numbers,
  1132. * which will filter other data types.
  1133. * @param {Array.<number>} data
  1134. * @return {number}
  1135. */
  1136. function sum(data) {
  1137. var len = data.length;
  1138. if (!len) {
  1139. return 0;
  1140. }
  1141. var sumData = 0;
  1142. for (var i = 0; i < len; i++) {
  1143. if (isNumber(data[i])) {
  1144. sumData += data[i];
  1145. }
  1146. }
  1147. return sumData;
  1148. }
  1149. return sum;
  1150. }.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
  1151. /***/ }),
  1152. /* 12 */
  1153. /***/ (function(module, exports, __webpack_require__) {
  1154. var __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_RESULT__ = function (require) {
  1155. var quantile = __webpack_require__(13);
  1156. /**
  1157. * Is a method for computing the median value of a sorted array of numbers
  1158. * @param {Array.<number>} data
  1159. * @return {number}
  1160. */
  1161. function median(data) {
  1162. return quantile(data, 0.5);
  1163. }
  1164. return median;
  1165. }.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
  1166. /***/ }),
  1167. /* 13 */
  1168. /***/ (function(module, exports, __webpack_require__) {
  1169. var __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_RESULT__ = function (require) {
  1170. /**
  1171. * Estimating quantiles from a sorted sample of numbers
  1172. * @see https://en.wikipedia.org/wiki/Quantile#Estimating_quantiles_from_a_sample
  1173. * R-7 method
  1174. * @param {Array.<number>} data sorted array
  1175. * @param {number} p
  1176. */
  1177. return function (data, p) {
  1178. var len = data.length;
  1179. if (!len) {
  1180. return 0;
  1181. }
  1182. if (p <= 0 || len < 2) {
  1183. return data[0];
  1184. }
  1185. if (p >= 1) {
  1186. return data[len -1];
  1187. }
  1188. // in the wikipedia's R-7 method h = (N - 1)p + 1, but here array index start from 0
  1189. var h = (len - 1) * p;
  1190. var i = Math.floor(h);
  1191. var a = data[i];
  1192. var b = data[i + 1];
  1193. return a + (b - a) * (h - i);
  1194. };
  1195. }.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
  1196. /***/ }),
  1197. /* 14 */
  1198. /***/ (function(module, exports, __webpack_require__) {
  1199. var __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_RESULT__ = function (require) {
  1200. var number = __webpack_require__(4);
  1201. var isNumber = number.isNumber;
  1202. /**
  1203. * Is a method for computing the min value of a list of numbers,
  1204. * which will filter other data types.
  1205. * @param {Array.<number>} data
  1206. * @return {number}
  1207. */
  1208. function min(data) {
  1209. var minData = Infinity;
  1210. for (var i = 0; i < data.length; i++) {
  1211. if (isNumber(data[i]) && data[i] < minData) {
  1212. minData = data[i];
  1213. }
  1214. }
  1215. return minData;
  1216. }
  1217. return min;
  1218. }.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
  1219. /***/ }),
  1220. /* 15 */
  1221. /***/ (function(module, exports, __webpack_require__) {
  1222. var __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_RESULT__ = function (require) {
  1223. var max = __webpack_require__(7);
  1224. var min = __webpack_require__(14);
  1225. var quantile = __webpack_require__(13);
  1226. var deviation = __webpack_require__(8);
  1227. var dataProcess = __webpack_require__(2);
  1228. var dataPreprocess = dataProcess.dataPreprocess;
  1229. var normalizeDimensions = dataProcess.normalizeDimensions;
  1230. var array = __webpack_require__(3);
  1231. var ascending = array.ascending;
  1232. var map = array.map;
  1233. var range = __webpack_require__(16);
  1234. var bisect = array.bisect;
  1235. var tickStep = __webpack_require__(17);
  1236. /**
  1237. * Compute bins for histogram
  1238. * @param {Array.<number>} data
  1239. * @param {Object|string} optOrMethod Optional settings or `method`.
  1240. * @param {Object|string} optOrMethod.method 'squareRoot' | 'scott' | 'freedmanDiaconis' | 'sturges'
  1241. * @param {Array.<number>|number} optOrMethod.dimensions If data is a 2-d array,
  1242. * which dimension will be used to calculate histogram.
  1243. * @return {Object}
  1244. */
  1245. function computeBins(data, optOrMethod) {
  1246. var opt = typeof optOrMethod === 'string'
  1247. ? { method: optOrMethod }
  1248. : (optOrMethod || {});
  1249. var threshold = opt.method == null
  1250. ? thresholdMethod.squareRoot
  1251. : thresholdMethod[opt.method];
  1252. var dimensions = normalizeDimensions(opt.dimensions);
  1253. var values = dataPreprocess(data, {
  1254. dimensions: dimensions,
  1255. toOneDimensionArray: true
  1256. });
  1257. var maxValue = max(values);
  1258. var minValue = min(values);
  1259. var binsNumber = threshold(values, minValue, maxValue);
  1260. var tickStepResult = tickStep(minValue, maxValue, binsNumber);
  1261. var step = tickStepResult.step;
  1262. var toFixedPrecision = tickStepResult.toFixedPrecision;
  1263. // return the xAxis coordinate for each bins, except the end point of the value
  1264. var rangeArray = range(
  1265. // use function toFixed() to avoid data like '0.700000001'
  1266. +((Math.ceil(minValue / step) * step).toFixed(toFixedPrecision)),
  1267. +((Math.floor(maxValue / step) * step).toFixed(toFixedPrecision)),
  1268. step,
  1269. toFixedPrecision
  1270. );
  1271. var len = rangeArray.length;
  1272. var bins = new Array(len + 1);
  1273. for (var i = 0; i <= len; i++) {
  1274. bins[i] = {};
  1275. bins[i].sample = [];
  1276. bins[i].x0 = i > 0
  1277. ? rangeArray[i - 1]
  1278. : (rangeArray[i] - minValue) === step
  1279. ? minValue
  1280. : (rangeArray[i] - step);
  1281. bins[i].x1 = i < len
  1282. ? rangeArray[i]
  1283. : (maxValue - rangeArray[i-1]) === step
  1284. ? maxValue
  1285. : rangeArray[i - 1] + step;
  1286. }
  1287. for (var i = 0; i < values.length; i++) {
  1288. if (minValue <= values[i] && values[i] <= maxValue) {
  1289. bins[bisect(rangeArray, values[i], 0, len)].sample.push(values[i]);
  1290. }
  1291. }
  1292. var data = map(bins, function (bin) {
  1293. // use function toFixed() to avoid data like '6.5666638489'
  1294. return [
  1295. +((bin.x0 + bin.x1) / 2).toFixed(toFixedPrecision),
  1296. bin.sample.length,
  1297. bin.x0,
  1298. bin.x1,
  1299. bin.x0 + ' - ' + bin.x1
  1300. ];
  1301. });
  1302. var customData = map(bins, function (bin) {
  1303. return [bin.x0, bin.x1, bin.sample.length];
  1304. });
  1305. return {
  1306. bins: bins,
  1307. data: data,
  1308. customData: customData
  1309. };
  1310. }
  1311. /**
  1312. * Four kinds of threshold methods used to
  1313. * compute how much bins the histogram should be divided
  1314. * @see https://en.wikipedia.org/wiki/Histogram
  1315. * @type {Object}
  1316. */
  1317. var thresholdMethod = {
  1318. squareRoot: function (data) {
  1319. var bins = Math.ceil(Math.sqrt(data.length));
  1320. return bins > 50 ? 50 : bins;
  1321. },
  1322. scott: function (data, min, max) {
  1323. return Math.ceil((max - min) / (3.5 * deviation(data) * Math.pow(data.length, -1 / 3)));
  1324. },
  1325. freedmanDiaconis: function (data, min, max) {
  1326. data.sort(ascending);
  1327. return Math.ceil(
  1328. (max - min) / (2 * (quantile(data, 0.75) - quantile(data, 0.25)) * Math.pow(data.length, -1 / 3))
  1329. );
  1330. },
  1331. sturges: function (data) {
  1332. return Math.ceil(Math.log(data.length) / Math.LN2) + 1;
  1333. }
  1334. };
  1335. return computeBins;
  1336. }.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
  1337. /***/ }),
  1338. /* 16 */
  1339. /***/ (function(module, exports, __webpack_require__) {
  1340. var __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_RESULT__ = function (require) {
  1341. var dataProcess = __webpack_require__(2);
  1342. var getPrecision = dataProcess.getPrecision;
  1343. /**
  1344. * Computing range array.
  1345. * Adding param precision to fix range value, avoiding range[i] = 0.7000000001.
  1346. * @param {number} start
  1347. * @param {number} end
  1348. * @param {number} step
  1349. * @param {number} precision
  1350. * @return {Array.<number>}
  1351. */
  1352. return function (start, end, step, precision) {
  1353. var len = arguments.length;
  1354. if (len < 2) {
  1355. end = start;
  1356. start = 0;
  1357. step = 1;
  1358. }
  1359. else if (len < 3) {
  1360. step = 1;
  1361. }
  1362. else if (len < 4) {
  1363. step = +step;
  1364. precision = getPrecision(step);
  1365. }
  1366. else {
  1367. precision = +precision;
  1368. }
  1369. var n = Math.ceil(((end - start) / step).toFixed(precision));
  1370. var range = new Array(n + 1);
  1371. for (var i = 0; i < n + 1; i++) {
  1372. range[i] = +(start + i * step).toFixed(precision);
  1373. }
  1374. return range;
  1375. };
  1376. }.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
  1377. /***/ }),
  1378. /* 17 */
  1379. /***/ (function(module, exports, __webpack_require__) {
  1380. var __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_RESULT__ = function (require) {
  1381. var numberUtil = __webpack_require__(4);
  1382. /**
  1383. * Computing the length of step
  1384. * @see https://github.com/d3/d3-array/blob/master/src/ticks.js
  1385. * @param {number} start
  1386. * @param {number} stop
  1387. * @param {number} count
  1388. */
  1389. return function (start, stop, count) {
  1390. var step0 = Math.abs(stop - start) / count;
  1391. var precision = numberUtil.quantityExponent(step0);
  1392. var step1 = Math.pow(10, precision);
  1393. var error = step0 / step1;
  1394. if (error >= Math.sqrt(50)) {
  1395. step1 *= 10;
  1396. }
  1397. else if (error >= Math.sqrt(10)) {
  1398. step1 *= 5;
  1399. }
  1400. else if(error >= Math.sqrt(2)) {
  1401. step1 *= 2;
  1402. }
  1403. var toFixedPrecision = precision < 0 ? -precision : 0;
  1404. var resultStep = +(
  1405. (stop >= start ? step1 : -step1).toFixed(toFixedPrecision)
  1406. );
  1407. return {
  1408. step: resultStep,
  1409. toFixedPrecision: toFixedPrecision
  1410. };
  1411. };
  1412. }.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
  1413. /***/ }),
  1414. /* 18 */
  1415. /***/ (function(module, exports, __webpack_require__) {
  1416. var __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_RESULT__ = function (require) {
  1417. var regression = __webpack_require__(5);
  1418. var transformHelper = __webpack_require__(19);
  1419. var FORMULA_DIMENSION = 2;
  1420. return {
  1421. type: 'ecStat:regression',
  1422. /**
  1423. * @param {Paramter<typeof regression>[0]} [params.config.method='linear'] 'linear' by default
  1424. * @param {Paramter<typeof regression>[2]} [params.config.order=2] Only work when method is `polynomial`.
  1425. * @param {DimensionLoose[]|DimensionLoose} [params.config.dimensions=[0, 1]] dimensions that used to calculate regression.
  1426. * By default [0, 1].
  1427. * @param {'start' | 'end' | 'all'} params.config.formulaOn Include formula on the last (third) dimension of the:
  1428. * 'start': first data item.
  1429. * 'end': last data item (by default).
  1430. * 'all': all data items.
  1431. * 'none': no data item.
  1432. */
  1433. transform: function transform(params) {
  1434. var upstream = params.upstream;
  1435. var config = params.config || {};
  1436. var method = config.method || 'linear';
  1437. var result = regression(method, upstream.cloneRawData(), {
  1438. order: config.order,
  1439. dimensions: transformHelper.normalizeExistingDimensions(params, config.dimensions)
  1440. });
  1441. var points = result.points;
  1442. var formulaOn = config.formulaOn;
  1443. if (formulaOn == null) {
  1444. formulaOn = 'end';
  1445. }
  1446. var dimensions;
  1447. if (formulaOn !== 'none') {
  1448. for (var i = 0; i < points.length; i++) {
  1449. points[i][FORMULA_DIMENSION] =
  1450. (
  1451. (formulaOn === 'start' && i === 0)
  1452. || (formulaOn === 'all')
  1453. || (formulaOn === 'end' && i === points.length - 1)
  1454. ) ? result.expression : '';
  1455. }
  1456. dimensions = upstream.cloneAllDimensionInfo();
  1457. dimensions[FORMULA_DIMENSION] = {};
  1458. }
  1459. return [{
  1460. dimensions: dimensions,
  1461. data: points
  1462. }];
  1463. }
  1464. };
  1465. }.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
  1466. /***/ }),
  1467. /* 19 */
  1468. /***/ (function(module, exports, __webpack_require__) {
  1469. var __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_RESULT__ = function (require) {
  1470. var arrayUtil = __webpack_require__(3);
  1471. var numberUtil = __webpack_require__(4);
  1472. var objectUtil = __webpack_require__(20);
  1473. /**
  1474. * type DimensionLoose = DimensionIndex | DimensionName;
  1475. * type DimensionIndex = number;
  1476. * type DimensionName = string;
  1477. *
  1478. * @param {object} transformParams The parameter of echarts transfrom.
  1479. * @param {DimensionLoose | DimensionLoose[]} dimensionsConfig
  1480. * @return {DimensionIndex | DimensionIndex[]}
  1481. */
  1482. function normalizeExistingDimensions(transformParams, dimensionsConfig) {
  1483. if (dimensionsConfig == null) {
  1484. return;
  1485. }
  1486. var upstream = transformParams.upstream;
  1487. if (arrayUtil.isArray(dimensionsConfig)) {
  1488. var result = [];
  1489. for (var i = 0; i < dimensionsConfig.length; i++) {
  1490. var dimInfo = upstream.getDimensionInfo(dimensionsConfig[i]);
  1491. validateDimensionExists(dimInfo, dimensionsConfig[i]);
  1492. result[i] = dimInfo.index;
  1493. }
  1494. return result;
  1495. }
  1496. else {
  1497. var dimInfo = upstream.getDimensionInfo(dimensionsConfig);
  1498. validateDimensionExists(dimInfo, dimensionsConfig);
  1499. return dimInfo.index;
  1500. }
  1501. function validateDimensionExists(dimInfo, dimConfig) {
  1502. if (!dimInfo) {
  1503. throw new Error('Can not find dimension by ' + dimConfig);
  1504. }
  1505. }
  1506. }
  1507. /**
  1508. * @param {object} transformParams The parameter of echarts transfrom.
  1509. * @param {(DimensionIndex | {name: DimensionName, index: DimensionIndex})[]} dimensionsConfig
  1510. * @param {{name: DimensionName | DimensionName[], index: DimensionIndex | DimensionIndex[]}}
  1511. */
  1512. function normalizeNewDimensions(dimensionsConfig) {
  1513. if (arrayUtil.isArray(dimensionsConfig)) {
  1514. var names = [];
  1515. var indices = [];
  1516. for (var i = 0; i < dimensionsConfig.length; i++) {
  1517. var item = parseDimensionNewItem(dimensionsConfig[i]);
  1518. names.push(item.name);
  1519. indices.push(item.index);
  1520. }
  1521. return {name: names, index: indices};
  1522. }
  1523. else if (dimensionsConfig != null) {
  1524. return parseDimensionNewItem(dimensionsConfig);
  1525. }
  1526. function parseDimensionNewItem(dimConfig) {
  1527. if (numberUtil.isNumber(dimConfig)) {
  1528. return { index: dimConfig };
  1529. }
  1530. else if (objectUtil.isObject(dimConfig) && numberUtil.isNumber(dimConfig.index)) {
  1531. return dimConfig;
  1532. }
  1533. throw new Error('Illegle new dimensions config. Expect `{ name: string, index: number }`.');
  1534. }
  1535. }
  1536. return {
  1537. normalizeExistingDimensions: normalizeExistingDimensions,
  1538. normalizeNewDimensions: normalizeNewDimensions
  1539. };
  1540. }.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
  1541. /***/ }),
  1542. /* 20 */
  1543. /***/ (function(module, exports, __webpack_require__) {
  1544. var __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_RESULT__ = function (require) {
  1545. function extend(target, source) {
  1546. if (Object.assign) {
  1547. Object.assign(target, source);
  1548. }
  1549. else {
  1550. for (var key in source) {
  1551. if (source.hasOwnProperty(key)) {
  1552. target[key] = source[key];
  1553. }
  1554. }
  1555. }
  1556. return target;
  1557. }
  1558. function isObject(value) {
  1559. const type = typeof value;
  1560. return type === 'function' || (!!value && type === 'object');
  1561. }
  1562. return {
  1563. extend: extend,
  1564. isObject: isObject
  1565. };
  1566. }.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
  1567. /***/ }),
  1568. /* 21 */
  1569. /***/ (function(module, exports, __webpack_require__) {
  1570. var __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_RESULT__ = function (require) {
  1571. var histogram = __webpack_require__(15);
  1572. var transformHelper = __webpack_require__(19);
  1573. return {
  1574. type: 'ecStat:histogram',
  1575. /**
  1576. * @param {'squareRoot' | 'scott' | 'freedmanDiaconis' | 'sturges'} [params.config.method='squareRoot']
  1577. * @param {DimnensionLoose[]} [params.config.dimensions=[0, 1]] dimensions that used to calculate histogram.
  1578. * By default [0].
  1579. */
  1580. transform: function transform(params) {
  1581. var upstream = params.upstream;
  1582. var config = params.config || {};
  1583. var result = histogram(upstream.cloneRawData(), {
  1584. method: config.method,
  1585. dimensions: transformHelper.normalizeExistingDimensions(params, config.dimensions)
  1586. });
  1587. return [{
  1588. dimensions: ['MeanOfV0V1', 'VCount', 'V0', 'V1', 'DisplayableName'],
  1589. data: result.data
  1590. }, {
  1591. data: result.customData
  1592. }];
  1593. }
  1594. };
  1595. }.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
  1596. /***/ }),
  1597. /* 22 */
  1598. /***/ (function(module, exports, __webpack_require__) {
  1599. var __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_RESULT__ = function (require) {
  1600. var clustering = __webpack_require__(1);
  1601. var numberUtil = __webpack_require__(4);
  1602. var transformHelper = __webpack_require__(19);
  1603. var isNumber = numberUtil.isNumber;
  1604. return {
  1605. type: 'ecStat:clustering',
  1606. /**
  1607. * @param {number} params.config.clusterCount Mandatory.
  1608. * The number of clusters in a dataset. It has to be greater than 1.
  1609. * @param {(DimensionName | DimensionIndex)[]} [params.config.dimensions] Optional.
  1610. * Target dimensions to calculate the regression.
  1611. * By default: use all of the data.
  1612. * @param {(DimensionIndex | {name?: DimensionName, index: DimensionIndex})} [params.config.outputClusterIndexDimension] Mandatory.
  1613. * @param {(DimensionIndex | {name?: DimensionName, index: DimensionIndex})[]} [params.config.outputCentroidDimensions] Optional.
  1614. * If specified, the centroid will be set to those dimensions of the result data one by one.
  1615. * By default not set centroid to result.
  1616. */
  1617. transform: function transform(params) {
  1618. var upstream = params.upstream;
  1619. var config = params.config || {};
  1620. var clusterCount = config.clusterCount;
  1621. if (!isNumber(clusterCount) || clusterCount <= 0) {
  1622. throw new Error('config param "clusterCount" need to be specified as an interger greater than 1.');
  1623. }
  1624. if (clusterCount === 1) {
  1625. return [{
  1626. }, {
  1627. data: []
  1628. }];
  1629. }
  1630. var outputClusterIndexDimension = transformHelper.normalizeNewDimensions(
  1631. config.outputClusterIndexDimension
  1632. );
  1633. var outputCentroidDimensions = transformHelper.normalizeNewDimensions(
  1634. config.outputCentroidDimensions
  1635. );
  1636. if (outputClusterIndexDimension == null) {
  1637. throw new Error('outputClusterIndexDimension is required as a number.');
  1638. }
  1639. var result = clustering.hierarchicalKMeans(upstream.cloneRawData(), {
  1640. clusterCount: clusterCount,
  1641. stepByStep: false,
  1642. dimensions: transformHelper.normalizeExistingDimensions(params, config.dimensions),
  1643. outputType: clustering.OutputType.SINGLE,
  1644. outputClusterIndexDimension: outputClusterIndexDimension.index,
  1645. outputCentroidDimensions: (outputCentroidDimensions || {}).index
  1646. });
  1647. var sourceDimAll = upstream.cloneAllDimensionInfo();
  1648. var resultDimsDef = [];
  1649. for (var i = 0; i < sourceDimAll.length; i++) {
  1650. var sourceDimItem = sourceDimAll[i];
  1651. resultDimsDef.push(sourceDimItem.name);
  1652. }
  1653. // Always set to dims def even if name not exists, because the resultDimsDef.length
  1654. // need to be enlarged to tell echarts that there is "cluster index dimension" and "dist dimension".
  1655. resultDimsDef[outputClusterIndexDimension.index] = outputClusterIndexDimension.name;
  1656. if (outputCentroidDimensions) {
  1657. for (var i = 0; i < outputCentroidDimensions.index.length; i++) {
  1658. if (outputCentroidDimensions.name[i] != null) {
  1659. resultDimsDef[outputCentroidDimensions.index[i]] = outputCentroidDimensions.name[i];
  1660. }
  1661. }
  1662. }
  1663. return [{
  1664. dimensions: resultDimsDef,
  1665. data: result.data
  1666. }, {
  1667. data: result.centroids
  1668. }];
  1669. }
  1670. };
  1671. }.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
  1672. /***/ })
  1673. /******/ ])
  1674. });
  1675. ;