Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,8 @@ const records = [
const table = new VTable.PivotChart({
container: document.getElementById('tableContainer'),
records,
rows: [
{ dimensionKey: 'region', title: '区域', width: 100 }
],
columns: [
{ dimensionKey: 'product', title: '产品' }
],
rows: [{ dimensionKey: 'region', title: '区域', width: 100 }],
columns: [{ dimensionKey: 'product', title: '产品' }],
indicators: [
{
indicatorKey: 'sales',
Expand Down Expand Up @@ -65,12 +61,8 @@ const table = new VTable.PivotChart({
const table = new VTable.PivotChart({
container: document.getElementById('tableContainer'),
records: monthlyData,
rows: [
{ dimensionKey: 'category', title: '品类', width: 100 }
],
columns: [
{ dimensionKey: 'month', title: '月份' }
],
rows: [{ dimensionKey: 'category', title: '品类', width: 100 }],
columns: [{ dimensionKey: 'month', title: '月份' }],
indicators: [
{
indicatorKey: 'sales',
Expand Down Expand Up @@ -147,16 +139,52 @@ const table = new VTable.PivotChart({
}
}
],
chartDimensionLinkage: true // 跨单元格维度联动高亮
chartDimensionLinkage: true // 跨单元格维度联动高亮
});

// 监听图例事件
table.on('legend_item_click', (args) => {
table.on('legend_item_click', args => {
console.log('图例点击:', args);
});
```

## 4. 迷你图 + 进度条混用
## 4. PivotChart records 对象格式(分指标分组时的注意事项)

```javascript
// 当 records 是对象格式时,key 必须与每个 indicator 的 indicatorKey 严格一致
// 否则图表只渲染轴,不渲染柱/折线等图形元素

const table = new VTable.PivotChart({
container: document.getElementById('tableContainer'),
indicatorsAsCol: false,
columnTree: [],
rowTree: [],
rows: [],
columns: [],
indicators: [
{ indicatorKey: 'METRIC_A', cellType: 'chart', chartModule: 'vchart',
chartSpec: { type: 'bar', xField: 'date', yField: 'value' } },
{ indicatorKey: 'METRIC_B', cellType: 'chart', chartModule: 'vchart',
chartSpec: { type: 'bar', xField: 'date', yField: 'count' } }
],
// ✅ 正确:records 的 key 与 indicatorKey 完全一致
records: {
'METRIC_A': [ { date: '2024-01', value: 100 }, ... ],
'METRIC_B': [ { date: '2024-01', count: 50 }, ... ]
}
// ❌ 错误示例(会导致图表无数据):
// records: { 'METRICA': [...], 'METRICB': [...] } // 缺少下划线
});
```

**副作用对照表:**

| 配置 | 现象 |
| -------------------------- | ----------------------------- |
| records key = indicatorKey | ✅ 柱/线等图形正常渲染 |
| records key ≠ indicatorKey | ❌ 只渲染坐标轴,图形区域空白 |

## 5. 迷你图 + 进度条混用

```javascript
// PivotTable 中直接使用 sparkline 和 progressbar(不需要 PivotChart)
Expand Down Expand Up @@ -187,7 +215,7 @@ const table = new VTable.PivotTable({
min: 0,
max: 100,
style: {
barColor: (args) => args.dataValue >= 80 ? '#52c41a' : args.dataValue >= 50 ? '#faad14' : '#ff4d4f'
barColor: args => (args.dataValue >= 80 ? '#52c41a' : args.dataValue >= 50 ? '#faad14' : '#ff4d4f')
}
}
]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ table.setRecords(newRecords);

// 增删改
table.addRecord({ id: 3, name: 'Charlie', age: 28 });
table.addRecords([record1, record2], 0); // 在索引0处插入
table.deleteRecords([0, 2]); // 删除第0、2条
table.addRecords([record1, record2], 0); // 在索引0处插入
table.deleteRecords([0, 2]); // 删除第0、2条
table.updateRecords([updatedRecord], [1]); // 更新第1条
```

Expand Down Expand Up @@ -59,16 +59,24 @@ const table = new ListTable({

```typescript
// 1. 简单字段名
{ field: 'name' }
{
field: 'name';
}

// 2. 嵌套字段(点号分隔)
{ field: 'address.city' }
{
field: 'address.city';
}

// 3. 数组路径
{ field: ['address', 'city'] }
{
field: ['address', 'city'];
}

// 4. 数字索引(数据为数组时)
{ field: 0 }
{
field: 0;
}
```

### fieldFormat — 格式化显示
Expand Down Expand Up @@ -100,8 +108,8 @@ const table = new ListTable({
field: 'name',
title: '姓名',
sort: (a, b, order) => {
return order === 'asc'
? a.localeCompare(b, 'zh')
return order === 'asc'
? a.localeCompare(b, 'zh')
: b.localeCompare(a, 'zh');
}
}
Expand Down Expand Up @@ -129,7 +137,7 @@ table.updateFilterRules([
// 自定义过滤函数
table.updateFilterRules([
{
filterFunc: (record) => record.age > 20
filterFunc: record => record.age > 20
}
]);

Expand Down Expand Up @@ -160,8 +168,8 @@ const filtered = table.getFilteredRecords();
```typescript
const table = new ListTable({
pagination: {
perPageCount: 20, // 每页 20 条
currentPage: 1 // 当前第 1 页
perPageCount: 20, // 每页 20 条
currentPage: 1 // 当前第 1 页
}
});

Expand All @@ -177,19 +185,23 @@ table.updatePagination({ currentPage: 2 });

```typescript
const table = new PivotTable({
records: flatData, // 平坦的原始数据
records: flatData, // 平坦的原始数据
rows: ['region', 'city'],
columns: ['category', 'subCategory'],
indicators: [{
indicatorKey: 'sales',
title: '销售额'
}],
dataConfig: {
aggregationRules: [{
indicators: [
{
indicatorKey: 'sales',
field: 'sales',
aggregationType: VTable.AggregationType.SUM
}]
title: '销售额'
}
],
dataConfig: {
aggregationRules: [
{
indicatorKey: 'sales',
field: 'sales',
aggregationType: VTable.AggregationType.SUM
}
]
}
});
```
Expand Down Expand Up @@ -234,36 +246,74 @@ const table = new PivotChart({
records: flatData,
rows: ['region'],
columns: ['category'],
indicators: [{
indicatorKey: 'sales',
title: '销售额',
cellType: 'chart',
chartModule: 'vchart',
chartSpec: {
type: 'bar',
xField: ['category'],
yField: 'sales'
indicators: [
{
indicatorKey: 'sales',
title: '销售额',
cellType: 'chart',
chartModule: 'vchart',
chartSpec: {
type: 'bar',
xField: ['category'],
yField: 'sales'
}
}
}]
]
});
```

注意:PivotChart 内部自动开启数据分析,不需要手动配置 `dataConfig`。

### PivotChart records 对象格式(按指标分组)

当数据已经按指标分好组时,`records` 可以是对象格式(key 为指标分组名):

```typescript
const table = new PivotChart({
indicators: [
{ indicatorKey: 'sales', cellType: 'chart', ... },
{ indicatorKey: 'profit', cellType: 'chart', ... }
],
// records 的 key 必须与 indicators[i].indicatorKey 严格一致
records: {
'sales': [ { region: '华东', sales: 1200, ... }, ... ],
'profit': [ { region: '华东', profit: 300, ... }, ... ]
}
});
```

> ⚠️ **关键规则:records 对象格式时,key 必须与 `indicatorKey` 完全一致(大小写、下划线均须匹配)。**
>
> 内部处理逻辑(参见 `dataset.ts` `processRecords`):当 `records` 是对象时,每个 key 会作为 `assignedIndicatorKey` 传入,与 `indicators[i].indicatorKey` 进行严格字符串比较。key 不匹配时,该组数据被忽略,对应图表单元格显示为空白(只渲染轴,不渲染柱/线等图形元素)。

**常见错误示例:**

```typescript
// ❌ 错误:key 与 indicatorKey 不一致
indicators: [{ indicatorKey: 'INDICATOR_KEY_0', ... }]
records: { 'INDICATORKEY0': [...] } // 下划线缺失 → 数据丢失

// ✅ 正确:key 与 indicatorKey 完全相同
indicators: [{ indicatorKey: 'INDICATOR_KEY_0', ... }]
records: { 'INDICATOR_KEY_0': [...] }
```

> 注意:`columnTree: []` / `rowTree: []` 为空数组是合法的,PivotChart 会在内部自动用指标节点补全,无需手动添加虚拟节点。

## 四、数据更新最佳实践

```typescript
// ✅ 推荐:使用 API 更新
table.setRecords(newRecords); // 全量更新
table.addRecords(newRecords); // 增量添加
table.changeCellValue(col, row, value); // 单格修改
table.setRecords(newRecords); // 全量更新
table.addRecords(newRecords); // 增量添加
table.changeCellValue(col, row, value); // 单格修改

// ❌ 不推荐:直接修改 records 数组
table.records.push(newRecord); // 不会触发重新渲染!
table.records.push(newRecord); // 不会触发重新渲染!

// 如果必须直接修改数据源,需手动刷新
table.records[0].name = 'NewName';
table.refreshAfterSourceChange(); // ListTable 专有
table.refreshAfterSourceChange(); // ListTable 专有
```

## 五、树形数据
Expand All @@ -273,25 +323,19 @@ const table = new ListTable({
records: [
{
name: '总部',
children: [
{ name: '研发部', children: [
{ name: '前端组' },
{ name: '后端组' }
]},
{ name: '市场部' }
]
children: [{ name: '研发部', children: [{ name: '前端组' }, { name: '后端组' }] }, { name: '市场部' }]
}
],
columns: [
{ field: 'name', title: '部门', tree: true }, // tree: true 标记树形列
{ field: 'name', title: '部门', tree: true }, // tree: true 标记树形列
{ field: 'headcount', title: '人数' }
],
hierarchyIndent: 20, // 缩进像素
hierarchyExpandLevel: 2 // 默认展开2层
hierarchyIndent: 20, // 缩进像素
hierarchyExpandLevel: 2 // 默认展开2层
});

// 动态加载子节点
table.on('tree_hierarchy_state_change', (args) => {
table.on('tree_hierarchy_state_change', args => {
if (args.hierarchyState === 'expand') {
loadChildren(args.originData).then(children => {
table.setRecordChildren(children, args.row);
Expand Down
Loading