@dou-ui/pivot 0.0.0-stage → 0.1.0-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (99) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +10 -2
  3. package/dist/assets/default-PXde2wzm.js.map +1 -0
  4. package/dist/core/format.js +116 -0
  5. package/dist/core/format.js.map +1 -0
  6. package/dist/core/labels.js +28 -0
  7. package/dist/core/labels.js.map +1 -0
  8. package/dist/core/layout.js +190 -0
  9. package/dist/core/layout.js.map +1 -0
  10. package/dist/core/source.js +46 -0
  11. package/dist/core/source.js.map +1 -0
  12. package/dist/core/table.js +154 -0
  13. package/dist/core/table.js.map +1 -0
  14. package/dist/engine/aggregate.js +51 -0
  15. package/dist/engine/aggregate.js.map +1 -0
  16. package/dist/engine/compute.js +735 -0
  17. package/dist/engine/compute.js.map +1 -0
  18. package/dist/engine/engine.js +46 -0
  19. package/dist/engine/engine.js.map +1 -0
  20. package/dist/engine/formula.js +225 -0
  21. package/dist/engine/formula.js.map +1 -0
  22. package/dist/engine/group.js +107 -0
  23. package/dist/engine/group.js.map +1 -0
  24. package/dist/engine/hash.js +108 -0
  25. package/dist/engine/hash.js.map +1 -0
  26. package/dist/engine/index.js +8 -0
  27. package/dist/engine/show.js +132 -0
  28. package/dist/engine/show.js.map +1 -0
  29. package/dist/engine/source.js +339 -0
  30. package/dist/engine/source.js.map +1 -0
  31. package/dist/engine/tree.js +226 -0
  32. package/dist/engine/tree.js.map +1 -0
  33. package/dist/fields/fields.js +6 -0
  34. package/dist/fields/fields.js.map +1 -0
  35. package/dist/fields/fields.vue_vue_type_script_setup_true_lang.js +881 -0
  36. package/dist/fields/fields.vue_vue_type_script_setup_true_lang.js.map +1 -0
  37. package/dist/fields/filter-list.js +6 -0
  38. package/dist/fields/filter-list.js.map +1 -0
  39. package/dist/fields/filter-list.vue_vue_type_script_setup_true_lang.js +184 -0
  40. package/dist/fields/filter-list.vue_vue_type_script_setup_true_lang.js.map +1 -0
  41. package/dist/fields/formula-dialog.js +6 -0
  42. package/dist/fields/formula-dialog.js.map +1 -0
  43. package/dist/fields/formula-dialog.vue_vue_type_script_setup_true_lang.js +165 -0
  44. package/dist/fields/formula-dialog.vue_vue_type_script_setup_true_lang.js.map +1 -0
  45. package/dist/fields/model.js +200 -0
  46. package/dist/fields/model.js.map +1 -0
  47. package/dist/fields/top-dialog.js +6 -0
  48. package/dist/fields/top-dialog.js.map +1 -0
  49. package/dist/fields/top-dialog.vue_vue_type_script_setup_true_lang.js +174 -0
  50. package/dist/fields/top-dialog.vue_vue_type_script_setup_true_lang.js.map +1 -0
  51. package/dist/index.js +16 -0
  52. package/dist/index.js.map +1 -0
  53. package/dist/locale.js +508 -0
  54. package/dist/locale.js.map +1 -0
  55. package/dist/pivot.js +6 -0
  56. package/dist/pivot.js.map +1 -0
  57. package/dist/pivot.vue_vue_type_script_setup_true_lang.js +1711 -0
  58. package/dist/pivot.vue_vue_type_script_setup_true_lang.js.map +1 -0
  59. package/dist/style.css +1 -0
  60. package/dist/style.d.ts +1 -0
  61. package/dist/style.js +13 -0
  62. package/dist/types/core/format.d.ts +26 -0
  63. package/dist/types/core/labels.d.ts +14 -0
  64. package/dist/types/core/layout.d.ts +72 -0
  65. package/dist/types/core/source.d.ts +7 -0
  66. package/dist/types/core/table.d.ts +73 -0
  67. package/dist/types/engine/aggregate.d.ts +35 -0
  68. package/dist/types/engine/compute.d.ts +173 -0
  69. package/dist/types/engine/engine.d.ts +29 -0
  70. package/dist/types/engine/formula.d.ts +44 -0
  71. package/dist/types/engine/group.d.ts +34 -0
  72. package/dist/types/engine/hash.d.ts +36 -0
  73. package/dist/types/engine/index.d.ts +15 -0
  74. package/dist/types/engine/show.d.ts +27 -0
  75. package/dist/types/engine/source.d.ts +108 -0
  76. package/dist/types/engine/tree.d.ts +87 -0
  77. package/dist/types/engine/types.d.ts +148 -0
  78. package/dist/types/fields/fields.vue.d.ts +26 -0
  79. package/dist/types/fields/filter-list.vue.d.ts +20 -0
  80. package/dist/types/fields/formula-dialog.vue.d.ts +30 -0
  81. package/dist/types/fields/model.d.ts +52 -0
  82. package/dist/types/fields/top-dialog.vue.d.ts +25 -0
  83. package/dist/types/index.d.ts +458 -0
  84. package/dist/types/locale.d.ts +184 -0
  85. package/dist/types/pivot.vue.d.ts +29 -0
  86. package/dist/types/types.d.ts +199 -0
  87. package/dist/types/worker/client.d.ts +19 -0
  88. package/dist/types/worker/default.d.ts +1 -0
  89. package/dist/types/worker/index.d.ts +5 -0
  90. package/dist/types/worker/protocol.d.ts +60 -0
  91. package/dist/types/worker/serve.d.ts +22 -0
  92. package/dist/worker/client.js +191 -0
  93. package/dist/worker/client.js.map +1 -0
  94. package/dist/worker/default.js +20 -0
  95. package/dist/worker/default.js.map +1 -0
  96. package/dist/worker/index.js +3 -0
  97. package/dist/worker/serve.js +101 -0
  98. package/dist/worker/serve.js.map +1 -0
  99. package/package.json +64 -4
