GithubHelp home page GithubHelp logo

dnalob / pivot-chart Goto Github PK

View Code? Open in Web Editor NEW

This project forked from observedobserver/pivot-chart

0.0 1.0 0.0 781 KB

light and fast implementation of web pivot table / pivot chart components.

Home Page: https://chspace.oss-cn-hongkong.aliyuncs.com/pivot-chart/index.html?

License: MIT License

JavaScript 63.83% HTML 0.80% CSS 1.58% TypeScript 33.80%

pivot-chart's Introduction

English | 简体中文

Pivot-Chart

pivot chart is a an extension data visualization type of pivot table. It allows user to observe the data in different chart type without limited to table and pure numbers.

pivot chart also provide with basic pivot table components for you to build your web apps, you can regard pivot table as a member in the subset of pivot charts. pivot chart is build based on cube-core: an MOLAP cube solution in js.

Demo

Online Demo

feature demo(gif)
basic expandable nest/cross table basic expandable nest/cross table.gif
custom aggregator of measures ustom aggregator of measures.gif
different visualization type different visualization type.gif

Usage


install npm package.

npm i --save pivot-chart

# or

yarn add pivot-chart


basic usage.

import { PivotChart } from 'fast-pivot';

function App () {
  return <PivotChart
    visType={visType}
    dataSource={data}
    rows={rows}
    columns={columns}
    measures={measures} 
    />
}



demo above can be run locally with
# init development environment
yarn workspace react-pivot-table initenv
# start dev server
yarn workspace react-pivot-table dev

API

Types

Type Desc
Field
- id 
- name 
- aggName  aggregator's name.
- cmp <(a: any, b: any) => number>
Measure extends Field
- aggregator aggregator function.
- minWidth 
- formatter <value: number> => number
VisType currently support number , bar , line , scatter .
Record a plain javascript object
DataSource Record[] , Array of Record.
QueryNode
- dimCode 
- dimValue 
QueryPath <QueryNode[]>.
example: [{dimCode: 'Sex', dimValue: 'male'}, {dimCode: 'Age', dimValue:'*'}]  

common

common interface are those used in both async pivot table and sync pivot table.

  • rows: Field[] dimensions in row. required
  • columns: Field[] dimensions in column.required
  • measures: Measure[] measures or indicators.required
  • visType: VisType mark type in cell. number as default(which is a common pivot table).optional
  • defaultExpandedDepth. default expanded level in row or column nest tree.optional
    • defaultExpandedDepth.rowDepth: number 
    • defaultExpandedDepth.columnDepth: number 
  • showAggregatedNode: {row: boolean; column: boolean} whether display aggregated node for each group. optional

SyncPivotTable

  • dataSource: Record[] . Array of record(normaly plain object). (json style data array). required

example:
import React, { useEffect, useState, useMemo } from 'react';
import ReactDOM from 'react-dom';
import { getTitanicData } from './mock';
import { ToolBar, PivotChart, DragableFields, Aggregators, DataSource, VisType, DraggableFieldState } from '../src/index';

const { dataSource, dimensions, measures } = getTitanicData();
const fields = dimensions.concat(measures).map(f => ({ id: f, name: f }));

const initDraggableState: DraggableFieldState = {
  fields: [],
  rows: [],
  columns: [],
  measures: []
};

function App () {
  const [data, setData] = useState<DataSource>([]);
  const [fstate, setFstate] = useState<DraggableFieldState>(initDraggableState)
  const [visType, setVisType] = useState<VisType>('number');
  useEffect(() => {
    setData(dataSource);
  }, [])
  const measures = useMemo(() => fstate['measures'].map(f => ({
    ...f,
    aggregator: Aggregators[(f.aggName || 'sum') as keyof typeof Aggregators]
  })), [fstate['measures']]);
  return <div>
    <DragableFields onStateChange={(state) => {setFstate(state)}} fields={fields} />
    <ToolBar visType={visType} onVisTypeChange={(type) => { setVisType(type) }} />
    <PivotChart visType={visType} dataSource={data} rows={fstate['rows']} columns={fstate['columns']} measures={measures} />
  </div>
}

ReactDOM.render(<App />, document.getElementById('root'))

AsyncPivotTable

  • cubeQuery: (path: QueryPath, measures: string[]) => Promise; . A function handle for cube query. path is the groupby dimension path(made of a series of dimension and its value). measures are the fields needed to be aggregated. required
  • branchFilter: bad api, not recommanded to use it. a fake filter whihc only control display of node and not influence the aggregated result of parent node. optional
  • dimensionCompare: (a: string, b: string) => number .compare function for sort of dimension node. optional
