npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

cube-core

v2.13.0

Published

![](https://travis-ci.com/ObservedObserver/cube-core.svg?branch=master) ![](https://img.shields.io/github/license/ObservedObserver/cube-core) ![](https://img.shields.io/npm/v/cube-core)

Downloads

267

Readme

cube-core

cube-core 是一个高效的Cube求解工具,你可以借助它来实现快速的Cube运算或搭建pivot table组件。 如果你想了解能够使用cube-core做什么,可以了解一个基于cube-core实现的前端的高性能pivot table项目:fast-pivot

使用

npm install --save cube-core

创建一个多维数据集

import {createCube} from 'cube-core'

let cube = createCube ({
    aggFunc: (subset, measures) => {},
    factTable: [{}, {}, {}, ..., {}],
    dimensions: ['dim1', 'dim2', ..., 'dimn'],
    measures: ['mea1', 'mea2', ..., 'mean']
})
  • factTable: 事实表数据。
  • dimensions: 维度数组,对应事实表中的维度字段名
  • measures: 度量数组,对应事实表中的度量字段名
  • aggFunc: 聚合函数,接收两个参数subset(事实表的子集), measures。示例:
function sum_unsafe (subset, MEASURES) {
    let sums = {}
    MEASURES.forEach((mea) => {
      sums[mea] = 0
    })
    for (let i = 0, len = subset.length; i < len; i++) {
        MEASURES.forEach((mea) => {
            sums[mea] += subset[i][mea]
          })
    }
    return sums
}

你可以选择在做聚合运算时进行类型判断以防止意外的错误,但聚合运算将会是整个cube求解中很消耗资源的一部分、所以尽量保证将数据清洗、特殊处理的过程放在cube求解之前,保证cube拿到的faceTable是干净、安全的数据。

API

cube.setData

setData会接收新的数据信息并根据信息重新计算聚合。

  • dimensions: (可选) 由维度字段名构成的数组
  • measures: (可选) 由度量字段名构成的数组
  • aggFunc: (可选) 聚合函数
  • factTable: (可选) 事实表数据

示例

cube.setData({
    dimensions: Dimensions.slice(3)
})

cube.get(dimMembers: any[]): Row

从cube中获取某一维度成员组合的聚合值

dimensions = ['Sex', 'Age', 'PClass'];
cube.get(['male', 30, 1]);

cube.tree

cube中构建的聚合树(索引树)会构建在属性tree中,你可以尝试自定义的对tree上的每个节点进行操作。 节点node的结构为

// moment cube
class Node {
    constructor () {
        this.children = new Map()
        this.rawData = []
    }
    push () {
        this.rawData.push(...arguments)
    }
    
    aggData (aggFunc, measures = []) {
        this._aggData = aggFunc(this.rawData, measures)
        return this._aggData
    }
}
// period cube
class pNode {
    constructor (aggFunc) {
        this.children = new Map()
        this._rawData = []
        this.aggFunc = aggFunc
        this.cache = false
    }
    push () {
        this._rawData.push(...arguments)
    }
    aggData (measures = []) {
        if (!this.cache) {
            this._aggData = this.aggFunc(this.rawData, measures)
            this.cache = true
        }
        return this._aggData
    }
    clearCache () {
        this.cache = false
    }
    get rawData () {
        if (!this.cache) {
            if (this.children.size !== 0) {
                let children = this.children.values()
                let rawData = []
                for (let child of children) {
                    let i, data = child.rawData;
                    let len = data.length;
                    for (i = 0; i < len; i++) {
                        rawData.push(data[i])
                    }
                }
                this._rawData = rawData
            }
            this.cache = true
        }
        return this._rawData
    }
}

node._aggData 与 node.aggData(aggFunc)

node 为tree上的任意节点,在node上,我们可以通过_aggData调用已经计算过的计算聚合值的缓存,也可以通过aggData(aggFunc)来重新获得当前节点基于聚合函数aggFunc的新的聚合值,这使得你可以在树的不同层级的不同节点使用不同的聚合方式。

> node._aggData
> {profit: 120, cost: 200, count: 15}

node.rawData

为了支持更多的场景,你还可以直接从当前节点获取该节点对应的原始数据而非聚合数据。这在可视化类BI应用中的聚合度量模式切换时的实现会提供极大的便利(比如散点图)。

> node.rawData
[
    {profit: 12, cost: 20, count: 1},
    {profit: 8, cost: 12, count: 1},
    {profit: 31, cost: 28, count: 1},
    {profit: 19, cost: 5, count: 1},
    ...
]

utils

cube-core提供了一些常见的聚合函数:

import { sum, unsafe_sum, count } from 'cube-core';
// sum 会做类型安全检查的和

流程

leftcycle-img

测试

cube-core为你提供了最基本的算法正确性检验测试与时间测试,你只需要使用npm test即可进行测试。

./test/performance中,有一些可以使用的对于真实数据集、尤其是那些非常大的数据集的测试脚本,你可以修改其中数据集文件的路径来使用自己的数据集进行测试。

在前端的使用

在前端使用时,你还需要将cube.tree转化成自己的UI渲染需要的数据结构。

个性化的优化

如果你能够定义两个聚合的快速合并方法,那么这棵树的性能可以大幅度提升。例如

parent.sum = child1.sum + child2.sum + ... + childn.sum 而不是 parent.sum = sum(parent.rawData)

对于和、计数、平均值、最大、最小值甚至是K大数等,没有必要每次都重新聚合后的数组进行计算,而是根据子节点的聚合值完成O(1)的运算。但对于更复杂的场景,设计这样一个聚合运算会愈发艰难。所以,cube-core再设计Cube时仍为你提供了node.rawData这一属性以方便你应对更为复杂的场景。

但你很快会发现,如果能够通过定义节点聚合值得聚合方式,那么你会获得极高的时间与空间的收益。