@@ -0,0 +1,200 @@
1
+ // src/fields/model.ts
2
+ var AREAS = [
3
+ "filters",
4
+ "columns",
5
+ "rows",
6
+ "values"
7
+ ];
8
+ var nameOf = (d) => typeof d === "string" ? d : d.field;
9
+ var specOf = (d) => typeof d === "string" ? { field: d } : d;
10
+ var fieldOfValue = (v) => typeof v === "string" ? v : v.field ?? "";
11
+ /** Whether a filter keeps out anything. */
12
+ var isFiltering = (filter) => !!filter && (filter.include !== void 0 || (filter.exclude?.length ?? 0) > 0 || !!filter.top || !!filter.between);
13
+ /** The fields in each area. A field filtered on an axis stays on its axis, not in the filters. */
14
+ function areasOf(config) {
15
+ const rows = (config.rows ?? []).map(nameOf);
16
+ const columns = (config.columns ?? []).map(nameOf);
17
+ const onAxis = /* @__PURE__ */ new Set([...rows, ...columns]);
18
+ return {
19
+ rows: rows.map((field, index) => ({
20
+ key: `r:${field}`,
21
+ kind: "dimension",
22
+ field,
23
+ index
24
+ })),
25
+ columns: columns.map((field, index) => ({
26
+ key: `c:${field}`,
27
+ kind: "dimension",
28
+ field,
29
+ index
30
+ })),
31
+ values: (config.values ?? []).map((v, index) => ({
32
+ key: `v:${index}`,
33
+ kind: "value",
34
+ field: fieldOfValue(v),
35
+ index
36
+ })),
37
+ filters: Object.keys(config.filters ?? {}).filter((field) => !onAxis.has(field)).map((field, index) => ({
38
+ key: `f:${field}`,
39
+ kind: "filter",
40
+ field,
41
+ index
42
+ }))
43
+ };
44
+ }
45
+ /** The config with the areas as given: what an axis knew of a field (sort, grouping) moves with it. */
46
+ function configOf(areas, config) {
47
+ const known = /* @__PURE__ */ new Map();
48
+ for (const d of [...config.rows ?? [], ...config.columns ?? []]) known.set(nameOf(d), specOf(d));
49
+ const fresh = /* @__PURE__ */ new Set();
50
+ for (const area of [
51
+ "rows",
52
+ "columns",
53
+ "filters"
54
+ ]) for (const item of areas[area]) if (item.kind === "field") fresh.add(item.field);
55
+ const placed = /* @__PURE__ */ new Set();
56
+ const axis = (area) => {
57
+ const out = [];
58
+ for (const item of areas[area]) {
59
+ if (!item.field || placed.has(item.field)) continue;
60
+ if (fresh.has(item.field) && item.kind !== "field") continue;
61
+ placed.add(item.field);
62
+ const spec = known.get(item.field);
63
+ out.push(spec && Object.keys(spec).length > 1 ? spec : item.field);
64
+ }
65
+ return out;
66
+ };
67
+ const rows = axis("rows");
68
+ const columns = axis("columns");
69
+ const values = [];
70
+ for (const item of areas.values) if (item.kind === "value") values.push(config.values[item.index]);
71
+ else if (item.field) values.push(item.field);
72
+ const filters = {};
73
+ const old = config.filters ?? {};
74
+ for (const item of areas.filters) {
75
+ if (!item.field || placed.has(item.field) || filters[item.field]) continue;
76
+ filters[item.field] = old[item.field] ?? {};
77
+ }
78
+ for (const field of placed) if (old[field]) filters[field] = old[field];
79
+ const next = {
80
+ ...config,
81
+ rows,
82
+ columns,
83
+ values,
84
+ filters
85
+ };
86
+ if (Object.keys(filters).length === 0) delete next.filters;
87
+ if (next.sort && (!values[next.sort.valueIndex] || !sameList(config.columns, next.columns))) next.sort = null;
88
+ return next;
89
+ }
90
+ var sameList = (a, b) => (a ?? []).map(nameOf).join("\0") === (b ?? []).map(nameOf).join("\0");
91
+ /** Moves an item to the end of an area (what "移到…" in a field's menu does). */
92
+ function moveItem(areas, from, item, to) {
93
+ const next = { ...areas };
94
+ if (from) next[from] = areas[from].filter((i) => i.key !== item.key);
95
+ if (to) next[to] = [...next[to], item];
96
+ return next;
97
+ }
98
+ /** A dimension with some of its options changed; plain names stay plain while they can. */
99
+ function withDimension(config, axis, field, patch) {
100
+ const list = (config[axis] ?? []).map((d) => {
101
+ if (nameOf(d) !== field) return d;
102
+ const spec = { ...specOf(d) };
103
+ if (patch.sort !== void 0) spec.sort = patch.sort;
104
+ if (patch.subtotal !== void 0) spec.subtotal = patch.subtotal;
105
+ if (patch.by === null) delete spec.by;
106
+ else if (patch.by !== void 0) spec.by = patch.by;
107
+ if (spec.sort === "asc") delete spec.sort;
108
+ if (spec.subtotal === true) delete spec.subtotal;
109
+ return Object.keys(spec).length === 1 ? spec.field : spec;
110
+ });
111
+ const next = {
112
+ ...config,
113
+ [axis]: list
114
+ };
115
+ if (patch.by !== void 0 && config.filters?.[field]) {
116
+ const filters = { ...config.filters };
117
+ filters[field] = {};
118
+ next.filters = filters;
119
+ }
120
+ return next;
121
+ }
122
+ /** A value with its way of summing up changed. */
123
+ function withAggregate(config, index, aggregate) {
124
+ const values = [...config.values ?? []];
125
+ const v = values[index];
126
+ if (v === void 0) return config;
127
+ values[index] = {
128
+ ...typeof v === "string" ? { field: v } : { ...v },
129
+ aggregate
130
+ };
131
+ return {
132
+ ...config,
133
+ values
134
+ };
135
+ }
136
+ /** A value with its way of showing, its mark or its formula changed; `null` takes one away. */
137
+ function withValue(config, index, patch) {
138
+ const values = [...config.values ?? []];
139
+ const v = values[index];
140
+ if (v === void 0) return config;
141
+ const spec = typeof v === "string" ? { field: v } : { ...v };
142
+ for (const key of [
143
+ "show",
144
+ "mark",
145
+ "formula",
146
+ "label"
147
+ ]) if (patch[key] === null) delete spec[key];
148
+ else if (patch[key] !== void 0) spec[key] = patch[key];
149
+ const keys = Object.keys(spec);
150
+ values[index] = keys.length === 1 && keys[0] === "field" ? spec.field : spec;
151
+ return {
152
+ ...config,
153
+ values
154
+ };
155
+ }
156
+ /** A field's filter with its `top` or `between` set, or both taken away; its lists stay as they are. */
157
+ function withRank(config, field, rank, inFilters) {
158
+ const next = { ...config.filters?.[field] };
159
+ delete next.top;
160
+ delete next.between;
161
+ if (rank?.top) next.top = rank.top;
162
+ else if (rank?.between) next.between = rank.between;
163
+ return withFilter(config, field, next, inFilters);
164
+ }
165
+ /** A field's filter replaced; an axis field without a filter left has none. */
166
+ function withFilter(config, field, filter, inFilters) {
167
+ const filters = { ...config.filters };
168
+ if (filter && isFiltering(filter)) filters[field] = filter;
169
+ else if (inFilters) filters[field] = {};
170
+ else delete filters[field];
171
+ const next = {
172
+ ...config,
173
+ filters
174
+ };
175
+ if (Object.keys(filters).length === 0) delete next.filters;
176
+ return next;
177
+ }
178
+ /** The closest of 1, 2, 5 or 10 times a power of ten. */
179
+ function nice(raw) {
180
+ const power = 10 ** Math.floor(Math.log10(raw));
181
+ const unit = raw / power;
182
+ return +((unit < 1.5 ? 1 : unit < 3.5 ? 2 : unit < 7.5 ? 5 : 10) * power).toPrecision(12);
183
+ }
184
+ /**
185
+ * Round range sizes for a number field: about 10, 5 and 20 ranges over
186
+ * its values, each 1, 2 or 5 times a power of ten.
187
+ */
188
+ function stepsFor(min, max) {
189
+ const span = max - min;
190
+ if (!(span > 0) || !Number.isFinite(span)) return [];
191
+ const out = [
192
+ nice(span / 10),
193
+ nice(span / 5),
194
+ nice(span / 20)
195
+ ];
196
+ return [...new Set(out)].sort((a, b) => a - b);
197
+ }
198
+ export { AREAS, areasOf, configOf, isFiltering, moveItem, stepsFor, withAggregate, withDimension, withFilter, withRank, withValue };
199
+
200
+ //# sourceMappingURL=model.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model.js","names":[],"sources":["../../src/fields/model.ts"],"sourcesContent":["import type { PivotGroupBy } from '../engine/group'\nimport type {\n PivotConfig,\n PivotDimension,\n PivotFilter,\n PivotShowAs,\n PivotValue,\n} from '../engine/types'\n\n/** The four places a field can go. */\nexport type PivotArea = 'filters' | 'columns' | 'rows' | 'values'\nexport const AREAS: readonly PivotArea[] = ['filters', 'columns', 'rows', 'values']\n\n/**\n * A field as the panel shows it. `kind` tells where it came from: the list\n * of all fields, an axis, the values or the filters; `index` is its place\n * in `values` for a value.\n */\nexport interface PivotFieldItem {\n key: string\n kind: 'field' | 'dimension' | 'value' | 'filter'\n /** The field's name; `''` for a count of records. */\n field: string\n index: number\n}\n\nexport type PivotAreas = Record<PivotArea, PivotFieldItem[]>\n\nconst nameOf = (d: PivotDimension) => (typeof d === 'string' ? d : d.field)\nconst specOf = (d: PivotDimension) => (typeof d === 'string' ? { field: d } : d)\nconst fieldOfValue = (v: PivotValue) => (typeof v === 'string' ? v : (v.field ?? ''))\n\n/** Whether a filter keeps out anything. */\nexport const isFiltering = (filter: PivotFilter | undefined) =>\n !!filter &&\n (filter.include !== undefined ||\n (filter.exclude?.length ?? 0) > 0 ||\n !!filter.top ||\n !!filter.between)\n\n/** The fields in each area. A field filtered on an axis stays on its axis, not in the filters. */\nexport function areasOf(config: PivotConfig): PivotAreas {\n const rows = (config.rows ?? []).map(nameOf)\n const columns = (config.columns ?? []).map(nameOf)\n const onAxis = new Set([...rows, ...columns])\n return {\n rows: rows.map((field, index) => ({ key: `r:${field}`, kind: 'dimension', field, index })),\n columns: columns.map((field, index) => ({\n key: `c:${field}`,\n kind: 'dimension',\n field,\n index,\n })),\n values: (config.values ?? []).map((v, index) => ({\n key: `v:${index}`,\n kind: 'value',\n field: fieldOfValue(v),\n index,\n })),\n filters: Object.keys(config.filters ?? {})\n .filter((field) => !onAxis.has(field))\n .map((field, index) => ({ key: `f:${field}`, kind: 'filter', field, index })),\n }\n}\n\n/** The config with the areas as given: what an axis knew of a field (sort, grouping) moves with it. */\nexport function configOf(areas: PivotAreas, config: PivotConfig): PivotConfig {\n const known = new Map<string, Exclude<PivotDimension, string>>()\n for (const d of [...(config.rows ?? []), ...(config.columns ?? [])])\n known.set(nameOf(d), specOf(d))\n\n // a field from the list wins over the same field elsewhere on the axes or in the filters\n const fresh = new Set<string>()\n for (const area of ['rows', 'columns', 'filters'] as const)\n for (const item of areas[area]) if (item.kind === 'field') fresh.add(item.field)\n const placed = new Set<string>()\n const axis = (area: 'rows' | 'columns') => {\n const out: PivotDimension[] = []\n for (const item of areas[area]) {\n if (!item.field || placed.has(item.field)) continue\n if (fresh.has(item.field) && item.kind !== 'field') continue\n placed.add(item.field)\n const spec = known.get(item.field)\n out.push(spec && Object.keys(spec).length > 1 ? spec : item.field)\n }\n return out\n }\n const rows = axis('rows')\n const columns = axis('columns')\n\n const values: PivotValue[] = []\n for (const item of areas.values) {\n if (item.kind === 'value') values.push(config.values![item.index]!)\n else if (item.field) values.push(item.field)\n }\n\n const filters: Record<string, PivotFilter> = {}\n const old = config.filters ?? {}\n for (const item of areas.filters) {\n if (!item.field || placed.has(item.field) || filters[item.field]) continue\n filters[item.field] = old[item.field] ?? {}\n }\n // a filter goes with its field onto an axis, and away with it\n for (const field of placed) if (old[field]) filters[field] = old[field]\n\n const next: PivotConfig = { ...config, rows, columns, values, filters }\n if (Object.keys(filters).length === 0) delete next.filters\n // sorting by a column of values only makes sense while those values stay\n if (next.sort && (!values[next.sort.valueIndex] || !sameList(config.columns, next.columns)))\n next.sort = null\n return next\n}\n\nconst sameList = (a?: readonly PivotDimension[], b?: readonly PivotDimension[]) =>\n (a ?? []).map(nameOf).join('\\u0000') === (b ?? []).map(nameOf).join('\\u0000')\n\n/** Moves an item to the end of an area (what \"移到…\" in a field's menu does). */\nexport function moveItem(\n areas: PivotAreas,\n from: PivotArea | null,\n item: PivotFieldItem,\n to: PivotArea | null,\n): PivotAreas {\n const next = { ...areas }\n if (from) next[from] = areas[from].filter((i) => i.key !== item.key)\n if (to) next[to] = [...next[to], item]\n return next\n}\n\n/** A dimension with some of its options changed; plain names stay plain while they can. */\nexport function withDimension(\n config: PivotConfig,\n axis: 'rows' | 'columns',\n field: string,\n patch: { sort?: 'asc' | 'desc'; subtotal?: boolean; by?: PivotGroupBy | null },\n): PivotConfig {\n const list = (config[axis] ?? []).map((d) => {\n if (nameOf(d) !== field) return d\n const spec: Exclude<PivotDimension, string> = { ...specOf(d) }\n if (patch.sort !== undefined) spec.sort = patch.sort\n if (patch.subtotal !== undefined) spec.subtotal = patch.subtotal\n if (patch.by === null) delete spec.by\n else if (patch.by !== undefined) spec.by = patch.by\n if (spec.sort === 'asc') delete spec.sort\n if (spec.subtotal === true) delete spec.subtotal\n return Object.keys(spec).length === 1 ? spec.field : spec\n })\n const next: PivotConfig = { ...config, [axis]: list }\n // a filter on the old groups no longer matches once the grouping changes\n if (patch.by !== undefined && config.filters?.[field]) {\n const filters = { ...config.filters }\n filters[field] = {}\n next.filters = filters\n }\n return next\n}\n\n/** A value with its way of summing up changed. */\nexport function withAggregate(config: PivotConfig, index: number, aggregate: string): PivotConfig {\n const values = [...(config.values ?? [])]\n const v = values[index]\n if (v === undefined) return config\n const spec = typeof v === 'string' ? { field: v } : { ...v }\n values[index] = { ...spec, aggregate }\n return { ...config, values }\n}\n\n/** A value with its way of showing, its mark or its formula changed; `null` takes one away. */\nexport function withValue(\n config: PivotConfig,\n index: number,\n patch: {\n show?: PivotShowAs | null\n mark?: 'bar' | 'scale' | null\n formula?: string\n label?: string | null\n },\n): PivotConfig {\n const values = [...(config.values ?? [])]\n const v = values[index]\n if (v === undefined) return config\n const spec: Exclude<PivotValue, string> = typeof v === 'string' ? { field: v } : { ...v }\n for (const key of ['show', 'mark', 'formula', 'label'] as const) {\n if (patch[key] === null) delete spec[key]\n else if (patch[key] !== undefined) (spec as Record<string, unknown>)[key] = patch[key]\n }\n const keys = Object.keys(spec)\n values[index] = keys.length === 1 && keys[0] === 'field' ? spec.field! : spec\n return { ...config, values }\n}\n\n/** Which groups of a field to keep by their totals: the top (or bottom) N, or a range. */\nexport type PivotRank = Pick<PivotFilter, 'top' | 'between'>\n\n/** A field's filter with its `top` or `between` set, or both taken away; its lists stay as they are. */\nexport function withRank(\n config: PivotConfig,\n field: string,\n rank: PivotRank | null,\n inFilters: boolean,\n): PivotConfig {\n const next: PivotFilter = { ...config.filters?.[field] }\n delete next.top\n delete next.between\n if (rank?.top) next.top = rank.top\n else if (rank?.between) next.between = rank.between\n return withFilter(config, field, next, inFilters)\n}\n\n/** A field's filter replaced; an axis field without a filter left has none. */\nexport function withFilter(\n config: PivotConfig,\n field: string,\n filter: PivotFilter | null,\n inFilters: boolean,\n): PivotConfig {\n const filters = { ...config.filters }\n if (filter && isFiltering(filter)) filters[field] = filter\n else if (inFilters) filters[field] = {}\n else delete filters[field]\n const next: PivotConfig = { ...config, filters }\n if (Object.keys(filters).length === 0) delete next.filters\n return next\n}\n\n/** The closest of 1, 2, 5 or 10 times a power of ten. */\nfunction nice(raw: number) {\n const power = 10 ** Math.floor(Math.log10(raw))\n const unit = raw / power\n const m = unit < 1.5 ? 1 : unit < 3.5 ? 2 : unit < 7.5 ? 5 : 10\n return +(m * power).toPrecision(12)\n}\n\n/**\n * Round range sizes for a number field: about 10, 5 and 20 ranges over\n * its values, each 1, 2 or 5 times a power of ten.\n */\nexport function stepsFor(min: number, max: number): number[] {\n const span = max - min\n if (!(span > 0) || !Number.isFinite(span)) return []\n const out = [nice(span / 10), nice(span / 5), nice(span / 20)]\n // oxlint-disable-next-line unicorn/no-array-sort -- sorts a fresh array\n return [...new Set(out)].sort((a, b) => a - b)\n}\n"],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import top_dialog_vue_vue_type_script_setup_true_lang_default from "./top-dialog.vue_vue_type_script_setup_true_lang.js";
2
+ // src/fields/top-dialog.vue
3
+ var top_dialog_default = top_dialog_vue_vue_type_script_setup_true_lang_default;
4
+ export { top_dialog_default as default };
5
+
6
+ //# sourceMappingURL=top-dialog.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"top-dialog.js","names":["_sfc_main"],"sources":["../../src/fields/top-dialog.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport {\n DouButton,\n DouDialog,\n DouForm,\n DouFormItem,\n DouInputNumber,\n DouSegmentedControl,\n DouSelect,\n} from 'dou-ui'\nimport { computed, ref, watch } from 'vue'\nimport type { PivotFilter } from '../engine/types'\nimport type { PivotMessages } from '../locale'\nimport { format } from '../locale'\nimport type { PivotRank } from './model'\n\nconst props = defineProps<{\n messages: PivotMessages\n /** The field's name as shown. */\n field: string\n /** The values to rank by, with their headers. */\n values: string[]\n /** The field's filter as it is. */\n filter: PivotFilter | undefined\n}>()\nconst open = defineModel<boolean>('open', { required: true })\nconst emit = defineEmits<{ apply: [rank: PivotRank | null] }>()\n\ntype Mode = 'top' | 'bottom' | 'between'\nconst mode = ref<Mode>('top')\nconst count = ref<number | null>(10)\nconst min = ref<number | null>(null)\nconst max = ref<number | null>(null)\nconst valueIndex = ref(0)\n\nwatch(open, (now) => {\n if (!now) return\n const { top, between } = props.filter ?? {}\n mode.value = between ? 'between' : top?.order === 'asc' ? 'bottom' : 'top'\n count.value = top?.count ?? 10\n min.value = between?.min ?? null\n max.value = between?.max ?? null\n valueIndex.value = top?.valueIndex ?? between?.valueIndex ?? 0\n})\n\nconst m = computed(() => props.messages.topDialog)\nconst modes = computed(() => [\n { value: 'top', label: m.value.top },\n { value: 'bottom', label: m.value.bottom },\n { value: 'between', label: m.value.between },\n])\nconst valueOptions = computed(() => props.values.map((label, value) => ({ label, value })))\nconst ready = computed(() =>\n mode.value === 'between' ? min.value !== null || max.value !== null : (count.value ?? 0) >= 1,\n)\n\nfunction apply() {\n if (!ready.value) return\n const index = valueIndex.value ? { valueIndex: valueIndex.value } : {}\n if (mode.value === 'between') {\n emit('apply', {\n between: {\n ...index,\n ...(min.value === null ? {} : { min: min.value }),\n ...(max.value === null ? {} : { max: max.value }),\n },\n })\n } else {\n emit('apply', {\n top: {\n count: Math.round(count.value!),\n ...index,\n ...(mode.value === 'bottom' ? { order: 'asc' as const } : {}),\n },\n })\n }\n open.value = false\n}\nfunction clear() {\n emit('apply', null)\n open.value = false\n}\n</script>\n\n<template>\n <DouDialog v-model:open=\"open\" :title=\"format(m.title, { field })\" :width=\"400\">\n <DouForm layout=\"vertical\" class=\"dou-pivot-top\" @submit=\"apply\">\n <DouSegmentedControl v-model=\"mode\" :options=\"modes\" block />\n <DouFormItem v-if=\"values.length > 1\" :label=\"m.by\">\n <DouSelect v-model=\"valueIndex\" :options=\"valueOptions\" />\n </DouFormItem>\n <DouFormItem v-if=\"mode !== 'between'\" :label=\"m.count\">\n <DouInputNumber v-model=\"count\" :min=\"1\" :step=\"1\" :precision=\"0\" />\n </DouFormItem>\n <div v-else class=\"dou-pivot-top__range\">\n <DouFormItem :label=\"m.min\">\n <DouInputNumber v-model=\"min\" />\n </DouFormItem>\n <DouFormItem :label=\"m.max\">\n <DouInputNumber v-model=\"max\" />\n </DouFormItem>\n </div>\n <p class=\"dou-pivot-top__help\">{{ m.help }}</p>\n </DouForm>\n <template #footer=\"{ close }\">\n <DouButton\n v-if=\"filter?.top || filter?.between\"\n class=\"dou-pivot-top__clear\"\n variant=\"ghost\"\n @click=\"clear\"\n >{{ m.clear }}</DouButton\n >\n <DouButton variant=\"outline\" @click=\"close\">{{ m.cancel }}</DouButton>\n <DouButton variant=\"solid\" :disabled=\"!ready\" @click=\"apply\">{{ m.apply }}</DouButton>\n </template>\n </DouDialog>\n</template>\n"],"mappings":""}
@@ -0,0 +1,174 @@
1
+ import { format } from "../locale.js";
2
+ import { DouButton, DouDialog, DouForm, DouFormItem, DouInputNumber, DouSegmentedControl, DouSelect } from "dou-ui";
3
+ import { computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createTextVNode, createVNode, defineComponent, mergeModels, openBlock, ref, toDisplayString, unref, useModel, watch, withCtx } from "vue";
4
+ // src/fields/top-dialog.vue?vue&type=script&setup=true&lang.ts
5
+ var _hoisted_1 = {
6
+ key: 2,
7
+ class: "dou-pivot-top__range"
8
+ };
9
+ var _hoisted_2 = { class: "dou-pivot-top__help" };
10
+ var top_dialog_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineComponent({
11
+ __name: "top-dialog",
12
+ props: /*@__PURE__*/ mergeModels({
13
+ messages: {},
14
+ field: {},
15
+ values: {},
16
+ filter: {}
17
+ }, {
18
+ "open": {
19
+ type: Boolean,
20
+ required: true
21
+ },
22
+ "openModifiers": {}
23
+ }),
24
+ emits: /*@__PURE__*/ mergeModels(["apply"], ["update:open"]),
25
+ setup(__props, { emit: __emit }) {
26
+ const props = __props;
27
+ const open = useModel(__props, "open");
28
+ const emit = __emit;
29
+ const mode = ref("top");
30
+ const count = ref(10);
31
+ const min = ref(null);
32
+ const max = ref(null);
33
+ const valueIndex = ref(0);
34
+ watch(open, (now) => {
35
+ if (!now) return;
36
+ const { top, between } = props.filter ?? {};
37
+ mode.value = between ? "between" : top?.order === "asc" ? "bottom" : "top";
38
+ count.value = top?.count ?? 10;
39
+ min.value = between?.min ?? null;
40
+ max.value = between?.max ?? null;
41
+ valueIndex.value = top?.valueIndex ?? between?.valueIndex ?? 0;
42
+ });
43
+ const m = computed(() => props.messages.topDialog);
44
+ const modes = computed(() => [
45
+ {
46
+ value: "top",
47
+ label: m.value.top
48
+ },
49
+ {
50
+ value: "bottom",
51
+ label: m.value.bottom
52
+ },
53
+ {
54
+ value: "between",
55
+ label: m.value.between
56
+ }
57
+ ]);
58
+ const valueOptions = computed(() => props.values.map((label, value) => ({
59
+ label,
60
+ value
61
+ })));
62
+ const ready = computed(() => mode.value === "between" ? min.value !== null || max.value !== null : (count.value ?? 0) >= 1);
63
+ function apply() {
64
+ if (!ready.value) return;
65
+ const index = valueIndex.value ? { valueIndex: valueIndex.value } : {};
66
+ if (mode.value === "between") emit("apply", { between: {
67
+ ...index,
68
+ ...min.value === null ? {} : { min: min.value },
69
+ ...max.value === null ? {} : { max: max.value }
70
+ } });
71
+ else emit("apply", { top: {
72
+ count: Math.round(count.value),
73
+ ...index,
74
+ ...mode.value === "bottom" ? { order: "asc" } : {}
75
+ } });
76
+ open.value = false;
77
+ }
78
+ function clear() {
79
+ emit("apply", null);
80
+ open.value = false;
81
+ }
82
+ return (_ctx, _cache) => {
83
+ return openBlock(), createBlock(unref(DouDialog), {
84
+ open: open.value,
85
+ "onUpdate:open": _cache[5] || (_cache[5] = ($event) => open.value = $event),
86
+ title: unref(format)(m.value.title, { field: __props.field }),
87
+ width: 400
88
+ }, {
89
+ footer: withCtx(({ close }) => [
90
+ __props.filter?.top || __props.filter?.between ? (openBlock(), createBlock(unref(DouButton), {
91
+ key: 0,
92
+ class: "dou-pivot-top__clear",
93
+ variant: "ghost",
94
+ onClick: clear
95
+ }, {
96
+ default: withCtx(() => [createTextVNode(toDisplayString(m.value.clear), 1)]),
97
+ _: 1
98
+ })) : createCommentVNode("", true),
99
+ createVNode(unref(DouButton), {
100
+ variant: "outline",
101
+ onClick: close
102
+ }, {
103
+ default: withCtx(() => [createTextVNode(toDisplayString(m.value.cancel), 1)]),
104
+ _: 1
105
+ }, 8, ["onClick"]),
106
+ createVNode(unref(DouButton), {
107
+ variant: "solid",
108
+ disabled: !ready.value,
109
+ onClick: apply
110
+ }, {
111
+ default: withCtx(() => [createTextVNode(toDisplayString(m.value.apply), 1)]),
112
+ _: 1
113
+ }, 8, ["disabled"])
114
+ ]),
115
+ default: withCtx(() => [createVNode(unref(DouForm), {
116
+ layout: "vertical",
117
+ class: "dou-pivot-top",
118
+ onSubmit: apply
119
+ }, {
120
+ default: withCtx(() => [
121
+ createVNode(unref(DouSegmentedControl), {
122
+ modelValue: mode.value,
123
+ "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => mode.value = $event),
124
+ options: modes.value,
125
+ block: ""
126
+ }, null, 8, ["modelValue", "options"]),
127
+ __props.values.length > 1 ? (openBlock(), createBlock(unref(DouFormItem), {
128
+ key: 0,
129
+ label: m.value.by
130
+ }, {
131
+ default: withCtx(() => [createVNode(unref(DouSelect), {
132
+ modelValue: valueIndex.value,
133
+ "onUpdate:modelValue": _cache[1] || (_cache[1] = ($event) => valueIndex.value = $event),
134
+ options: valueOptions.value
135
+ }, null, 8, ["modelValue", "options"])]),
136
+ _: 1
137
+ }, 8, ["label"])) : createCommentVNode("", true),
138
+ mode.value !== "between" ? (openBlock(), createBlock(unref(DouFormItem), {
139
+ key: 1,
140
+ label: m.value.count
141
+ }, {
142
+ default: withCtx(() => [createVNode(unref(DouInputNumber), {
143
+ modelValue: count.value,
144
+ "onUpdate:modelValue": _cache[2] || (_cache[2] = ($event) => count.value = $event),
145
+ min: 1,
146
+ step: 1,
147
+ precision: 0
148
+ }, null, 8, ["modelValue"])]),
149
+ _: 1
150
+ }, 8, ["label"])) : (openBlock(), createElementBlock("div", _hoisted_1, [createVNode(unref(DouFormItem), { label: m.value.min }, {
151
+ default: withCtx(() => [createVNode(unref(DouInputNumber), {
152
+ modelValue: min.value,
153
+ "onUpdate:modelValue": _cache[3] || (_cache[3] = ($event) => min.value = $event)
154
+ }, null, 8, ["modelValue"])]),
155
+ _: 1
156
+ }, 8, ["label"]), createVNode(unref(DouFormItem), { label: m.value.max }, {
157
+ default: withCtx(() => [createVNode(unref(DouInputNumber), {
158
+ modelValue: max.value,
159
+ "onUpdate:modelValue": _cache[4] || (_cache[4] = ($event) => max.value = $event)
160
+ }, null, 8, ["modelValue"])]),
161
+ _: 1
162
+ }, 8, ["label"])])),
163
+ createElementVNode("p", _hoisted_2, toDisplayString(m.value.help), 1)
164
+ ]),
165
+ _: 1
166
+ })]),
167
+ _: 1
168
+ }, 8, ["open", "title"]);
169
+ };
170
+ }
171
+ });
172
+ export { top_dialog_vue_vue_type_script_setup_true_lang_default as default };
173
+
174
+ //# sourceMappingURL=top-dialog.vue_vue_type_script_setup_true_lang.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"top-dialog.vue_vue_type_script_setup_true_lang.js","names":["_useModel","_openBlock","_createBlock","_unref","_withCtx","_createTextVNode","_toDisplayString","_createCommentVNode","_createVNode","_createElementBlock","_createElementVNode"],"sources":["../../src/fields/top-dialog.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport {\n DouButton,\n DouDialog,\n DouForm,\n DouFormItem,\n DouInputNumber,\n DouSegmentedControl,\n DouSelect,\n} from 'dou-ui'\nimport { computed, ref, watch } from 'vue'\nimport type { PivotFilter } from '../engine/types'\nimport type { PivotMessages } from '../locale'\nimport { format } from '../locale'\nimport type { PivotRank } from './model'\n\nconst props = defineProps<{\n messages: PivotMessages\n /** The field's name as shown. */\n field: string\n /** The values to rank by, with their headers. */\n values: string[]\n /** The field's filter as it is. */\n filter: PivotFilter | undefined\n}>()\nconst open = defineModel<boolean>('open', { required: true })\nconst emit = defineEmits<{ apply: [rank: PivotRank | null] }>()\n\ntype Mode = 'top' | 'bottom' | 'between'\nconst mode = ref<Mode>('top')\nconst count = ref<number | null>(10)\nconst min = ref<number | null>(null)\nconst max = ref<number | null>(null)\nconst valueIndex = ref(0)\n\nwatch(open, (now) => {\n if (!now) return\n const { top, between } = props.filter ?? {}\n mode.value = between ? 'between' : top?.order === 'asc' ? 'bottom' : 'top'\n count.value = top?.count ?? 10\n min.value = between?.min ?? null\n max.value = between?.max ?? null\n valueIndex.value = top?.valueIndex ?? between?.valueIndex ?? 0\n})\n\nconst m = computed(() => props.messages.topDialog)\nconst modes = computed(() => [\n { value: 'top', label: m.value.top },\n { value: 'bottom', label: m.value.bottom },\n { value: 'between', label: m.value.between },\n])\nconst valueOptions = computed(() => props.values.map((label, value) => ({ label, value })))\nconst ready = computed(() =>\n mode.value === 'between' ? min.value !== null || max.value !== null : (count.value ?? 0) >= 1,\n)\n\nfunction apply() {\n if (!ready.value) return\n const index = valueIndex.value ? { valueIndex: valueIndex.value } : {}\n if (mode.value === 'between') {\n emit('apply', {\n between: {\n ...index,\n ...(min.value === null ? {} : { min: min.value }),\n ...(max.value === null ? {} : { max: max.value }),\n },\n })\n } else {\n emit('apply', {\n top: {\n count: Math.round(count.value!),\n ...index,\n ...(mode.value === 'bottom' ? { order: 'asc' as const } : {}),\n },\n })\n }\n open.value = false\n}\nfunction clear() {\n emit('apply', null)\n open.value = false\n}\n</script>\n\n<template>\n <DouDialog v-model:open=\"open\" :title=\"format(m.title, { field })\" :width=\"400\">\n <DouForm layout=\"vertical\" class=\"dou-pivot-top\" @submit=\"apply\">\n <DouSegmentedControl v-model=\"mode\" :options=\"modes\" block />\n <DouFormItem v-if=\"values.length > 1\" :label=\"m.by\">\n <DouSelect v-model=\"valueIndex\" :options=\"valueOptions\" />\n </DouFormItem>\n <DouFormItem v-if=\"mode !== 'between'\" :label=\"m.count\">\n <DouInputNumber v-model=\"count\" :min=\"1\" :step=\"1\" :precision=\"0\" />\n </DouFormItem>\n <div v-else class=\"dou-pivot-top__range\">\n <DouFormItem :label=\"m.min\">\n <DouInputNumber v-model=\"min\" />\n </DouFormItem>\n <DouFormItem :label=\"m.max\">\n <DouInputNumber v-model=\"max\" />\n </DouFormItem>\n </div>\n <p class=\"dou-pivot-top__help\">{{ m.help }}</p>\n </DouForm>\n <template #footer=\"{ close }\">\n <DouButton\n v-if=\"filter?.top || filter?.between\"\n class=\"dou-pivot-top__clear\"\n variant=\"ghost\"\n @click=\"clear\"\n >{{ m.clear }}</DouButton\n >\n <DouButton variant=\"outline\" @click=\"close\">{{ m.cancel }}</DouButton>\n <DouButton variant=\"solid\" :disabled=\"!ready\" @click=\"apply\">{{ m.apply }}</DouButton>\n </template>\n </DouDialog>\n</template>\n"],"mappings":"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"}
package/dist/index.js ADDED
@@ -0,0 +1,16 @@
1
+ import { defineAggregator } from "./engine/aggregate.js";
2
+ import { PivotFormulaError, parsePivotFormula } from "./engine/formula.js";
3
+ import { bucketer } from "./engine/group.js";
4
+ import { PivotSource } from "./engine/source.js";
5
+ import { PivotTree } from "./engine/tree.js";
6
+ import { PivotResult, checkPivotFormula, computePivot } from "./engine/compute.js";
7
+ import { pivotLocales, usePivotMessages } from "./locale.js";
8
+ import pivot_default from "./pivot.js";
9
+ import fields_default from "./fields/fields.js";
10
+ import { withInstall } from "dou-ui";
11
+ // src/index.ts
12
+ var DouPivot = withInstall(pivot_default);
13
+ var DouPivotFields = withInstall(fields_default);
14
+ export { DouPivot, DouPivot as default, DouPivotFields, PivotFormulaError, PivotResult, PivotSource, PivotTree, bucketer, checkPivotFormula, computePivot, defineAggregator, parsePivotFormula, pivotLocales, usePivotMessages };
15
+
16
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":["Pivot","PivotFields"],"sources":["../src/index.ts"],"sourcesContent":["import { withInstall } from 'dou-ui'\nimport Pivot from './pivot.vue'\nimport PivotFields from './fields/fields.vue'\nimport type { PivotFieldsProps, PivotProps } from './types'\n\nexport const DouPivot = withInstall(Pivot)\nexport const DouPivotFields = withInstall(PivotFields)\nexport default DouPivot\n\nexport type {\n PivotCellEvent,\n PivotChartRows,\n PivotChartRowsOptions,\n PivotCopyOptions,\n PivotEmits,\n PivotExpose,\n PivotFieldsProps,\n PivotPrintOptions,\n PivotProps,\n PivotSheetCell,\n PivotSheetWorkbook,\n} from './types'\nexport type { PivotCSVOptions, PivotGrid, PivotGridCell } from './core/table'\nexport type { PivotAxis } from './core/layout'\nexport {\n bucketer,\n checkPivotFormula,\n computePivot,\n defineAggregator,\n parsePivotFormula,\n PivotFormulaError,\n PivotResult,\n PivotSource,\n PivotTree,\n} from './engine'\nexport type {\n PivotAggregateName,\n PivotAggregator,\n PivotCollapsed,\n PivotColumns,\n PivotComputeOptions,\n PivotComputeRequest,\n PivotConfig,\n PivotData,\n PivotDimension,\n PivotField,\n PivotFieldType,\n PivotFilter,\n PivotEngine,\n PivotFormat,\n PivotFormula,\n PivotFormulaErrorCode,\n PivotGroupBy,\n PivotLevel,\n PivotMark,\n PivotPacket,\n PivotPath,\n PivotRangeFilter,\n PivotResolvedField,\n PivotResolvedValue,\n PivotShow,\n PivotShowAs,\n PivotSourceOptions,\n PivotTone,\n PivotTopFilter,\n PivotValue,\n PivotValueSort,\n} from './engine'\nexport { pivotLocales, usePivotMessages } from './locale'\nexport type { PivotMessages, PivotMessagesOverride } from './locale'\n\ndeclare module 'vue' {\n export interface GlobalComponents {\n DouPivot: typeof DouPivot\n DouPivotFields: typeof DouPivotFields\n }\n}\n\ndeclare module 'dou-ui' {\n export interface GenericComponentProps {\n DouPivot: PivotProps\n DouPivotFields: PivotFieldsProps\n }\n}\n"],"mappings":";;;;;;;;;;;AAKA,IAAa,WAAW,YAAYA,aAAK;AACzC,IAAa,iBAAiB,YAAYC,cAAW"}