function AsyncApp () {
  
  const [data, setData] = useState<DataSource>([]);
  const [fields, setFields] = useState<Field[]>([]);
  const [fstate, setFstate] = useState<DraggableFieldState>(initDraggableState)
  const [visType, setVisType] = useState<VisType>('number');
  useEffect(() => {
    const { dataSource, dimensions, measures } = getTitanicData();
    setData(dataSource);
    const fs: Field[] = [...dimensions, ...measures].map((f: string) => ({ id: f, name: f }));
    setFields(fs);
  }, [])
  const measures = useMemo(() => fstate['measures'].map(f => ({
    ...f,
    aggregator: Aggregators[(f.aggName || 'sum') as keyof typeof Aggregators],
    minWidth: 100,
    formatter: f.id === 'Survived' && ((val: any) => `${val} *`)
  })), [fstate['measures']]);
  const cubeQuery = useCallback(async (path: QueryPath, measures: string[]) => {
    return TitanicCubeService(path.map(p => p.dimCode), measures);
  }, [])
  return <div>
    <DragableFields onStateChange={(state) => {setFstate(state)}} fields={fields} />
    <ToolBar visType={visType} onVisTypeChange={(type) => { setVisType(type) }} />
    <AsyncPivotChart
      visType={visType}
      rows={fstate['rows']}
      columns={fstate['columns']}
      async
      defaultExpandedDepth={{
        rowDepth: 20,
        columnDepth: 20
      }}
      cubeQuery={cubeQuery}
      measures={measures} />
  </div>
}

Theme

  • Theme.registerTheme(theme: ThemeConfig)
  • ThemeConfig 
interface ThemeConfig {
  root?: {
    display?: boolean,
    label?: string
  },
  summary?: {
    label?: string
  },
  table?: {
    thead?: {
      backgroundColor?: string;
      color?: string;
    }
    borderColor?: string;
    color?: string;
  }
}
// default config
const THEME_CONFIG: ThemeConfig = {
  root: {
    display: true,
    label: 'All'
  },
  summary: {
    label: '(total)'
  },
  table: {
    thead: {
      backgroundColor: '#E9EDF2',
      color: '#5A6C84'
    },
    borderColor: '#DFE3E8',
    color: '#333333'
  }
};
import React, { useEffect, useState, useMemo } from 'react';
import ReactDOM from 'react-dom';
import { getTitanicData } from './mock';
import { ToolBar, PivotChart, DragableFields, Aggregators, DataSource, VisType, DraggableFieldState, Theme } from '../src/index';

const { dataSource, dimensions, measures } = getTitanicData();
const fields = dimensions.concat(measures).map(f => ({ id: f, name: f }));

const initDraggableState: DraggableFieldState = {
  fields: [],
  rows: [],
  columns: [],
  measures: []
};

Theme.registerTheme({
  root: {
    display: true,
    label: 'root'
  },
  summary: {
    label: '(total)'
  }
})

function App () {
  const [data, setData] = useState<DataSource>([]);
  const [fstate, setFstate] = useState<DraggableFieldState>(initDraggableState)
  const [visType, setVisType] = useState<VisType>('number');
  useEffect(() => {
    setData(dataSource);
  }, [])
  const measures = useMemo(() => fstate['measures'].map(f => ({
    ...f,
    aggregator: Aggregators[(f.aggName || 'sum') as keyof typeof Aggregators]
  })), [fstate['measures']]);
  return <div>
    <DragableFields onStateChange={(state) => {setFstate(state)}} fields={fields} />
    <ToolBar visType={visType} onVisTypeChange={(type) => { setVisType(type) }} />
    <PivotChart visType={visType} dataSource={data} rows={fstate['rows']} columns={fstate['columns']} measures={measures} />
  </div>
}

ReactDOM.render(<App />, document.getElementById('root'))

Others


another implementation of cube-core pivot-table can be found as ./packages/demo

Common Question

SyncPivotChart vs. AsyncPivotChart ?

Sync Pivot Chart does all cube computaion in frontend.(In future, it may do those work in webworker and it will seems to be async). Those cube query can be speeded up by cube-core which can reuse similarly groupby result.
Async Pivot Chart can use cube query from server or customed implementation(either on server or browser, async or sync), but developer need to figure out how to speed up those by themsleves.

pivot-chart's People

Contributors

observedobserver avatar dependabot[bot] avatar

Watchers

James Cloos avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.