pivot-table: Fix handling of current-layer in spv files, and update display.
authorBen Pfaff <blp@cs.stanford.edu>
Sun, 10 Jan 2021 03:59:48 +0000 (19:59 -0800)
committerBen Pfaff <blp@cs.stanford.edu>
Sun, 10 Jan 2021 03:59:48 +0000 (19:59 -0800)
doc/dev/spv-file-format.texi
src/output/pivot-output.c
src/output/spv/spv-light-decoder.c
src/output/spv/spv-writer.c
tests/output/pivot-table.at

index 54decbcf52bfa7034c6b34bc4465115c7aa3451b..da4aa136f0ee21ce4289917dc040882a77f8e816 100644 (file)
@@ -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
index 0efba3e34b0e0a6922644e18338cf219c3fad5db..15df5c730673bc70f5386bb4814b9278861c2a0b 100644 (file)
@@ -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
index 0ce5c06924c3c52e78952e752dba1eecab431640..520cb2b0a066698fe6263acb2f0894a84888306b 100644 (file)
@@ -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;
 }
 
index 58cb308fadbaa1e563d3cc995dcc08a2e002692f..09ca01b412f10f77844e8b96dc81ffb529d3e199 100644 (file)
@@ -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);
index 5e45563d666e7319fcf0c4e6ee6de23027686809..543dac1eb0d6ab819ab00759d3f0b222032d29d7 100644 (file)
@@ -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")