### Initialize Perspective Viewer and Connect to WebSocket Source: https://github.com/perspective-dev/perspective/blob/master/examples/python-tornado-streaming/index.html Imports necessary libraries, gets a reference to the viewer element, and establishes a WebSocket connection to the Perspective server. This setup is required before loading data. ```javascript import "/node_modules/@perspective-dev/viewer/dist/cdn/perspective-viewer.js"; import perspective from "/node_modules/@perspective-dev/client/dist/cdn/perspective.js"; const viewer = document.getElementById("viewer"); // Create a client that expects a server to accept // Websocket connections at the specified URL. const websocket = await perspective.websocket("ws://localhost:8080/websocket"); ``` -------------------------------- ### Run Example Packages Source: https://github.com/perspective-dev/perspective/blob/master/DEVELOPMENT.md After a successful build, execute this command to run example packages, such as 'blocks'. ```bash pnpm run start blocks ``` -------------------------------- ### Run Pyodide Test Setup Source: https://github.com/perspective-dev/perspective/blob/master/rust/perspective-python/pyodide-tests/README.md Execute the setup command for the Pyodide target using pnpm. ```bash pnpm -w run setup ``` -------------------------------- ### Install Perspective and Tornado Source: https://github.com/perspective-dev/perspective/blob/master/docs/md/tutorials/python/tornado.md Install the necessary Python packages for Perspective and Tornado. ```bash pip install perspective-python tornado ``` -------------------------------- ### Load Superstore Data into Perspective Viewer Source: https://github.com/perspective-dev/perspective/blob/master/rust/perspective-viewer/test/html/superstore-inline.html Imports the Perspective Viewer, fetches the Superstore CSV, creates a Perspective worker, loads the data into a table, and then loads the table into the viewer. This is the primary setup for the inline example. ```javascript import "/node_modules/@perspective-dev/viewer/dist/esm/perspective-viewer.inline.js"; import perspective from "/node_modules/@perspective-dev/client/dist/cdn/perspective.js"; async function load() { let resp = await fetch("/node_modules/@perspective-dev/test/assets/superstore.csv"); let csv = await resp.text(); const viewer = document.querySelector("perspective-viewer"); const worker = await perspective.worker(); const table = worker.table(csv, { index: "Row ID" }); await viewer.load(table); window.__TEST_WORKER__ = worker; } await load(); window.__TEST_PERSPECTIVE_READY__ = true; ``` -------------------------------- ### Install Perspective and ClickHouse Client Source: https://github.com/perspective-dev/perspective/blob/master/docs/md/how_to/javascript/virtual_server/clickhouse.md Install the necessary Perspective client, viewer, and the ClickHouse web client using npm. ```bash npm install @perspective-dev/client @perspective-dev/viewer @clickhouse/client-web ``` -------------------------------- ### Install Perspective and ClickHouse Connect Source: https://github.com/perspective-dev/perspective/blob/master/docs/md/how_to/python/virtual_server/clickhouse.md Install the necessary Python packages for Perspective and ClickHouse connectivity. ```bash pip install perspective-python clickhouse-connect ``` -------------------------------- ### Install Perspective JavaScript Packages Source: https://context7.com/perspective-dev/perspective/llms.txt Install the core data engine and viewer UI, along with optional visualization plugins and a React wrapper. ```bash # Core data engine + viewer UI npm add @perspective-dev/client @perspective-dev/viewer # Optional visualization plugins npm add @perspective-dev/viewer-charts @perspective-dev/viewer-datagrid # React wrapper npm add @perspective-dev/react ``` -------------------------------- ### ESM Builds with Bundler - Basic Setup Source: https://github.com/perspective-dev/perspective/blob/master/docs/md/how_to/javascript/importing.md This is the basic setup for ESM builds with a bundler. You need to provide the paths to the WASM binaries and then initialize Perspective. The exact paths will depend on your bundler's configuration. ```javascript import perspective_viewer from "@perspective-dev/viewer"; import perspective from "@perspective-dev/client"; // TODO These paths must be provided by the bundler! const SERVER_WASM = ... // "@perspective-dev/server/dist/wasm/perspective-server.wasm" const CLIENT_WASM = ... // "@perspective-dev/viewer/dist/wasm/perspective-viewer.wasm" await Promise.all([ perspective.init_server(SERVER_WASM), perspective_viewer.init_client(CLIENT_WASM), ]); // Now Perspective API will work! const worker = await perspective.worker(); const viewer = document.createElement("perspective-viewer"); ``` -------------------------------- ### Install Node.js Client Source: https://github.com/perspective-dev/perspective/blob/master/docs/md/how_to/javascript/installation.md Install the Perspective client for use in a Node.js server environment. This package includes the WebAssembly data engine. ```bash npm add @perspective-dev/client ``` -------------------------------- ### Install Perspective and DuckDB Source: https://github.com/perspective-dev/perspective/blob/master/docs/md/how_to/python/virtual_server/duckdb.md Install the necessary Python packages for Perspective and DuckDB. ```bash pip install perspective-python duckdb ``` -------------------------------- ### Install Core Browser Modules Source: https://github.com/perspective-dev/perspective/blob/master/docs/md/how_to/javascript/installation.md Install the core Perspective client and viewer for browser-based applications. The viewer provides the UI framework, while the client includes the WebAssembly data engine. ```bash npm add @perspective-dev/client @perspective-dev/viewer ``` -------------------------------- ### Install Perspective and Polars Source: https://github.com/perspective-dev/perspective/blob/master/docs/md/how_to/python/virtual_server/polars.md Install the necessary Python packages for Perspective and Polars. ```bash pip install perspective-python polars ``` -------------------------------- ### Install Perspective and DuckDB WASM Source: https://github.com/perspective-dev/perspective/blob/master/docs/md/how_to/javascript/virtual_server/duckdb.md Install the necessary packages for Perspective client, viewer, and DuckDB-WASM. ```bash npm install @perspective-dev/client @perspective-dev/viewer @duckdb/duckdb-wasm ``` -------------------------------- ### Install Python Requirements Source: https://github.com/perspective-dev/perspective/blob/master/DEVELOPMENT.md Install the necessary Python requirements for the perspective-python package. Ensure your project is configured for Python builds using 'pnpm run setup' first. ```bash pip install -r rust/perspective-python/requirements.txt ``` -------------------------------- ### Protobuf Setup Source: https://github.com/perspective-dev/perspective/blob/master/rust/perspective-server/cpp/perspective/CMakeLists.txt Sets up the Protocol Buffers (protobuf) library for the project. It disables protobuf tests and adds the protobuf build directory to the main binary directory. ```cmake # Protobuf setup set(protobuf_BUILD_TESTS OFF FORCE) add_subdirectory(${PSP_CMAKE_MODULE_PATH}/../cpp/protos "${CMAKE_BINARY_DIR}/protos-build") ``` -------------------------------- ### Install Optional Browser Plugins Source: https://github.com/perspective-dev/perspective/blob/master/docs/md/how_to/javascript/installation.md Install optional visualization plugins for the Perspective viewer. These plugins add specific renderers like charts and data grids to the viewer's capabilities. ```bash npm add @perspective-dev/viewer-charts @perspective-dev/viewer-datagrid @perspective-dev/viewer-openlayers ``` -------------------------------- ### Install Playwright Browsers Source: https://github.com/perspective-dev/perspective/blob/master/rust/perspective-python/pyodide-tests/README.md Install the necessary browsers for Playwright if prompted during the test execution. ```bash python -m playwright install ``` -------------------------------- ### Install Perspective Python Package Source: https://context7.com/perspective-dev/perspective/llms.txt Install the Perspective Python package. For DuckDB virtual server support, install duckdb as well. ```bash pip install perspective-python # For DuckDB virtual server support pip install perspective-python duckdb ``` -------------------------------- ### Initialize Rust Server, Load Arrow Data, and Query Source: https://context7.com/perspective-dev/perspective/llms.txt Set up a local Perspective server and client in Rust, load data from an Arrow file, and perform queries using a View. This example demonstrates filtering, grouping, and aggregation. ```rust use perspective::{Server, TableData, TableInitOptions, UpdateData}; use perspective_client::config::*; use std::{fs::File, io::Read, collections::HashMap}; #[tokio::main] async fn main() -> Result<(), Box> { let server = Server::default(); let client = server.new_local_client(); // Load an Arrow file let mut file = File::open("data/superstore.arrow")?; let mut bytes = Vec::new(); file.read_to_end(&mut bytes)?; let mut opts = TableInitOptions::default(); opts.set_name("superstore"); let table = client .table(TableData::Update(UpdateData::Arrow(bytes.into())), opts) .await?; // Query with a View let view = table .view(Some(ViewConfigUpdate { columns: Some(vec![Some("Sales".into()), Some("Profit".into())]), group_by: Some(vec!["Region".into(), "Category".into()]) , aggregates: Some(HashMap::from([ ("Sales".into(), "sum".into()), ("Profit".into(), "sum".into()), ])), filter: Some(vec![Filter::new( "Category", "in", &["Furniture", "Technology"], )]), sort: Some(vec![Sort("Sales".into(), SortDir::Desc)]), ..ViewConfigUpdate::default() })) .await?; let arrow = view.to_arrow().await?; let json = view.to_json().await?; println!("Result rows: {}", json.as_array().unwrap().len()); // Tree expansion view.set_depth(1).await?; view.expand(2).await?; view.delete().await?; Ok(()) } ``` -------------------------------- ### Install Perspective Python with Verbose Logging Source: https://github.com/perspective-dev/perspective/blob/master/DEVELOPMENT.md Installs the perspective-python package in verbose mode to aid in troubleshooting installation issues, particularly CMake or Boost problems. ```bash pip install -vv perspective-python ``` -------------------------------- ### Python Tornado Server Setup Source: https://github.com/perspective-dev/perspective/blob/master/docs/md/explanation/architecture/client_server.md Sets up a Perspective server using Python and Tornado, creating a local client and exposing a websocket endpoint for client connections. Ensure 'csv' is defined and imported. ```python from perspective import Server, PerspectiveTornadoHandler server = Server() client = server.new_local_client() client.table(csv, name="my_table") routes = [( r"/websocket", perspective.handlers.tornado.PerspectiveTornadoHandler, {"perspective_server": server}, )] app = tornado.web.Application(routes) app.listen(8080) loop = tornado.ioloop.IOLoop.current() loop.start() ``` -------------------------------- ### Install Perspective-Python Pyodide Requirements Source: https://github.com/perspective-dev/perspective/blob/master/rust/perspective-python/pyodide-tests/README.md Install the main requirements for perspective-python and the additional requirements specific to Pyodide. ```bash pip install -r rust/perspective-python/requirements.txt pip install -r rust/perspective-python/requirements-pyodide.txt ``` -------------------------------- ### Install JupyterLab Manager and Perspective Extension Source: https://github.com/perspective-dev/perspective/blob/master/packages/jupyterlab/README.md Install the necessary JupyterLab extensions for the Perspective integration. This is a prerequisite for using the Perspective JupyterLab extension. ```bash jupyter labextension install @jupyter-widgets/jupyterlab-manager jupyter labextension install @perspective-dev/jupyterlab ``` -------------------------------- ### Create a View with Aggregations and Filters Source: https://github.com/perspective-dev/perspective/blob/master/docs/md/explanation/view/querying.md Create a view on a table instance to query data. This example configures columns, aggregations, grouping, and filters. ```javascript const view = await table.view({ columns: ["Sales"], aggregates: { Sales: "sum" }, group_by: ["Region", "Country"], filter: [["Category", "in", ["Furniture", "Technology"]]], }); ``` ```python view = table.view( columns=["Sales"], aggregates={"Sales": "sum"}, group_by=["Region", "Country"], filter=[["Category", "in", ["Furniture", "Technology"]]] ) ``` ```rust use crate::config::*; let view = table .view(Some(ViewConfigUpdate { columns: Some(vec![Some("Sales".into())]), aggregates: Some(HashMap::from_iter(vec![("Sales".into(), "sum".into())])), group_by: Some(vec!["Region".into(), "Country".into()]) , filter: Some(vec![Filter::new("Category", "in", &[ "Furniture", "Technology", ])]), ..ViewConfigUpdate::default() })) .await?; ``` -------------------------------- ### Python ClickHouse Virtual Server Setup Source: https://github.com/perspective-dev/perspective/blob/master/docs/md/how_to/python/virtual_server/clickhouse.md Create a Tornado web server that exposes ClickHouse tables to browser clients via WebSocket using Perspective's ClickhouseVirtualServer. ```python import clickhouse_connect import tornado.web import tornado.ioloop from perspective import ClickhouseVirtualServer from perspective.handlers.tornado import PerspectiveTornadoHandler # Connect to ClickHouse client = clickhouse_connect.get_client(host="localhost") # Create virtual server backed by ClickHouse server = ClickhouseVirtualServer(client) # Serve over WebSocket app = tornado.web.Application([ (r"/websocket", PerspectiveTornadoHandler, {"perspective_server": server}), ]) app.listen(8080) tornado.ioloop.IOLoop.current().start() ``` -------------------------------- ### Initialize Perspective and Load Data Source: https://github.com/perspective-dev/perspective/blob/master/examples/blocks/src/superstore/index.html Imports necessary Perspective modules, fetches data from a URL, and loads it into a Perspective table. This is the primary setup for displaying data. ```javascript import "/node_modules/@perspective-dev/viewer/dist/cdn/perspective-viewer.js"; import "/node_modules/@perspective-dev/workspace/dist/cdn/perspective-workspace.js"; import "/node_modules/@perspective-dev/viewer-datagrid/dist/cdn/perspective-viewer-datagrid.js"; import "/node_modules/@perspective-dev/viewer-charts/dist/cdn/perspective-viewer-charts.js"; import perspective from "/node_modules/@perspective-dev/client/dist/cdn/perspective.js"; const DATA_URL = "/node_modules/superstore-arrow/superstore.lz4.arrow"; async function get_layout() { const req = await fetch("layout.json"); const json = await req.json(); return json; } const request = fetch(DATA_URL); const worker = await perspective.worker(); const response = await request; const buffer = await response.arrayBuffer(); await worker.table(buffer, { name: "superstore" }); window.workspace.load(worker); const layout = await get_layout(); await window.workspace.restore(layout); ``` -------------------------------- ### Tornado WebSocket Server Setup Source: https://github.com/perspective-dev/perspective/blob/master/docs/md/how_to/python/websocket.md Set up a Tornado web server with `PerspectiveTornadoHandler` to expose a Perspective `Server` instance at a WebSocket endpoint. This allows multiple `perspective-viewer` clients to connect and access hosted tables. ```python from perspective import Server from perspective.handlers.tornado import PerspectiveTornadoHandler # Create an instance of Server, and host a Table SERVER = Server() CLIENT = SERVER.new_local_client() # The Table is exposed at `localhost:8888/websocket` with the name `data_source` client.table(data, name = "data_source") app = tornado.web.Application([ # create a websocket endpoint that the client JavaScript can access (r"/websocket", PerspectiveTornadoHandler, {"perspective_server": SERVER}) ]) # Start the Tornado server app.listen(8888) loop = tornado.ioloop.IOLoop.current() loop.start() ``` -------------------------------- ### Install Perspective via Cargo Source: https://github.com/perspective-dev/perspective/blob/master/docs/md/how_to/rust.md Add the Perspective library to your Rust project using Cargo. ```bash cargo add perspective ``` -------------------------------- ### Configure with HTML Attributes Source: https://github.com/perspective-dev/perspective/blob/master/docs/md/how_to/javascript/viewer.md Configure the using HTML attributes for initial setup. Attributes like 'columns', 'group-by', and 'sort' allow pre-setting the viewer's configuration. ```html ``` -------------------------------- ### Python Server Setup for Distributed Mode Source: https://github.com/perspective-dev/perspective/blob/master/rust/perspective-python/docs/lib.md Sets up a Tornado server to host a Perspective Table and expose it via WebSocket. This server instance can then be accessed by multiple `perspective-viewer` clients. ```python from perspective import Server from perspective.hadnlers.tornado import PerspectiveTornadoHandler # Create an instance of Server, and host a Table SERVER = Server() CLIENT = SERVER.new_local_client() # The Table is exposed at `localhost:8888/websocket` with the name `data_source` client.table(data, name = "data_source") app = tornado.web.Application([ # create a websocket endpoint that the client JavaScript can access (r"/websocket", PerspectiveTornadoHandler, {"perspective_server": SERVER}) ]) # Start the Tornado server app.listen(8888) loop = tornado.ioloop.IOLoop.current() loop.start() ``` -------------------------------- ### Client-Server Editing Setup Source: https://github.com/perspective-dev/perspective/blob/master/examples/python-tornado/client_server_editing.html Connects to a websocket, creates a Perspective worker, and sets up tables and views on both the server and client for synchronized editing. Ensure the server is running and accessible at ws://localhost:8080/websocket. ```javascript const viewer = document.getElementById("viewer"); const websocket = perspective.websocket("ws://localhost:8080/websocket"); const worker = perspective.worker(); const server_table = await websocket.open_table("data_source_one"); const server_view = await server_table.view(); const arrow = await server_view.to_arrow(); const client_table = await worker.table(arrow, { index: "Row ID" }); const client_view = await client_table.view(); await viewer.load(Promise.resolve(client_table)); const client_edit_port = await viewer.getEditPort(); const server_edit_port = await server_table.make_port(); ``` -------------------------------- ### Start WebSocket Server and Host Table in Node.js Source: https://github.com/perspective-dev/perspective/blob/master/docs/md/how_to/javascript/nodejs_server.md Initiates a WebSocket and HTTP host on a specified port and serves static assets. It then reads an Arrow file from the file system and hosts it as a named table on the server. ```javascript const { WebSocketServer, table } = require("@perspective-dev/client"); const fs = require("fs"); // Start a WS/HTTP host on port 8080. The `assets` property allows // the `WebSocketServer()` to also serves the file structure rooted in this // module's directory. const host = new WebSocketServer({ assets: [__dirname], port: 8080 }); // Read an arrow file from the file system and host it as a named table. const arr = fs.readFileSync(__dirname + "/superstore.lz4.arrow"); await table(arr, { name: "table_one" }); ``` -------------------------------- ### Initialize with a Table Source: https://github.com/perspective-dev/perspective/blob/master/docs/md/how_to/javascript/viewer.md Import and initialize the Web Component in JavaScript to bind a Perspective.js Table to it. This example demonstrates loading data into the viewer. ```html ``` -------------------------------- ### Initialize Perspective Viewer with Worker Source: https://github.com/perspective-dev/perspective/blob/master/rust/perspective-viewer/test/html/blank.html Import the Perspective Viewer and client modules, then initialize a web worker for Perspective. This setup is required before using the Perspective Viewer in an HTML page. ```html import "/node_modules/@perspective-dev/viewer/dist/cdn/perspective-viewer.js"; import perspective from "/node_modules/@perspective-dev/client/dist/cdn/perspective.js"; window.WORKER = perspective.worker(); ``` -------------------------------- ### Load Arrow Data and Group By in Python Source: https://github.com/perspective-dev/perspective/blob/master/docs/md/explanation/python.md This example demonstrates loading Apache Arrow data into a Perspective table, performing a 'Group By' operation, and converting the result back to Arrow format. Ensure `arrow_bytes_data` is defined and contains valid Arrow data. ```python from perspective import Server client = Server().new_local_client() table = client.table(arrow_bytes_data) view = table.view(group_by = ["CounterParty", "Security"]) arrow = view.to_arrow() ``` -------------------------------- ### Install Specific Emscripten Version Source: https://github.com/perspective-dev/perspective/blob/master/DEVELOPMENT.md Use this command to install a particular version of the Emscripten SDK, for example, '2.0.6'. ```bash ./emsdk install 2.0.6 ``` -------------------------------- ### Initialize Server and Client Source: https://github.com/perspective-dev/perspective/blob/master/docs/md/how_to/rust.md Set up a Perspective server and create a new local client connection. ```rust let server = Server::default(); let client = server.new_local_client(); ``` -------------------------------- ### Initialize Perspective Server and Client Source: https://github.com/perspective-dev/perspective/blob/master/docs/md/tutorials/python/tornado.md Set up a Perspective server and a local client to manage tables. ```python import perspective SERVER = perspective.Server() CLIENT = SERVER.new_local_client() ``` -------------------------------- ### Install perspective-python via Pip Source: https://github.com/perspective-dev/perspective/blob/master/docs/md/how_to/python/installation.md Use this command to install the perspective-python package from PyPI. If JupyterLab is installed, the PerspectiveWidget class will be available. ```bash pip install perspective-python ``` -------------------------------- ### Install perspective via Conda Source: https://github.com/perspective-dev/perspective/blob/master/docs/md/how_to/python/installation.md Use this command to install the perspective package from Conda Forge. This is an alternative installation method for Anaconda users. ```bash conda install -c conda-forge perspective ``` -------------------------------- ### Initialize and Configure `` Source: https://context7.com/perspective-dev/perspective/llms.txt Load data into the viewer and programmatically set its configuration, including plugin, columns, grouping, sorting, filtering, and expressions. State can be saved and restored. ```html ``` -------------------------------- ### Python: Set up DuckDB Virtual Server Source: https://github.com/perspective-dev/perspective/blob/master/docs/md/how_to/python/virtual_server/duckdb.md Create a Python server using Tornado that exposes a DuckDB database via Perspective's virtual server. Load data into DuckDB and serve it over WebSocket. ```python import duckdb import tornado.web import tornado.ioloop from perspective import DuckDBVirtualServer from perspective.handlers.tornado import PerspectiveTornadoHandler # Create DuckDB connection and load data conn = duckdb.connect() conn.execute("CREATE TABLE my_table AS SELECT * FROM 'data.parquet'") # Create virtual server backed by DuckDB server = DuckDBVirtualServer(conn) # Serve over WebSocket app = tornado.web.Application([ (r"/websocket", PerspectiveTornadoHandler, {"perspective_server": server}), ]) app.listen(8080) tornado.ioloop.IOLoop.current().start() ``` -------------------------------- ### Run Perspective Benchmarks Source: https://github.com/perspective-dev/perspective/blob/master/DEVELOPMENT.md Generates machine-specific benchmarks, hosts a live dashboard at http://localhost:8080, and outputs a benchmark.arrow file. ```bash pnpm run bench ``` -------------------------------- ### Create and Query a View in Python Source: https://github.com/perspective-dev/perspective/blob/master/docs/md/explanation/view.md Shows how to initialize a Perspective table, create a view selecting specific columns, serialize the view to Apache Arrow format, and then delete the view. This is useful for data querying and extraction in Python. ```python table = perspective.Table({ "id": [1, 2, 3, 4], "name": ["a", "b", "c", "d"] }); view = table.view(columns=["name"]) arrow = view.to_arrow() view.delete() ``` -------------------------------- ### Install Boost Dependencies on Ubuntu/Debian Source: https://github.com/perspective-dev/perspective/blob/master/DEVELOPMENT.md Installs the Boost development libraries and copies headers to the project's source directory to resolve CMake conflicts. ```bash apt-get install libboost-all-dev cp -r /usr/include/boost ./packages/perspective/src/include/ ``` -------------------------------- ### Initialize PerspectiveWidget with data and options Source: https://github.com/perspective-dev/perspective/blob/master/docs/md/how_to/python/jupyterlab.md Instantiate a `PerspectiveWidget` with data, specifying plugin, aggregates, and sort order. This is useful for setting up an initial view with specific configurations. ```python from perspective.widget import PerspectiveWidget w = perspective.PerspectiveWidget( data, plugin="X Bar", aggregates={"datetime": "any"}, sort=[["date", "desc"]] ) ``` -------------------------------- ### Initialize Perspective Viewer and Load Data Source: https://github.com/perspective-dev/perspective/blob/master/docs/template.html Imports necessary Perspective modules and initializes the viewer. Fetches data from a URL, creates a Perspective table, and loads it into the viewer. Toggles the viewer's configuration panel. ```javascript import "/node_modules/@perspective-dev/viewer/dist/cdn/perspective-viewer.js"; import "/node_modules/@perspective-dev/viewer-datagrid/dist/cdn/perspective-viewer-datagrid.js"; import "/node_modules/@perspective-dev/viewer-charts/dist/cdn/perspective-viewer-charts.js"; import perspective from "/node_modules/@perspective-dev/client/dist/cdn/perspective.js"; const WORKER = await perspective.worker(); var xhr = new XMLHttpRequest(); const req = await fetch("/node_modules/superstore-arrow/superstore.lz4.arrow"); const buff = await req.arrayBuffer(); var el = document.getElementsByTagName("perspective-viewer")[0]; const plugin = await el.getPlugin("Heatmap"); plugin.render_warning = false; const table = WORKER.table(buff); await el.load(table); await el.toggleConfig(); window.__TEST_PERSPECTIVE_READY__ = true; ``` -------------------------------- ### Install System Dependencies on MacOS Source: https://github.com/perspective-dev/perspective/blob/master/DEVELOPMENT.md Install CMake and a specific version of LLVM using Homebrew on MacOS. Linking LLVM is optional but may be required. ```bash brew install cmake llvm@17 ``` ```bash brew link llvm@17 ``` -------------------------------- ### NDJSON (JSON Lines) Example Source: https://github.com/perspective-dev/perspective/blob/master/docs/md/explanation/table/loading_data.md Example of NDJSON (or JSONL) format, where each line is a valid JSON object. This streaming-friendly format is useful for data pipelines. ```json { "a": 86, "b": false, "c": "words" } { "a": 0, "b": true, "c": "" } { "a": 12345, "b": false, "c": "here" } ``` -------------------------------- ### Initialize Table with Index (Python) Source: https://github.com/perspective-dev/perspective/blob/master/docs/md/explanation/table/options.md Configure a Perspective `Table` with an `index` column in Python to enable in-place updates and row management based on a primary key. ```python indexed_table = perspective.Table(data, index="a"); ``` -------------------------------- ### Row-Oriented JSON Example Source: https://github.com/perspective-dev/perspective/blob/master/docs/md/explanation/table/loading_data.md Example of row-oriented JSON data, where each object in the list represents a row in the table. This format is suitable for direct loading into Perspective. ```json [ { "a": 86, "b": false, "c": "words" }, { "a": 0, "b": true, "c": "" }, { "a": 12345, "b": false, "c": "here" } ] ``` -------------------------------- ### Initialize Perspective Client and Generate Data Source: https://github.com/perspective-dev/perspective/blob/master/examples/blocks/src/dataset/index.html Sets up the Perspective client and defines functions to generate random data for a table. It includes logic for batch updates and delays. ```javascript import "/node_modules/@perspective-dev/viewer-datagrid/dist/cdn/perspective-viewer-datagrid.js"; import "/node_modules/@perspective-dev/viewer-charts/dist/cdn/perspective-viewer-charts.js"; import "/node_modules/@perspective-dev/viewer/dist/cdn/perspective-viewer.js"; import "/node_modules/@perspective-dev/workspace/dist/cdn/perspective-workspace.js"; import perspective from "/node_modules/@perspective-dev/client/dist/cdn/perspective.js"; const client = await perspective.worker(); const choose = (x) => x[Math.floor(Math.random() * x.length)]; const range = (x, y) => Math.random() * (y - x) + x; const rand_string = () => Math.random().toString(36).substring(7); const strings = (choices) => new Array(choices).fill(null).map(rand_string); const colname = (name, x) => `${name.charAt(0).toUpperCase() + name.slice(1)} ${x}`; function* col_iter() { for (const name of ["float", "integer", "string", "datetime", "boolean"]) { const ncols = window[`num_${name}`].value; for (let x = 0; x < ncols; x++) { yield [name, x]; } } } const assign = (fn) => { const obj = {}; for (const [name, x] of col_iter()) { obj[colname(name, x)] = fn(name, x); } return obj; }; const new_schema = () => assign((x) => x); let string_cache; function reset_strings_cache() { string_cache = {}; } reset_strings_cache(); const get_dict = (xs) => { string_cache[xs] = string_cache[xs] || strings(parseInt(num_strings.value)); return string_cache[xs]; }; const cell_args = { float: () => range(-10, 10), integer: () => Math.floor(range(-10, 10)), string: (xs) => choose(get_dict(xs)), datetime: () => new Date(), boolean: () => choose([true, false, null]), }; const new_row = () => assign((name, x) => cell_args[name](x)); const gen_data = async () => { reset_strings_cache(); let nrows = num_rows.value; let rows = []; const batch_size = Math.floor(nrows / num_batches.value); const batch_freq = batch_delay.value; const tbl = await client.table(new_schema(), { name: "superstore" }); (function batch() { while (nrows > 0) { rows.push(new_row()); nrows--; if (nrows % batch_size === 0) { tbl.update(rows); rows = []; setTimeout(batch, batch_freq); break; } } })(); return tbl; }; ``` -------------------------------- ### Column-Oriented JSON Example Source: https://github.com/perspective-dev/perspective/blob/master/docs/md/explanation/table/loading_data.md Example of column-oriented JSON data, where each key is a column name and the list contains all values for that column. This format is also suitable for direct loading. ```json { "a": [86, 0, 12345], "b": [false, true, false], "c": ["words", "", "here"] } ``` -------------------------------- ### Conditional Clangd Setup in CMake Source: https://github.com/perspective-dev/perspective/blob/master/rust/perspective-server/cpp/perspective/CMakeLists.txt Includes the clangd setup script only if the PSP_DISABLE_CLANGD environment variable is not set. This is useful for development environments to enable code completion and analysis tools. ```cmake # TODO this needs to be omitted when built by `cmake-rs`, because #`cargo publish --dry-run` complains when this generate `.clangd` in the Rust # root dir instead of teh `target` dir. if(NOT DEFINED ENV{PSP_DISABLE_CLANGD}) include(SetupClangd) endif() ``` -------------------------------- ### Rust Reactive Join Example Source: https://context7.com/perspective-dev/perspective/llms.txt Perform a reactive join between two tables in Rust using Perspective. This example demonstrates joining order and product data based on 'product_id' with a left join. ```rust use perspective::{Server, TableData, TableInitOptions, UpdateData, JoinOptions, JoinType}; let server = Server::default(); let client = server.new_local_client(); let orders = client.table( TableData::Update(UpdateData::JsonRows( r#"[{{"id":1,"product_id":101,"qty":5}},{{"id":2,"product_id":102,"qty":3}}]"#.into(), )), TableInitOptions::default(), ).await?; let products = client.table( TableData::Update(UpdateData::JsonRows( r#"[{{"product_id":101,"name":"Widget"}},{{"product_id":102,"name":"Gadget"}}]"#.into(), )), TableInitOptions::default(), ).await?; let joined = client.join( (&orders).into(), (&products).into(), "product_id", JoinOptions { join_type: Some(JoinType::Left), ..JoinOptions::default() }, ).await?; let view = joined.view(None).await?; let json = view.to_json().await?; // [{ product_id: 101, id: 1, qty: 5, name: "Widget" }, ...] ``` -------------------------------- ### Monitor System Information with Perspective Source: https://github.com/perspective-dev/perspective/blob/master/examples/blocks/src/dataset/index.html Creates a 'stats' table to monitor system information like heap size, CPU time, and version. It continuously updates this table with live system data. ```javascript const stats_table = await client.table( { heap_size: "float", used_size: "float", cpu_time: "integer", cpu_time_epoch: "integer", version: "integer", timestamp: "datetime", client_used: "float", client_heap: "float", }, { limit: 2000, name: "stats", }); (async function check_mem_loop() { await stats_table.update([await client.system_info()]); setTimeout(check_mem_loop, 200); })(); ``` -------------------------------- ### Initialize Perspective.js and Load Data Source: https://github.com/perspective-dev/perspective/blob/master/examples/blocks/src/movies/index.html This script initializes Perspective.js, fetches movie data from a URL, processes release dates, creates a Perspective table, and updates it with the fetched data. It also loads a workspace layout. ```javascript import "/node_modules/@perspective-dev/viewer/dist/cdn/perspective-viewer.js"; import "/node_modules/@perspective-dev/workspace/dist/cdn/perspective-workspace.js"; import "/node_modules/@perspective-dev/viewer-datagrid/dist/cdn/perspective-viewer-datagrid.js"; import "/node_modules/@perspective-dev/viewer-charts/dist/cdn/perspective-viewer-charts.js"; import perspective from "/node_modules/@perspective-dev/client/dist/cdn/perspective.js"; const SCHEMA = { Title: "string", "US Gross": "float", "Worldwide Gross": "float", "US DVD Sales": "float", "Production Budget": "float", "Release Date": "date", "MPAA Rating": "string", "Running Time min": "integer", Distributor: "string", Source: "string", "Major Genre": "string", "Creative Type": "string", Director: "string", "Rotten Tomatoes Rating": "integer", "IMDB Rating": "float", "IMDB Votes": "integer", }; const MOVIES_URL = "https://vega.github.io/editor/data/movies.json"; (async () => { const request = fetch(MOVIES_URL); const worker = await perspective.worker(); const response = await request; const json = await response.json(); for (const row of json) { row["Release Date"] = row["Release Date"] ? new Date(row["Release Date"]) || null : null; } const table = await worker.table(SCHEMA, { name: "movies" }); table.update(json); let req = await fetch("layout.json"); let layout = await req.json(); await window.workspace.load(worker); await window.workspace.restore(layout); })(); ``` -------------------------------- ### Connect to a Virtual Server with perspective.worker() Source: https://github.com/perspective-dev/perspective/blob/master/docs/md/how_to/javascript/custom_worker.md Connect a Perspective client to a Virtual Server by creating a `MessagePort` with `perspective.createMessageHandler()` and passing it to `perspective.worker()`. This allows Perspective queries to be handled by an external data source. ```javascript import perspective from "@perspective-dev/client"; const handler = { /* VirtualServerHandler implementation */ }; const server = perspective.createMessageHandler(handler); const client = await perspective.worker(server); const table = await client.open_table("my_table"); ``` -------------------------------- ### Retrieve Full View Configuration Source: https://github.com/perspective-dev/perspective/blob/master/docs/md/explanation/view/advanced.md Get the complete configuration object that was used to create the current view. ```javascript const config = await view.get_config(); // { group_by: [...], split_by: [...], sort: [...], filter: [...], ... } ``` ```python config = view.get_config() ``` -------------------------------- ### Create Perspective Table from PyArrow Table Source: https://github.com/perspective-dev/perspective/blob/master/docs/md/how_to/python/table_data.md Construct a Perspective Table directly from a PyArrow Table. Ensure PyArrow is installed. ```python import pyarrow as pa import perspective arrow_table = pa.table({ "int": pa.array([1, 2, 3], type=pa.int64()), "float": pa.array([1.5, 2.5, 3.5], type=pa.float64()), "string": pa.array(["a", "b", "c"], type=pa.string()), }) table = perspective.table(arrow_table) ``` -------------------------------- ### Initialize DuckDB and Connect to Viewer Source: https://github.com/perspective-dev/perspective/blob/master/docs/md/how_to/javascript/virtual_server/duckdb.md Initialize DuckDB-WASM, load data, and connect it to a Perspective viewer. This involves setting up the DuckDB worker, instantiating the database, and creating a Perspective virtual server handler. ```javascript import perspective from "@perspective-dev/client"; import "@perspective-dev/viewer"; import * as duckdb from "@duckdb/duckdb-wasm"; // Initialize DuckDB-WASM const DUCKDB_BUNDLES = duckdb.getJsDelivrBundles(); const bundle = await duckdb.selectBundle(DUCKDB_BUNDLES); const worker = await duckdb.createWorker(bundle.mainWorker); const logger = new duckdb.ConsoleLogger(); const db = new duckdb.AsyncDuckDB(logger, worker); await db.instantiate(bundle.mainModule); // Load data into DuckDB const conn = await db.connect(); await conn.query(`CREATE TABLE my_table AS SELECT * FROM 'data.parquet'`); // Create a Perspective virtual server backed by DuckDB const handler = perspective.DuckDBHandler(db); const messageHandler = perspective.createMessageHandler(handler); // Connect a viewer const client = await perspective.worker(messageHandler); const table = await client.open_table("my_table"); document.getElementById("viewer").load(table); ``` -------------------------------- ### View Dimensions Source: https://github.com/perspective-dev/perspective/blob/master/docs/md/explanation/view/advanced.md Get the current dimensions of the View, including the number of rows and columns, and information about group-by header rows. ```APIDOC ## View Dimensions `View::dimensions` returns the number of rows and columns in the current view. ### Dimensions Retrieves the dimensions of the view. - **Method**: `dimensions()` - **Returns**: `Promise` - An object containing view dimensions such as `num_view_rows`, `num_view_columns`, `num_table_rows`, `num_table_columns`, etc. ``` -------------------------------- ### Get View Dimensions Source: https://github.com/perspective-dev/perspective/blob/master/docs/md/explanation/view/advanced.md Obtain the number of rows and columns in the current view, including details about group-by header rows. ```javascript const dims = await view.dimensions(); // { num_view_rows, num_view_columns, num_table_rows, num_table_columns, ... } ``` ```python dims = view.dimensions() ``` -------------------------------- ### Connect to WebSocket and Load Table Source: https://github.com/perspective-dev/perspective/blob/master/rust/perspective-python/bench/runtime/benchmark_hosted.html Establishes a WebSocket connection to the Perspective server, opens a specific table, and loads it into the viewer. Ensure the viewer element exists in the HTML and the server is running. ```javascript const websocket = perspective.websocket("ws://localhost:8888/websocket"); const table = websocket.open_table("benchmark_results"); document.getElementById("viewer").load(table); ``` -------------------------------- ### Develop Python Package with Maturin Source: https://github.com/perspective-dev/perspective/blob/master/DEVELOPMENT.md Use this command for an editable install of the Python package using Maturin, facilitating local development. ```bash pnpm -F @perspective-dev/python develop:maturin ``` -------------------------------- ### Build Perspective Project Source: https://github.com/perspective-dev/perspective/blob/master/DEVELOPMENT.md Run this command to build the entire Perspective project. It may prompt you to generate a .perspectiverc configuration file on the first run. ```bash pnpm run build ``` -------------------------------- ### Update Perspective Table with PyArrow Table Source: https://github.com/perspective-dev/perspective/blob/master/docs/md/how_to/python/table_data.md Append data to an existing Perspective Table using a PyArrow Table. Ensure PyArrow is installed. ```python table.update(arrow_table) ``` -------------------------------- ### Connect to ClickHouse and Bind to Viewer Source: https://github.com/perspective-dev/perspective/blob/master/docs/md/how_to/javascript/virtual_server/clickhouse.md Connect to a ClickHouse instance using the `@clickhouse/client-web` library and then create a Perspective virtual server handler. Finally, open a table and load it into a Perspective viewer. ```javascript import perspective from "@perspective-dev/client"; import "@perspective-dev/viewer"; import { createClient } from "@clickhouse/client-web"; // Connect to ClickHouse const clickhouseClient = createClient({ url: "http://localhost:8123", database: "default", }); // Create a Perspective virtual server backed by ClickHouse const handler = perspective.ClickhouseHandler(clickhouseClient); const messageHandler = perspective.createMessageHandler(handler); // Connect a viewer const client = await perspective.worker(messageHandler); const table = await client.open_table("my_table"); document.getElementById("viewer").load(table); ``` -------------------------------- ### Load Perspective Viewer with WebSocket Connection Source: https://github.com/perspective-dev/perspective/blob/master/examples/python-polars-virtual/index.html Import necessary Perspective viewer components and establish a WebSocket connection to a Perspective server. Load the viewer with data from a specified data source. ```javascript import "/node_modules/@perspective-dev/viewer/dist/cdn/perspective-viewer.js"; import "/node_modules/@perspective-dev/viewer-datagrid/dist/cdn/perspective-viewer-datagrid.js"; import "/node_modules/@perspective-dev/viewer-charts/dist/cdn/perspective-viewer-charts.js"; import perspective from "/node_modules/@perspective-dev/client/dist/cdn/perspective.js"; const viewer = document.getElementById("viewer"); // Create a client that expects a Perspective server to accept // Websocket connections at the specified URL. const websocket = await perspective.websocket("ws://localhost:3000/websocket"); viewer.load(websocket); viewer.restore({table: "data_source_one"}) ``` -------------------------------- ### Get Min/Max Values for a Column Source: https://github.com/perspective-dev/perspective/blob/master/docs/md/explanation/view/advanced.md Retrieve the minimum and maximum values for a specified column in the current view. This is useful for setting scales in visualizations. ```javascript const [min, max] = await view.get_min_max("Sales"); ``` ```python min_val, max_val = view.get_min_max("Sales") ``` -------------------------------- ### Initialize Perspective Viewer and Load Data Source: https://github.com/perspective-dev/perspective/blob/master/examples/blocks/src/evictions/index.html Imports necessary Perspective.js components and initializes the worker. It then fetches eviction data, caches it, and loads it into the viewer. ```javascript import "/node_modules/@perspective-dev/viewer/dist/cdn/perspective-viewer.js"; import "/node_modules/@perspective-dev/viewer-datagrid/dist/cdn/perspective-viewer-datagrid.js"; import "/node_modules/@perspective-dev/viewer-charts/dist/cdn/perspective-viewer-charts.js"; import "/node_modules/@perspective-dev/viewer-openlayers/dist/cdn/perspective-viewer-openlayers.js"; import { worker } from "/node_modules/@perspective-dev/client/dist/cdn/perspective.js"; const WORKER = await worker(); const URL = `https://data.sfgov.org/resource/5cei-gny5.csv?$limit=50000`; async function get_evictions() { const arrow = localStorage.getItem(URL); if (arrow !== null) { console.log("Using cached data from localStorage"); try { const buffer = fflate.strToU8(arrow, true); return await WORKER.table(fflate.decompressSync(buffer).buffer); } catch (e) { console.error("Can't load cached data", e); localStorage.clear(); } } console.log("Downloading data from data.sfgov.org"); const resp = await fetch( URL, // "5cei-gny5.csv" // "evictions.all.arrow" ); const csv = await resp.text(); const table = await WORKER.table(csv); (async () => { console.log("Caching data"); const view = await table.view(); const arrow = await view.to_arrow(); try { const x = fflate.compressSync(new Uint8Array(arrow)); const zipped = fflate.strFromU8(x, true); localStorage.setItem(URL, zipped); } catch (e) { console.error("Can't cache data from data.sfgov.org", e); } })(); return table; } async function load() { const el = document.getElementsByTagName("perspective-viewer")[0]; const evictions = get_evictions(); const layout_json = await fetch("layout.json"); const layout = await layout_json.json(); el.load(await evictions); el.restore(layout); } load(); ``` -------------------------------- ### Activate Emscripten Environment Source: https://github.com/perspective-dev/perspective/blob/master/DEVELOPMENT.md Source this script to activate your local Emscripten SDK environment. This is necessary when building the JavaScript library with a local Emscripten installation. ```bash source emsdk/emsdk_env.sh ``` -------------------------------- ### Create Perspective Table from Pandas DataFrame Source: https://github.com/perspective-dev/perspective/blob/master/docs/md/how_to/python/table_data.md Construct a Perspective Table from a Pandas DataFrame. Type support is dictated by `pyarrow.Table.from_pandas`. Ensure Pandas and NumPy are installed. ```python from datetime import date, datetime import numpy as np import pandas as pd import perspective data = pd.DataFrame({ "int": np.arange(100), "float": [i * 1.5 for i in range(100)], "bool": [True for i in range(100)], "date": [date.today() for i in range(100)], "datetime": [datetime.now() for i in range(100)], "string": [str(i) for i in range(100)], }) table = perspective.table(data, index="float") ``` -------------------------------- ### Connect to Server and Load Table Source: https://github.com/perspective-dev/perspective/blob/master/docs/md/explanation/architecture/server_only.md Connects to a Perspective server via WebSocket, opens a table, and loads it into a perspective-viewer element. Ensure the server is running and the table exists. ```javascript const websocket = await perspective.websocket("ws://localhost:8080"); const server_table = await websocket.open_table("my_table"); const viewer = document.createElement("perspective-viewer"); document.body.appendChild(viewer); await viewer.load(server_table); ``` -------------------------------- ### Initialize and Load Perspective Viewer Source: https://github.com/perspective-dev/perspective/blob/master/tools/bench/src/html/index.html Initializes the Perspective Viewer, sets up event listeners for configuration updates, and loads data from a WebSocket. It also saves and restores the viewer's layout using local storage. ```javascript perspective-viewer { position: absolute; top: 0; left: 0; right: 0; bottom: 0; } import "/node_modules/@perspective-dev/viewer/dist/cdn/perspective-viewer.js"; import perspective from "/node_modules/@perspective-dev/client/dist/cdn/perspective.js"; const el = document.getElementsByTagName("perspective-viewer")[0]; el.addEventListener("perspective-config-update", async () => { const config = await el.save(); delete config["table"]; localStorage.setItem("layout", JSON.stringify(config)); }); const websocket = await perspective.websocket("ws://localhost:8081/subscribe"); const table = await websocket.open_table("benchmarks"); const worker = await perspective.worker(); const table2 = await worker.table(await table.view()); el.load(table2); el.restore(JSON.parse(localStorage.getItem("layout"))); ``` -------------------------------- ### Flattening a View to a Table in Rust Source: https://github.com/perspective-dev/perspective/blob/master/docs/md/explanation/view/advanced.md Instantiate a new table from a view in Rust. This demonstrates the basic setup for creating a table from a view, suitable for replication scenarios. ```rust let opts = TableInitOptions::default(); let data = TableData::Update(UpdateData::Csv("x,y\n1,2\n3,4".into())); let table = client.table(data, opts).await?; let view = table.view(None).await?; let table2 = client.table(TableData::View(view)).await?; table.update(data).await?; ```