From 0e930a175e71cf7c93589f5c64c64f10e667cbb8 Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Sat, 9 Jan 2021 19:59:48 -0800 Subject: [PATCH] pivot-table: Fix handling of current-layer in spv files, and update display. --- doc/dev/spv-file-format.texi | 20 ++++++++-- src/output/pivot-output.c | 6 +-- src/output/spv/spv-light-decoder.c | 8 ++-- src/output/spv/spv-writer.c | 17 ++++++++- tests/output/pivot-table.at | 61 +++++++++++++++++++++++++----- 5 files changed, 91 insertions(+), 21 deletions(-) diff --git a/doc/dev/spv-file-format.texi b/doc/dev/spv-file-format.texi index 54decbcf52..da4aa136f0 100644 --- a/doc/dev/spv-file-format.texi +++ b/doc/dev/spv-file-format.texi @@ -1301,8 +1301,19 @@ PointKeep => be32[offset] be32 be32 The TableSettings reflect display settings. The fixed value of @code{endian} can be used to validate the endianness. -@code{current-layer} is the displayed layer. The interpretation when -there is more than one layer dimension is not yet known. +@code{current-layer} is the displayed layer. Suppose there are +@math{d} layers, numbered 1 through @math{d} in the order given in the +Dimensions (@pxref{SPV Light Member Dimensions}), and that the +displayed value of dimension @math{i} is @math{d_i}, @math{0 \le x_i < +n_i}, where @math{n_i} is the number of categories in dimension +@math{i}. Then @code{current-layer} is calculated by the following +algorithm: + +@display +let @code{current-layer} = 0 +for each @math{i} from @math{d} downto 1: + @code{current-layer} = (@math{n_i \times} @code{current-layer}) @math{+} @math{x_i} +@end display If @code{omit-empty} is 1, empty rows or columns (ones with nothing in any cell) are hidden; otherwise, they are shown. @@ -1691,7 +1702,10 @@ permutation of the 0-based dimension numbers. The first layers, the next @code{n-rows} integers specify the dimensions represented by rows, and the final @code{n-columns} integers specify the dimensions represented by columns. When there is more than one -dimension of a given kind, the inner dimensions are given first. +dimension of a given kind, the inner dimensions are given first. (For +the layer axis, this means that the first dimension is at the bottom +of the list and the last dimension is at the top when the current +layer is displayed.) @node SPV Light Member Cells @subsection Cells diff --git a/src/output/pivot-output.c b/src/output/pivot-output.c index 0efba3e34b..15df5c7306 100644 --- a/src/output/pivot-output.c +++ b/src/output/pivot-output.c @@ -595,7 +595,7 @@ pivot_output (const struct pivot_table *pt, if (n_layers > 0) { layers = create_aux_table (pt, 1, n_layers, PIVOT_AREA_LAYERS); - size_t y = 0; + size_t y = n_layers - 1; for (size_t i = 0; i < layer_axis->n_dimensions; i++) { const struct pivot_dimension *d = layer_axis->dimensions[i]; @@ -603,11 +603,9 @@ pivot_output (const struct pivot_table *pt, continue; struct string s = DS_EMPTY_INITIALIZER; - pivot_value_format (d->root->name, pt, &s); - ds_put_cstr (&s, ": "); pivot_value_format (d->data_leaves[layer_indexes[i]]->name, pt, &s); fill_cell_owned (layers, 0, y, 0, y, PIVOT_AREA_LAYERS, &s, false); - y++; + y--; } } else diff --git a/src/output/spv/spv-light-decoder.c b/src/output/spv/spv-light-decoder.c index 0ce5c06924..520cb2b0a0 100644 --- a/src/output/spv/spv-light-decoder.c +++ b/src/output/spv/spv-light-decoder.c @@ -808,19 +808,21 @@ decode_current_layer (uint64_t current_layer, struct pivot_table *table) table->current_layer = xnmalloc (axis->n_dimensions, sizeof *table->current_layer); + uint64_t remainder = current_layer; for (size_t i = 0; i < axis->n_dimensions; i++) { const struct pivot_dimension *d = axis->dimensions[i]; if (d->n_leaves) { - table->current_layer[i] = current_layer % d->n_leaves; - current_layer /= d->n_leaves; + table->current_layer[i] = remainder % d->n_leaves; + remainder /= d->n_leaves; } else table->current_layer[i] = 0; } - if (current_layer > 0) + if (remainder > 0) return xasprintf ("out of range layer data index %"PRIu64, current_layer); + return NULL; } diff --git a/src/output/spv/spv-writer.c b/src/output/spv/spv-writer.c index 58cb308fad..09ca01b412 100644 --- a/src/output/spv/spv-writer.c +++ b/src/output/spv/spv-writer.c @@ -827,6 +827,21 @@ put_x3 (struct buf *buf, const struct pivot_table *table) put_y2 (buf, table); } +static uint32_t +encode_current_layer (const struct pivot_table *table) +{ + uint32_t current_layer = 0; + + const struct pivot_axis *axis = &table->axes[PIVOT_AXIS_LAYER]; + for (size_t i = axis->n_dimensions - 1; i < axis->n_dimensions; i--) + { + const struct pivot_dimension *d = axis->dimensions[i]; + current_layer = current_layer * d->n_leaves + table->current_layer[i]; + } + + return current_layer; +} + static void put_light_table (struct buf *buf, uint64_t table_id, const struct pivot_table *table) @@ -943,7 +958,7 @@ put_light_table (struct buf *buf, uint64_t table_id, uint32_t ts_start = start_count (buf); put_be32 (buf, 1); put_be32 (buf, 4); - put_be32 (buf, 0); /* XXX current_layer */ + put_be32 (buf, encode_current_layer (table)); put_bool (buf, table->look->omit_empty); put_bool (buf, table->look->row_labels_in_corner); put_bool (buf, !table->look->show_numeric_markers); diff --git a/tests/output/pivot-table.at b/tests/output/pivot-table.at index 5e45563d66..543dac1eb0 100644 --- a/tests/output/pivot-table.at +++ b/tests/output/pivot-table.at @@ -320,7 +320,7 @@ AT_DATA([pivot.txt], [[ ]]) AT_CHECK([pivot-table-test --table-look $srcdir/output/look.stt pivot.txt --box unicode], [0], [dnl Column x b1 -b: b1 +b1 ╭──┬──┬──╮ │a1│a2│a3│ ├──┼──┼──┤ @@ -328,7 +328,7 @@ b: b1 ╰──┴──┴──╯ Row x b1 -b: b1 +b1 ╭──┬─╮ │a1│0│ │a2│1│ @@ -336,7 +336,7 @@ b: b1 ╰──┴─╯ Column x b2 -b: b2 +b2 ╭──┬──┬──╮ │a1│a2│a3│ ├──┼──┼──┤ @@ -344,7 +344,7 @@ b: b2 ╰──┴──┴──╯ Row x b2 -b: b2 +b2 ╭──┬─╮ │a1│3│ │a2│4│ @@ -352,7 +352,7 @@ b: b2 ╰──┴─╯ Column (All Layers) -b: b1 +b1 ╭──┬─╮ │a1│0│ │a2│1│ @@ -360,7 +360,7 @@ b: b1 ╰──┴─╯ Column (All Layers) -b: b2 +b2 ╭──┬─╮ │a1│3│ │a2│4│ @@ -368,7 +368,7 @@ b: b2 ╰──┴─╯ Column (All Layers) -b: b3 +b3 ╭──┬─╮ │a1│6│ │a2│7│ @@ -376,7 +376,7 @@ b: b3 ╰──┴─╯ Row (All Layers) -b: b1 +b1 ╭──┬──┬──╮ │a1│a2│a3│ ├──┼──┼──┤ @@ -384,7 +384,7 @@ b: b1 ╰──┴──┴──╯ Row (All Layers) -b: b2 +b2 ╭──┬──┬──╮ │a1│a2│a3│ ├──┼──┼──┤ @@ -392,7 +392,7 @@ b: b2 ╰──┴──┴──╯ Row (All Layers) -b: b3 +b3 ╭──┬──┬──╮ │a1│a2│a3│ ├──┼──┼──┤ @@ -401,6 +401,47 @@ b: b3 ]) AT_CLEANUP +AT_SETUP([3-d pivot table - layers]) +AT_DATA([pivot.txt], [[ +/layer "a"("a1", "a2", "a3") +/layer "b"("b1", "b2", "b3", "b4") +/col "c"("c1", "c2", "c3", "c4", "c5") +/cell[all, all, all] +/title "Column x b1 x a1" /display +/title "Column x b2 x a1" /show layer 0 1 /display +/title "Column x b3 x a2" /show layer 1 2 /display +]]) +AT_DATA([expout], [dnl +Column x b1 x a1 +b1 +a1 +╭──┬──┬──┬──┬──╮ +│c1│c2│c3│c4│c5│ +├──┼──┼──┼──┼──┤ +│ 0│12│24│36│48│ +╰──┴──┴──┴──┴──╯ + +Column x b2 x a1 +b2 +a1 +╭──┬──┬──┬──┬──╮ +│c1│c2│c3│c4│c5│ +├──┼──┼──┼──┼──┤ +│ 3│15│27│39│51│ +╰──┴──┴──┴──┴──╯ + +Column x b3 x a2 +b3 +a2 +╭──┬──┬──┬──┬──╮ +│c1│c2│c3│c4│c5│ +├──┼──┼──┼──┼──┤ +│ 7│19│31│43│55│ +╰──┴──┴──┴──┴──╯ +]) +AT_CHECK([pivot-table-test --table-look $srcdir/output/look.stt pivot.txt --box unicode], [0], [expout]) +AT_CLEANUP + AT_SETUP([pivot table title and caption]) AT_DATA([pivot.txt], [[ /col "a"("a1", "a2") -- 2.30.2