Skip to content

Instantly share code, notes, and snippets.

@texodus
Forked from timkpaine/.block
Last active August 10, 2022 19:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save texodus/eb151fdd9f98bde987538cbc20e003f6 to your computer and use it in GitHub Desktop.
Save texodus/eb151fdd9f98bde987538cbc20e003f6 to your computer and use it in GitHub Desktop.
Perspective / IEX Cloud Example
license: apache-2.0
perspective-workspace {
flex: 1
}
#container {
flex: 1;
display: flex;
}
input {
margin: 12px 8px 4px 8px;
padding: 8px;
font-size: 24px;
flex: 0 1;
text-transform: uppercase;
max-width: 600px;
}
perspective-viewer-datagrid regular-table {
overflow-x: hidden;
}
perspective-viewer table {
white-space: nowrap;
}
perspective-viewer tr,
perspective-viewer thead,
perspective-viewer tbody {
display: inline-block;
}
perspective-viewer th,
perspective-viewer td {
display: block;
}
body {
background-color: #eee;
display: flex;
margin: 0;
flex-direction: column;
position: absolute;
top: 0;
left:0;
right: 0;
bottom: 0;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no" />
<script src="https://cdn.jsdelivr.net/npm/@finos/perspective@latest"></script>
<script src="https://cdn.jsdelivr.net/npm/@finos/perspective-workspace@latest"></script>
<script src="https://cdn.jsdelivr.net/npm/@finos/perspective-viewer-datagrid@latest"></script>
<script src="https://cdn.jsdelivr.net/npm/@finos/perspective-viewer-d3fc@latest"></script>
<link rel='stylesheet' href="index.css">
<link rel='stylesheet' crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@finos/perspective-workspace/dist/css/material.css">
<script src="index.js"></script>
</head>
<body>
<input id="ticker" type="text" value="JPM"></input>
<div id="container">
<perspective-workspace id="workspace">
<perspective-viewer table="query1"></perspective-viewer>
<perspective-viewer table="query2"></perspective-viewer>
<perspective-viewer table="query3"></perspective-viewer>
</perspective-workspace>
</div>
</body>
</html>
const PUB_TOKEN = "Tpk_ecc89ddf30a611e9958142010a80043c";
const IEX_URL = "https://sandbox.iexapis.com/beta/stock/";
const QUERY1 = "/chart?token=" + PUB_TOKEN;
const QUERY2 = "/stats?token=" + PUB_TOKEN;
const QUERY3 = "/balance-sheet?token=" + PUB_TOKEN;
const worker = perspective.shared_worker();
const TABLES = new Map();
async function run(input, string, wrap = false, index = null) {
const req = await fetch(IEX_URL + input.value + string);
let data = await req.json();
if (index) {
data = data[index];
}
if (wrap) {
data = [data];
}
let table;
if (TABLES.has(string)) {
table = TABLES.get(string);
table.clear();
table.update(data);
} else {
table = await worker.table(data);
TABLES.set(string, table);
}
return table;
}
async function get_layout() {
const req = await fetch("layout.json");
const json = await req.json();
return json;
}
window.addEventListener("DOMContentLoaded", async function () {
const workspace = document.getElementsByTagName("perspective-workspace")[0];
const input = document.getElementById("ticker");
input.addEventListener("keydown", async (ev) => {
input.style.color = "inherit";
if (ev.keyCode === 13) {
try {
await run(input, QUERY1);
await run(input, QUERY2, true);
await run(input, QUERY3, false, "balancesheet");
} catch (e) {
input.style.color = "red";
}
}
});
workspace.addTable("query1", run(input, QUERY1));
workspace.addTable("query2", run(input, QUERY2, true));
workspace.addTable("query3", run(input, QUERY3, false, "balancesheet"));
customElements.get("perspective-viewer-datagrid").prototype.virtual_mode =
"none";
const to_span = (x) => `<span style='color:#666'>${x}</span>`;
workspace.addEventListener("perspective-datagrid-after-update", (event) => {
const form = new Intl.NumberFormat([], {});
const datagrid = event.detail;
for (const td of datagrid.get_tds()) {
const metadata = datagrid.get_meta(td);
if (metadata.column.endsWith("Percent")) {
td.innerHTML =
form.format(Math.round(metadata.value * 100)) +
to_span(" %");
} else if (
metadata.type === "float" &&
(metadata.value < -1000000 || metadata.value > 1000000)
) {
td.innerHTML =
form.format(Math.round(metadata.value / 1000000)) +
to_span(" mm");
}
}
});
const json = await get_layout();
workspace.restore(json);
});
{
"sizes": [1],
"detail": {
"main": {
"type": "split-area",
"orientation": "horizontal",
"children": [
{
"type": "tab-area",
"widgets": [
"PERSPECTIVE_GENERATED_ID_1",
"PERSPECTIVE_GENERATED_ID_2"
],
"currentIndex": 0
},
{
"type": "tab-area",
"widgets": [
"PERSPECTIVE_GENERATED_ID_5",
"PERSPECTIVE_GENERATED_ID_3"
],
"currentIndex": 0
}
],
"sizes": [0.4, 0.6]
}
},
"mode": "globalFilters",
"viewers": {
"PERSPECTIVE_GENERATED_ID_1": {
"plugin": "datagrid",
"columns": [
"companyName",
"nextDividendDate",
"nextEarningsDate",
"exDividendDate",
"week52change",
"week52high",
"week52low",
"marketcap",
"employees",
"day200MovingAvg",
"day50MovingAvg",
"float",
"avg10Volume",
"avg30Volume",
"ttmEPS",
"ttmDividendRate",
"sharesOutstanding",
"maxChangePercent",
"year5ChangePercent",
"year2ChangePercent",
"year1ChangePercent",
"ytdChangePercent",
"month6ChangePercent",
"month3ChangePercent",
"month1ChangePercent",
"day30ChangePercent",
"day5ChangePercent",
"dividendYield",
"peRatio",
"beta"
],
"master": false,
"name": "Reference",
"table": "query2",
"linked": false
},
"PERSPECTIVE_GENERATED_ID_2": {
"plugin": "datagrid",
"columns": [
"reportDate",
"fiscalDate",
"currency",
"currentCash",
"shortTermInvestments",
"receivables",
"inventory",
"otherCurrentAssets",
"currentAssets",
"longTermInvestments",
"propertyPlantEquipment",
"goodwill",
"intangibleAssets",
"otherAssets",
"totalAssets",
"accountsPayable",
"currentLongTermDebt",
"otherCurrentLiabilities",
"totalCurrentLiabilities",
"longTermDebt",
"otherLiabilities",
"minorityInterest",
"totalLiabilities",
"commonStock",
"retainedEarnings",
"treasuryStock",
"capitalSurplus",
"shareholderEquity",
"netTangibleAssets"
],
"master": false,
"name": "Balance Sheet",
"table": "query3",
"linked": false
},
"PERSPECTIVE_GENERATED_ID_5": {
"plugin": "Candlestick",
"columns": ["open", "close", "high", "low"],
"group_by": ["date"],
"plugin_config": {
"realValues": ["open", "close", "high", "low"]
},
"master": false,
"name": "Px",
"table": "query1",
"linked": false
},
"PERSPECTIVE_GENERATED_ID_3": {
"plugin": "Y Bar",
"columns": ["uVolume"],
"plugin_config": {
"realValues": ["uVolume"]
},
"master": false,
"name": "Volume",
"table": "query1",
"linked": false
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment