Search code examples
dynamicwolfram-mathematicatabular

Dynamic List Selection within another Dynamic in Mathematica


Building up on the solution proposed by Belisarius in "Manipulate custom Tabular".

  • Consider the following Function to create custom Tabular representation :

    DataSampleXX[data_, linesNumber_, columnsList_, color1_, color2_, color3_] :=
    
    Grid[
    Join[
         {columnsList}, {Map[Rotate[Text[#], 90 Degree] &, 
          data[[1, columnsList]]]}, data[[2 ;; linesNumber, columnsList]]],
    Background  -> {{{{color1, color2}}, {1 -> color3}}},
    Dividers    -> {All, {1 -> True, 2 -> True, 3 -> True, 0 -> True}},
    ItemSize    -> {1 -> Automatic, Automatic},
    Alignment   -> Top,
    Frame       -> True,
    FrameStyle  -> Thickness[2],
    ItemStyle   -> {Automatic, 
    Automatic, {{1, 1}, 
    {1, Length[data]}} -> Directive[FontSize -> 15, Black, Bold]}
    ];
    
  • And the following data :

    soData = {{"col1", "col2", "col3", "col4", "col5", "col6", "col7", 
               "col8", "col9", "col10"}, Range[1, 10], Range[11, 20], 
                Range[21, 30], Range[31, 40]}
    
    
    With[
         {columnsList = {1, 3},
          data = soData,
          linesNumber = 3,
          color1 = LightBlue,
          color2 = LightRed,
          color3 = LightGray},
          DataSampleXX[data, linesNumber, columnsList, color1, color2, color3]]
    

Output

  • I would like to integrate the following Dynamic to feed the columnsList argument of the DataSampleXX Function.

    Manipulate[Sort@Join[Sequence @@ {a, b}], 
               Evaluate[Sequence @@ MapThread[{{#1, {}, ""}, #2, 
               ControlType -> TogglerBar} &, {{a, b},
               Partition[Rule @@@ Transpose[{Range[10], soData[[1]]}], 5]}]], 
               ControlPlacement -> Top]
    

What I want

  • This should enable me to dynamically choose the columns (VS a range of column in my previous question) to display using DataSampleXX but I yet can`t figure out how to merge the 2 mechanisms.

Solution

  • What you want to do needs a few tricks.

    For example:

     Maipulate[ f[ Array[ a, exp], ...], ...]
    

    and similar constructs do not work (and is explained in the docs), because the a[_] are not explicit in the expression, so making it difficult to have a variable number of controls. The solution I found is:

    Manipulate[ f[#,...], ... ] & @ Array[a, exp]
    

    Other problem is that the construct

     Control@( .#. ) &/@ _controls_ 
    

    does not allow per se a two dimensional partition, so we have to use both Control@ syntax options ( Control@ and { ... }), which is not documented.

    Other nuisances you can find in the code below.

    So:

    soData = {{"col01", "col02", "col03", "col04", "col05", "col06", 
              "col07", "col08", "col09", "col10"}, 
               Range[1, 10], Range[11, 20], Range[21, 30], Range[31, 40]};
    perRow = 5;
    colsel = (# -> Graphics[{#, Disk[]}, ImageSize -> 15]) &/@ColorData[1, "ColorList"];
    s[x_] := Style[x, Black, Bold, 12];
    ct = ControlType -> PopupMenu;
    
    Manipulate[
       DataSampleXX[soData, linesNumber, Sort@Join[Sequence @@ #], color1,
                                                                   color2, color3], 
       Row[
         {Column[
           {Control@{{linesNumber, 2, s@"Lines"}, 
             Range[2, Length@soData[[All, 1]] - 1], ct}}], 
            Spacer[20], 
         Column[
           {Control@{{color1, colsel[[1, 1]], s@"Color 1"}, colsel, ct},
            Control@{{color2, colsel[[2, 1]], s@"Color 2"}, colsel, ct}, 
            Control@{{color3, colsel[[3, 1]], s@"Color 3"}, colsel, ct}}]}], 
       Evaluate[
        Sequence @@ 
         MapThread[{{#1, {}, ""}, #2, ControlType -> TogglerBar} &, 
            {#, Partition[Rule @@@ Transpose[{Range[10], soData[[1]]}], perRow]}]]] &@ 
    Array[a, Length[soData[[1]]]/perRow]
    

    enter image description here