PerspectiveExamples

Market — Orders Themed

3-panel dashboard of Y Bar, Heatmap and X/Y Scatter: Y Bar chart of if("side"=='buy'){1}else{-1}, grouped by bucket("timestamp", 'm'), split by side and status, with 3 computed expression columns; Heatmap chart of if("side"=='buy'){-1}else{1}, grouped by bucket("timestamp", 'm'), split by bucket("price", 0.5), with 3 computed expression columns; X/Y Scatter chart of timestamp, price and if("status"!='open'){"status"}else{"side"}, with 2 computed expression columns.

Depth over time, price-level heatmap and closed orders from the same feed.

Market — Orders Themed: 3-panel dashboard of Y Bar, Heatmap and X/Y Scatter: Y Bar chart of if("side"=='buy'){1}else{-1}, grouped by bucket("timestamp", 'm'), split by side and status, with 3 computed expression columns; Heatmap chart of if("side"=='buy'){-1}else{1}, grouped by bucket("timestamp", 'm'), split by bucket("price", 0.5), with 3 computed expression columns; X/Y Scatter chart of timestamp, price and if("status"!='open'){"status"}else{"side"}, with 2 computed expression columns.

Data

A simulated order book streaming into a Perspective table in real time: orders are created, filled, cancelled and expired continuously, and every data grid, pivot and chart updates incrementally as they arrive.

Generated continuously in the browser by a JavaScript simulation streaming into a Perspective Table.

Configuration

This example is a saved <perspective-viewer> workspace. Pass this JSON to viewer.restoreWorkspace() to reproduce it over the same table:

{
    "layout": {
        "type": "split-layout",
        "orientation": "vertical",
        "sizes": [
            0.5,
            0.5
        ],
        "children": [
            {
                "type": "tab-layout",
                "tabs": [
                    "depth"
                ],
                "selected": 0
            },
            {
                "type": "split-layout",
                "orientation": "horizontal",
                "sizes": [
                    0.5,
                    0.5
                ],
                "children": [
                    {
                        "type": "tab-layout",
                        "tabs": [
                            "heat"
                        ],
                        "selected": 0
                    },
                    {
                        "type": "tab-layout",
                        "tabs": [
                            "closed"
                        ],
                        "selected": 0
                    }
                ]
            }
        ]
    },
    "panels": {
        "depth": {
            "table": "",
            "theme": "Vaporwave",
            "plugin": "Y Bar",
            "plugin_config": {},
            "title": "Depth Timeseries",
            "group_by": [
                "bucket(\"timestamp\", 'm')"
            ],
            "split_by": [
                "side",
                "status"
            ],
            "columns": [
                "if(\"side\"=='buy'){1}else{-1}"
            ],
            "filter": [],
            "sort": [],
            "expressions": {
                "bucket(\"timestamp\", 'm')": "bucket(\"timestamp\", 'm')",
                "if(\"side\"=='buy'){1}else{-1}": "if(\"side\"=='buy'){1}else{-1}",
                "if(\"side\"=='sell'){-1}else{integer(null)}": "if(\"side\"=='sell'){-1}else{integer(null)}"
            },
            "aggregates": {
                "bucket(\"timestamp\", 'm')": "dominant"
            }
        },
        "heat": {
            "table": "",
            "theme": "Solarized Dark",
            "plugin": "Heatmap",
            "plugin_config": {},
            "title": "Heatmap",
            "group_by": [
                "bucket(\"timestamp\", 'm')"
            ],
            "split_by": [
                "bucket(\"price\", 0.5)"
            ],
            "columns": [
                "if(\"side\"=='buy'){-1}else{1}"
            ],
            "filter": [],
            "sort": [],
            "expressions": {
                "bucket(\"timestamp\", 'm')": "bucket(\"timestamp\", 'm')",
                "bucket(\"price\", 0.5)": "bucket(\"price\", 0.5)",
                "if(\"side\"=='buy'){-1}else{1}": "if(\"side\"=='buy'){-1}else{1}"
            },
            "aggregates": {}
        },
        "closed": {
            "table": "",
            "theme": "Solarized Light",
            "plugin": "X/Y Scatter",
            "plugin_config": {},
            "title": "Closed Orders",
            "group_by": [],
            "split_by": [],
            "columns": [
                "timestamp",
                "price",
                "if(\"status\"!='open'){\"status\"}else{\"side\"}"
            ],
            "filter": [],
            "sort": [],
            "expressions": {
                "if(\"status\"!='open'){\"status\"}else{\"side\"}": "if(\"status\"!='open'){\"status\"}else{\"side\"}",
                "if(\"status\"=='closed'){1}else if(\"status\"=='expired'){2}else{0}": "if(\"status\"=='closed'){1}else if(\"status\"=='expired'){2}else{0}"
            },
            "aggregates": {}
        }
    },
    "active": "depth"
}

About Perspective

Perspective is an open-source, WebAssembly-powered data grid, pivot table and charting component for large, real-time and streaming datasets — in the browser, Python, Jupyter, Node.js and Rust.

Documentation