Интерактивные дашборды Sprucely.io можно встроить в собственный сайт или веб-приложение тремя способами: с помощью стандартного HTML-элемента iframe, путём нативной отрисовки через автономную среду выполнения JavaScript или путём монтирования автономных React-компонентов. iframe настраивается быстрее всего; автономные среды выполнения отрисовывают дашборды непосредственно на странице и позволяют добавлять новые данные во время выполнения. JSON-структура, которую считывают автономные среды выполнения — дашборды, диаграммы и наборы данных, — описана в справочнике формат данных. Об автоматизации дашбордов с помощью ИИ см. раздел MCP API.
Встраивание дашбордов в HTML
Самый простой способ интеграции — использовать стандартный HTML-элемент iframe; он работает на любом сайте и даже на локальных HTML-страницах. Чтобы дашборд загрузился, для него нужно включить общий доступ — в облаке (Cloud) или локально (On-premise). Обратите внимание: локальные (On-premise) дашборды загружаются только тогда, когда обращающийся к ним клиент находится в той же корпоративной сети.
Инструкция:
1) Скопируйте ссылку для встраивания дашборда - на странице Дашборды убедитесь, что для дашборда включён общий доступ, и нажмите значок рядом с этим дашбордом. Зелёный всплывающий баннер сообщит, что ссылка скопирована в буфер обмена. Используйте её, чтобы заменить содержимое атрибута src HTML-элемента iframe ниже.
2) Встройте дашборд с фиксированным размером
<html>
<head>
<title>Sprucely.io Dashboard</title>
</head>
<body>
<h1>Sprucely.io Dashboard</h1>
<iframe src="https://www.sprucely.io/service/dashboards/embed/[userId]/[dashboardId]/"
allow="clipboard-write"
style="height: 500px; width: 700px;"
title="Sprucely.io Dashboard"></iframe>
</body>
</html>(или) Встройте дашборд с динамической шириной - Автоматически изменяет размер дашборда в зависимости от ширины родительского документа
Вы можете использовать CSS-параметр aspect-ratio, чтобы автоматически пересчитывать высоту на основе ширины.
<html>
<head>
<title>Sprucely.io Dashboard</title>
</head>
<body>
<h1>Sprucely.io Dashboard</h1>
<iframe src="https://www.sprucely.io/service/dashboards/embed/[userId]/[dashboardId]/"
allow="clipboard-write"
scrolling="no"
style="width: 100%; aspect-ratio: 1.5; border: none;"
title="Sprucely.io Dashboard"></iframe>
</body>
</html>3) Другие полезные параметры встраивания
Вы можете добавлять собственные стилевые изменения в блок style элемента iframe, чтобы настроить внешний вид фрейма. Эти параметры соответствуют стандартным рекомендациям HTML и CSS. В примере ниже вокруг дашборда добавлена серая рамка:
<html>
<head>
<title>Sprucely.io Dashboard</title>
</head>
<body>
<h1>Sprucely.io Dashboard</h1>
<iframe src="https://www.sprucely.io/service/dashboards/embed/[userId]/[dashboardId]/"
allow="clipboard-write"
style="height: 100%; width: 100%; border: 2px solid grey;"
title="Sprucely.io Dashboard"></iframe>
</body>
</html>Встраивание с помощью автономного JavaScript
Автономная среда выполнения отрисовывает дашборды непосредственно на странице - без iframe. Ваши данные загружаются во внутрибраузерную базу данных и отображаются в виде полностью интерактивных диаграмм; среда выполнения обращается к Sprucely.io только для проверки вашего токена доступа.
Инструкция:
1) Создайте токен доступа - в разделе Токены доступа вашего профиля создайте токен доступа для источника, с которого обслуживаются ваши страницы (например, https://www.yourdomain.com). Перед отрисовкой среда выполнения проверяет, что источник встраивающей страницы совпадает с токеном.
2) Загрузите среду выполнения и отрисуйте дашборд - добавьте скрипт среды выполнения на свою страницу, один раз подключите внутрибраузерную базу данных с помощью sprucely_db, а затем отрисуйте каждый дашборд с помощью sprucely_create. Полная страница ниже также подключает кнопку, которая добавляет дополнительные строки:
<html>
<head>
<title>Orders Dashboard</title>
</head>
<body>
<div id="database"></div>
<div id="orders_dashboard"></div>
<button onclick="addRows()">Add rows</button>
<script src="https://www.sprucely.io/cross-origin/sprucely-runtime.min.js"></script>
<script>
const data = {
name: "Orders",
headers: ["region", "amount", "items"],
types: ["VARCHAR", "FLOAT", "INTEGER"],
entries: [
["North", 120.50, 2],
["South", 89.95, 1],
["North", 432.00, 5],
["South", 74.50, 1]
]
};
const dashboard = {
config: {
type: "dashboard",
style: {
widget: {
color: "#667FFF",
backgroundColor: "#0C0B29",
primaryColor: "#01EEAE",
primaryColorSubtle: "#C70584",
secondaryColor: "#2C2B49"
}
}
},
data: {
type: "dash",
children: [
{
type: "dash_stacker_hor",
children: [
{ type: "dash_chart", datasetId: "Orders", x: "region", chartType: "bar", dataFunction: "count" },
{ type: "dash_chart", datasetId: "Orders", x: "amount", y: "items", chartType: "hexbin", dataFunction: "count" }
]
}
]
}
};
sprucely_db({
id: "database",
host: "https://www.yourdomain.com",
accessToken: "YOUR_ACCESS_TOKEN"
});
sprucely_create({ id: "orders_dashboard", dashboard, data });
function addRows() {
sprucely_add({
name: "Orders",
headers: ["region", "amount", "items"],
types: ["VARCHAR", "FLOAT", "INTEGER"],
entries: [
["East", 310.40, 3],
["West", 129.95, 1]
]
});
}
</script>
</body>
</html>3) Добавляйте данные во время выполнения - в любой момент вызывайте sprucely_add с дополнительными строками. Каждый дашборд, использующий этот набор данных, обновится автоматически:
sprucely_add({
name: "Orders",
headers: ["region", "amount", "items"],
types: ["VARCHAR", "FLOAT", "INTEGER"],
entries: [
["East", 310.40, 3],
["West", 129.95, 1]
]
});Справочник функций
sprucely_db({ id, host, accessToken })- подключает внутрибраузерную базу данных и проверяет ваш токен доступа по источнику страницы. Отрисовывает баннер статуса в элементе с указанным id. Вызывайте один раз на странице, перед созданием дашбордов.sprucely_create({ id, dashboard, data })- отрисовывает один дашборд в элементе с указанным id. Параметр dashboard задаёт макет и оформление; data содержит набор данных с его именем, заголовками, типами столбцов (VARCHAR,INTEGER,FLOATилиTIMESTAMP) и строками - см. справочник формат данных.sprucely_add(data)- добавляет строки к набору данных, имя которого совпадает с уже загруженным набором данных, а затем обновляет все дашборды, которые его используют.
Встраивание с помощью автономного React
Если ваш сайт построен на React, вы можете отрисовывать дашборды в виде компонентов вместо ручной загрузки скрипта. Компоненты используют те же токены доступа, определения дашбордов и формат наборов данных, что и автономная среда выполнения JavaScript.
Инструкция:
1) Создайте токен доступа - как и для автономного JavaScript, создайте токен доступа для источника вашего сайта в разделе Токены доступа вашего профиля.
2) Отрисуйте компоненты дашборда - получите среду выполнения по адресу https://www.sprucely.io/cross-origin/sprucely-runtime.min.cjs.js и разместите её в своём проекте. Монтируйте один компонент Sprucely.Database на страницу и один компонент Sprucely.Dashboard на каждый дашборд. Дашборды показывают индикатор загрузки, пока база данных не проверит токен доступа, а затем отрисовываются. Полное приложение ниже отрисовывает два дашборда из отдельных наборов данных и через пять секунд добавляет новые строки к первому:
// Get https://www.sprucely.io/cross-origin/sprucely-runtime.min.cjs.js
// and place it in your project, next to this file.
import React, { useEffect } from "react";
import { createRoot } from "react-dom/client";
import Sprucely, { sprucely_add } from "./sprucely-runtime.min.cjs.js";
const style = {
widget: {
color: "#667FFF",
backgroundColor: "#0C0B29",
primaryColor: "#01EEAE",
primaryColorSubtle: "#C70584",
secondaryColor: "#2C2B49"
}
};
const orders = {
name: "Orders",
headers: ["region", "amount", "items"],
types: ["VARCHAR", "FLOAT", "INTEGER"],
entries: [
["North", 120.50, 2],
["South", 89.95, 1],
["North", 432.00, 5],
["South", 74.50, 1]
]
};
const returns = {
name: "Returns",
headers: ["reason", "amount", "days"],
types: ["VARCHAR", "FLOAT", "INTEGER"],
entries: [
["Damaged", 45.00, 3],
["Late", 12.50, 8],
["Changed", 99.90, 2]
]
};
const moreOrders = {
name: "Orders",
headers: ["region", "amount", "items"],
types: ["VARCHAR", "FLOAT", "INTEGER"],
entries: [
["East", 310.40, 3],
["West", 129.95, 1]
]
};
const ordersDashboard = {
config: { type: "dashboard", style },
data: {
type: "dash",
children: [
{
type: "dash_stacker_hor",
children: [
{ type: "dash_chart", datasetId: "Orders", x: "region", chartType: "bar", dataFunction: "count" },
{ type: "dash_chart", datasetId: "Orders", x: "amount", y: "items", chartType: "hexbin", dataFunction: "count" }
]
}
]
}
};
const returnsDashboard = {
config: { type: "dashboard", style },
data: {
type: "dash",
children: [
{
type: "dash_stacker_hor",
children: [
{ type: "dash_chart", datasetId: "Returns", x: "amount", y: "days", d: "amount", r: "days", chartType: "dot", dataFunction: "average" }
]
}
]
}
};
const App = () => {
useEffect(() => {
const timer = setTimeout(() => { sprucely_add(moreOrders); }, 5000);
return () => clearTimeout(timer);
}, []);
return (
<>
<Sprucely.Database host="https://www.yourdomain.com" accessToken="YOUR_ACCESS_TOKEN" />
<Sprucely.Dashboard id="orders_dashboard" dashboard={ordersDashboard} data={orders} />
<Sprucely.Dashboard id="returns_dashboard" dashboard={returnsDashboard} data={returns} />
</>
);
};
createRoot(document.getElementById("root")).render(<App />);Обслуживание с помощью краткосрочных токенов
Токен доступа, который вы создали выше, — долгоживущий, и он должен оставаться секретом на стороне сервера. Если встраивающие страницы обслуживает ваш собственный бэкенд — а не страница вовсе без бэкенда, — вам не нужно вообще размещать этот долгоживущий токен на странице: ваш бэкенд может обменять его напрямую, по схеме «сервер—сервер», на краткосрочный (15-минутный) токен отрисовки непосредственно перед отдачей каждой страницы, и до браузера доходит только этот токен отрисовки. Токен отрисовки, который посетитель извлечёт со страницы, полезен лишь считанные минуты, а не бессрочно.
Инструкция:
1) Обменяйте токен доступа на токен отрисовки - вызовите со своего бэкенда POST https://www.sprucely.io/api/auth/render_token, передав токен доступа как bearer-учётные данные. В ответе приходит новый токен, привязанный к нему хост и время жизни в секундах:
// On your server, immediately before serving each embedding page:
const response = await fetch("https://www.sprucely.io/api/auth/render_token", {
method: "POST",
headers: { Authorization: "Bearer " + process.env.SPRUCELY_ACCESS_TOKEN }
});
const { token, expires_in } = await response.json(); // expires_in: 900 (15 minutes)
// Send only the render token to the browser - never the long-lived access
// token itself:
res.send(`
<script src="https://www.sprucely.io/cross-origin/sprucely-runtime.min.js"></script>
<script>
sprucely_db({
id: "database",
host: "https://www.yourdomain.com",
accessToken: "${token}"
});
</script>
`);2) Передайте токен отрисовки в браузер - используйте его точно так же, как токен доступа, при вызове sprucely_db или монтировании Sprucely.Database. Повторяйте обмен перед обслуживанием каждой страницы (или по таймеру, если вы кешируете отрисованную страницу), чтобы в браузер никогда не попадал токен, действительный дольше 15 минут.
Справочник функций
POST /api/auth/render_token- обменивает действительный токен доступа, переданный какAuthorization: Bearer <token>, на токен отрисовки. Возвращает{ token, host, expires_in }, гдеexpires_inвсегда равно 900 секундам. Токен отрисовки нельзя обменять на другой токен отрисовки - запросить его может только долгоживущий токен доступа.
Настройки безопасности
Если на вашем сайте применяется политика безопасности контента (CSP), для описанных выше интеграций автономного JavaScript и React потребуется разрешить несколько источников, прежде чем дашборды смогут загрузиться - среда выполнения загружает свой скрипт с Sprucely.io, открывает внутрибраузерную базу данных на основе WebAssembly и проверяет ваш токен доступа через наш API, и каждому из этих действий требуется явное разрешение CSP. Если ваш сайт не использует CSP, этот раздел можно пропустить.
Добавьте следующие источники в существующую политику - это директивы для объединения с уже имеющимися, а не полная политика, заменяющая то, что у вас уже есть:
script-src 'self' https://www.sprucely.io 'wasm-unsafe-eval';
connect-src 'self' https://www.sprucely.io;
worker-src 'self' blob: https://www.sprucely.io;Назначение каждой директивы:
script-src-https://www.sprucely.ioзагружает скрипт среды выполнения.'wasm-unsafe-eval'необходим для компиляции и запуска внутрибраузерной базы данных, построенной на WebAssembly.connect-src- кhttps://www.sprucely.ioвыполняется обращение для проверки токена доступа и загрузки файлов WebAssembly и воркера базы данных.worker-src- внутрибраузерная база данных выполняет запросы в фоновом потоке, созданном из URL видаblob:.
Ничего из перечисленного не требует 'unsafe-inline' - самой среде выполнения Sprucely он никогда не нужен. Если вы храните собственные определения дашборда и набора данных во встроенном теге <script>, как в примере автономного JavaScript выше, или ваша страница использует встроенные стили, добавьте 'unsafe-inline' в script-src или style-src, либо рассмотрите использование CSP-нонсов.