piveau-preview-plugin
v2.3.3
Published
A Vue 3 CSV preview tool with tabular, numerical, and categorical views
Readme
piveau preview plugin
A Vue 3 component library for previewing and visualizing tabular data (CSV, TSV, XLSX, XLS, ODS) from remote URLs. Built for the Piveau Hub Data Preview API.
Features
- Table View — Paginated, filterable data grid (AG Grid)
- Numerical View — Line and bar charts for numerical columns (Chart.js)
- Categorical View — Bar and doughnut charts for categorical data
- AI View — Chat-powered Vega-Lite chart generation via a backend proxy (API key stays server-side)
- Smart Launcher — Button-triggered preview (inline or modal) for distribution lists
- Auto-detection — Automatic column typing and default chart selection
Installation
npm install piveau-preview-pluginPeer Dependencies
| Package | Required | Notes |
|---------|----------|-------|
| vue | Yes | ^3.4.0 |
All other runtime dependencies are bundled as package dependencies and are installed automatically with piveau-preview-plugin.
Install:
npm install piveau-preview-plugin vueVue 3 Quick Start
Register Chart.js components in your app entry:
// main.ts
import { createApp } from 'vue'
import App from './App.vue'
import { registerCharts } from 'piveau-preview-plugin'
import 'piveau-preview-plugin/style.css'
import 'ag-grid-community/styles/ag-grid.css'
import 'ag-grid-community/styles/ag-theme-quartz.css'
registerCharts()
createApp(App).mount('#app')Use the preview component:
<template>
<DistributionVisualisation
downloadUrl="https://example.com/data.csv"
fileFormat="csv"
title="My Dataset"
:showAiTab="false"
/>
</template>
<script setup lang="ts">
import { DistributionVisualisation } from 'piveau-preview-plugin'
</script>With AI Chat (Secure)
The AI tab generates Vega-Lite charts from natural language prompts. API credentials are not passed through the frontend — instead, the component calls your backend service, which proxies to the LLM:
<template>
<DistributionVisualisation
downloadUrl="https://example.com/data.csv"
fileFormat="csv"
:showAiTab="true"
apiBaseUrl="https://your-backend.example.com/api/preview"
/>
</template>Your backend should expose an endpoint at {apiBaseUrl}/ai/chat that forwards messages to an OpenAI-compatible API using a server-side API key (see Backend Proxy below).
Nuxt 3 Integration
1. Install dependencies
npm install piveau-preview-pluginNuxt 3 bringt Vue bereits mit. Eine separate Installation von Vue ist dort nicht notwendig.
2. Add CSS to nuxt.config.ts
export default defineNuxtConfig({
css: [
'piveau-preview-plugin/style.css',
'ag-grid-community/styles/ag-grid.css',
'ag-grid-community/styles/ag-theme-quartz.css',
],
})3. Register Chart.js in a plugin
// plugins/charts.client.ts
import { registerCharts } from 'piveau-preview-plugin'
export default defineNuxtPlugin(() => {
registerCharts()
})4. Use the component
<!-- pages/preview.vue -->
<template>
<ClientOnly>
<DistributionVisualisation
:downloadUrl="url"
fileFormat="csv"
title="Data Preview"
/>
</ClientOnly>
</template>
<script setup lang="ts">
const url = ref('https://example.com/data.csv')
</script>5. (Optional) Backend Proxy for AI Chat
Create a server route that proxies AI requests. The API key stays server-side:
// server/api/ai-chat.post.ts
export default defineEventHandler(async (event) => {
const body = await readBody(event)
const response = await $fetch('https://api.openai.com/v1/chat/completions', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${process.env.AI_API_KEY}`,
},
body,
})
return response
})Then set apiBaseUrl to your Nuxt app URL (e.g., http://localhost:3000/api) — the AI tab calls {apiBaseUrl}/ai/chat automatically.
Components
DistributionVisualisation
The main preview component with all four tabs.
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| downloadUrl | string | — | URL to the data file |
| fileFormat | 'csv' \| 'tsv' \| 'xlsx' \| 'xls' \| 'ods' | — | File format |
| compressFormat | string | — | Compression MIME type |
| title | string | — | Chart title |
| datasetTitle | string | — | Heading shown above the preview |
| datasetDescription | string | — | Subtext below the title |
| showAiTab | boolean | true | Shows or hides the AI Chat beta tab |
| apiBaseUrl | string | — | Backend API base URL (used for data preview and AI proxy) |
| primaryColor | string | '#001D85' | Primary theme color for accents and active states |
| buttonBorderRadius | string | '6px' | Border radius used by buttons/interactive controls |
| errorBackgroundColor | string | '#fafafa' | Background color for the error alert box |
DistributionPreviewLauncher
A button that opens the preview (inline or modal).
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| downloadUrl | string | — | URL to the data file |
| fileFormat | string | — | File format |
| compressFormat | string | — | Compression MIME type |
| title | string | — | Chart title |
| datasetTitle | string | — | Heading shown above the preview |
| datasetDescription | string | — | Subtext below the title |
| showAiTab | boolean | true | Pass-through for showing or hiding the AI Chat beta tab |
| apiBaseUrl | string | — | Preview API endpoint, required |
| buttonLabel | string | 'Preview' | Button text |
| variant | 'inline' \| 'modal' | 'inline' | Display mode |
| primaryColor | string | '#001D85' | Primary theme color for launcher + preview accents |
| buttonBorderRadius | string | '6px' | Border radius used by launcher and preview buttons |
| errorBackgroundColor | string | '#fafafa' | Background color for the preview error alert box |
<DistributionPreviewLauncher
:downloadUrl="dist.url"
fileFormat="csv"
variant="modal"
datasetTitle="Traffic Data"
datasetDescription="Monthly traffic counts across all measuring stations"
/>Slots
DistributionPreviewLauncher exposes a #button slot for custom trigger elements:
<DistributionPreviewLauncher :downloadUrl="url" fileFormat="csv">
<template #button="{ toggle, isOpen }">
<button @click="toggle" class="custom-btn">
{{ isOpen ? 'Close' : 'Open Preview' }}
</button>
</template>
</DistributionPreviewLauncher>Composable
import { useDataPreview } from 'piveau-preview-plugin'
const { loading, error, data, fetchPreview } = useDataPreview('https://custom-api.example.com')
await fetchPreview('https://example.com/data.csv', 'csv')AI Chat
The AI tab lets users describe charts in natural language. By default it uses the backend proxy at {apiBaseUrl}/ai/chat. The composable is also available standalone with two modes:
Backend Proxy (Secure)
import { useAiChat } from 'piveau-preview-plugin'
const chat = useAiChat({
baseUrl: 'https://your-backend.example.com/api/preview', // calls {baseUrl}/ai/chat
model: 'gpt-4o',
maxRequests: 20,
})Direct LLM (for testing)
import { useAiChat } from 'piveau-preview-plugin'
const chat = useAiChat({
apiUrl: 'https://api.openai.com/v1/chat/completions',
apiKey: 'sk-...', // WARNING: exposed client-side
model: 'gpt-4o',
maxRequests: 20,
})The AI returns structured JSON configs that are compiled into full Vega-Lite specs client-side. Configure rate limits and cooldowns via the options object.
Backend Proxy
For production use, your backend should expose an endpoint at POST /ai/chat. The component sends requests in this format:
{
"messages": [
{ "role": "system", "content": "..." },
{ "role": "user", "content": "Show me sales over time" }
],
"model": "gpt-4o",
"temperature": 0.3,
"max_tokens": 2000
}Your backend reads an LLM API key from a server-side environment variable, forwards the request, and returns the response. The composable accepts both OpenAI-style (choices[0].message.content) and simplified (content) response formats.
Development
# Install all dependencies
npm install
cd demo && npm install
# Start the demo
npm run devRelease
# Validate package before publishing
npm run release:dry-run
# Publish a patch/minor/major release
npm run release:patch
npm run release:minor
npm run release:majorAfter publish, push commit and tag:
git push
git push --tagsAPI Response Format
The preview API returns a JSON report with the following structure:
{
"default_view_options": {
"default_view": "table",
"default_numerical_chart": "line",
"default_categorical_chart": "bar",
"default_axes": {
"numerical_chart": { "x": "date", "y": ["value"] },
"categorical_chart": "category"
}
},
"labels": {
"all_labels": ["date", "value", "category"],
"numerical_labels": ["value"],
"categorical_labels": ["category"],
"time_labels": ["date"]
},
"data": [...],
"categorized": [...]
}License
MIT
