#dashboard
#basic-dashboard
Kết hợp resource chart và insight bằng dashboard builder để tạo dashboard cơ bản
Thẻ:
basic
Loading...
import { createVBI, VBIChartBuilder, VBIInsightBuilder, VBIDashboardBuilder } from '@visactor/vbi'
import { JsonRender } from '@components'
import { useEffect, useState } from 'react'
export default () => {
const [result, setResult] = useState<any>(null)
const [error, setError] = useState<string | null>(null)
useEffect(() => {
try {
const LocalVBI = createVBI()
const resources = {
charts: {
salesChart: LocalVBI.chart.create({
"connectorId": "demoSupermarket",
"chartType": "bar",
"dimensions": [
{
"field": "province",
"alias": "Tỉnh"
}
],
"measures": [
{
"field": "sales",
"alias": "Doanh số",
"encoding": "xAxis",
"aggregate": {
"func": "sum"
}
}
],
"whereFilter": {
"id": "root",
"op": "and",
"conditions": []
},
"havingFilter": {
"id": "root",
"op": "and",
"conditions": []
},
"theme": "light",
"locale": "vi-VN",
"version": 1
}),
},
insights: {
salesInsight: LocalVBI.insight.create({
"content": "Doanh số khu vực Hoa Đông đang dẫn đầu. Nên tiếp tục theo dõi các khách hàng trọng điểm.",
"version": 0
}),
},
}
const builder = LocalVBI.dashboard.create({
"widgets": [],
"breakpoints": {
"xxl": 1600,
"xl": 1200,
"lg": 996,
"md": 768,
"sm": 480,
"xs": 0
},
"layout": {
"xxl": [],
"xl": [],
"lg": [],
"md": [],
"sm": [],
"xs": []
},
"meta": {
"title": "Dashboard doanh số",
"theme": "light"
},
"version": 0
})
const applyBuilder = (builder: VBIDashboardBuilder, resources: any) => {
builder.chart.add(chart => {
chart
.setChartId(resources.charts.salesChart)
.setTitle('Xu hướng doanh số')
.setDescription('Tổng hợp doanh số theo tỉnh')
.setLayouts({
lg: { x: 0, y: 0, w: 8, h: 6 },
md: { x: 0, y: 0, w: 6, h: 5 }
})
})
builder.insight.add(insight => {
insight
.setInsightId(resources.insights.salesInsight)
.setTitle('Insight chính')
.setLayouts({
lg: { x: 8, y: 0, w: 4, h: 6 },
md: { x: 0, y: 5, w: 6, h: 3 }
})
})
}
applyBuilder(builder, resources)
setResult(builder.build())
} catch (err) {
setError(err instanceof Error ? err.message : String(err))
}
}, [])
if (error) return <JsonRender value={{ error }} />
if (!result) return <div>Loading...</div>
return <JsonRender value={result} />
}#responsive-dashboard-layout
Kết hợp nhiều resource chart và insight, rồi thiết lập layout dashboard responsive cho các breakpoint khác nhau
Thẻ:
layoutresponsiveresources
Loading...
import { createVBI, VBIChartBuilder, VBIInsightBuilder, VBIDashboardBuilder } from '@visactor/vbi'
import { JsonRender } from '@components'
import { useEffect, useState } from 'react'
export default () => {
const [result, setResult] = useState<any>(null)
const [error, setError] = useState<string | null>(null)
useEffect(() => {
try {
const LocalVBI = createVBI()
const resources = {
charts: {
salesChart: LocalVBI.chart.create({
"connectorId": "demoSupermarket",
"chartType": "bar",
"dimensions": [
{
"field": "province",
"alias": "Tỉnh"
}
],
"measures": [
{
"field": "sales",
"alias": "Doanh số",
"encoding": "xAxis",
"aggregate": {
"func": "sum"
}
}
],
"whereFilter": {
"id": "root",
"op": "and",
"conditions": []
},
"havingFilter": {
"id": "root",
"op": "and",
"conditions": []
},
"theme": "light",
"locale": "vi-VN",
"version": 1
}),
profitChart: LocalVBI.chart.create({
"connectorId": "demoSupermarket",
"chartType": "line",
"dimensions": [
{
"field": "order_date",
"alias": "Tháng đặt hàng",
"aggregate": {
"func": "toMonth"
}
}
],
"measures": [
{
"field": "profit",
"alias": "Lợi nhuận",
"encoding": "yAxis",
"aggregate": {
"func": "sum"
}
}
],
"whereFilter": {
"id": "root",
"op": "and",
"conditions": []
},
"havingFilter": {
"id": "root",
"op": "and",
"conditions": []
},
"theme": "light",
"locale": "vi-VN",
"version": 1
}),
},
insights: {
opsInsight: LocalVBI.insight.create({
"content": "Cần quan sát kết hợp xu hướng doanh số và lợi nhuận. Các tháng có lợi nhuận thấp nên được phân tích sâu hơn theo cấu trúc danh mục.",
"version": 0
}),
},
}
const builder = LocalVBI.dashboard.create({
"widgets": [],
"breakpoints": {
"xxl": 1600,
"xl": 1200,
"lg": 996,
"md": 768,
"sm": 480,
"xs": 0
},
"layout": {
"xxl": [],
"xl": [],
"lg": [],
"md": [],
"sm": [],
"xs": []
},
"meta": {
"title": "Dashboard vận hành",
"theme": "dark"
},
"version": 0
})
const applyBuilder = (builder: VBIDashboardBuilder, resources: any) => {
builder.chart.add(chart => {
chart
.setChartId(resources.charts.salesChart)
.setTitle('Doanh số khu vực')
.setDescription('Tổng hợp doanh số theo tỉnh')
.setLayouts({
lg: { x: 0, y: 0, w: 7, h: 5 },
md: { x: 0, y: 0, w: 6, h: 4 },
sm: { x: 0, y: 0, w: 4, h: 4 }
})
})
builder.chart.add(chart => {
chart
.setChartId(resources.charts.profitChart)
.setTitle('Xu hướng lợi nhuận')
.setDescription('Tổng hợp lợi nhuận theo tháng')
.setLayouts({
lg: { x: 7, y: 0, w: 5, h: 5 },
md: { x: 0, y: 4, w: 6, h: 4 },
sm: { x: 0, y: 4, w: 4, h: 4 }
})
})
builder.insight.add(insight => {
insight
.setInsightId(resources.insights.opsInsight)
.setTitle('Insight vận hành')
.setDescription('Giải thích liên hệ giữa doanh số và lợi nhuận')
.setLayouts({
lg: { x: 0, y: 5, w: 12, h: 3 },
md: { x: 0, y: 8, w: 6, h: 3 },
sm: { x: 0, y: 8, w: 4, h: 3 }
})
})
}
applyBuilder(builder, resources)
setResult(builder.build())
} catch (err) {
setError(err instanceof Error ? err.message : String(err))
}
}, [])
if (error) return <JsonRender value={{ error }} />
if (!result) return <div>Loading...</div>
return <JsonRender value={result} />
}#update-and-remove-dashboard-widgets
Thêm nhiều dashboard widget, sau đó cập nhật layout và xóa chart tạm thời
Thẻ:
layoutmutation
Loading...
import { createVBI, VBIChartBuilder, VBIInsightBuilder, VBIDashboardBuilder } from '@visactor/vbi'
import { JsonRender } from '@components'
import { useEffect, useState } from 'react'
export default () => {
const [result, setResult] = useState<any>(null)
const [error, setError] = useState<string | null>(null)
useEffect(() => {
try {
const LocalVBI = createVBI()
const resources = {
charts: {
},
insights: {
},
}
const builder = LocalVBI.dashboard.create({
"widgets": [],
"breakpoints": {
"xxl": 1600,
"xl": 1200,
"lg": 996,
"md": 768,
"sm": 480,
"xs": 0
},
"layout": {
"xxl": [],
"xl": [],
"lg": [],
"md": [],
"sm": [],
"xs": []
},
"meta": {
"title": "",
"theme": "light"
},
"version": 0
})
const applyBuilder = (builder: VBIDashboardBuilder, _resources: any) => {
builder.chart.add(chart => {
chart.setTitle('Chart tạm thời').setLayouts({ lg: { x: 0, y: 0, w: 6, h: 4 } })
})
builder.insight.add(insight => {
insight.setTitle('Insight được giữ lại').setLayouts({ lg: { x: 6, y: 0, w: 6, h: 4 } })
})
const [chartWidget] = builder.chart.toJSON()
const [insightWidget] = builder.insight.toJSON()
builder.chart.update(chartWidget.id, chart => {
chart
.setDescription('Xóa sau khi cập nhật')
.setLayouts({ lg: { x: 0, y: 1, w: 5, h: 3 } })
})
builder.insight.update(insightWidget.id, insight => {
insight.setDescription('Mô tả insight được giữ lại trong dashboard')
})
builder.chart.remove(chartWidget.id)
}
applyBuilder(builder, resources)
setResult(builder.build())
} catch (err) {
setError(err instanceof Error ? err.message : String(err))
}
}, [])
if (error) return <JsonRender value={{ error }} />
if (!result) return <div>Loading...</div>
return <JsonRender value={result} />
}