PrettyTables.jl icon indicating copy to clipboard operation
PrettyTables.jl copied to clipboard

Merge cells in HTML

Open gitboy16 opened this issue 4 years ago • 9 comments
trafficstars

Hi, Thank you for implementing HTML. I was wondering if it is possible to merge cells in a HTML?

Example here:https://www.computerhope.com/issues/ch001655.htm

In R for example, there is the flextable package which allows these type of things but also much more. https://davidgohel.github.io/flextable/

Thank you

gitboy16 avatar May 20 '21 10:05 gitboy16

Hi @gitboy16

Thank you for implementing HTML. I was wondering if it is possible to merge cells in a HTML?

Nice, I am glad it is being useful! :)

Given that example, it should be easy to implement. The problem is developing a good API that must be the same in all backends. I will think about it.

ronisbr avatar May 20 '21 15:05 ronisbr

Btw, do you have any suggestion about the API? How can we define that two cells must be merged? This definition has been very difficult for me.

I thought about something like:

merge_cells = ((1, 3) => (2, 2), (4, 5) => (3, 2))

which will merge the cell (1,3) into a 2 x 2 block, and the cell (4, 5) into a 3 x 2 block.

ronisbr avatar May 20 '21 19:05 ronisbr

I was thinking about something similar to flextable. See https://ardata-fr.github.io/flextable-book/format.html#usual-functions-for-formatting

Section 4.3 Usual functions for formatting. A function like merge_v(j = "eye") which merge words which are the same assuming the table is already sorted. So basically you just pass the column name or number as argument and the function merge row which are the same. The API of flextable is very flexible that is why I provided it as an example.

gitboy16 avatar May 20 '21 20:05 gitboy16

Thanks, I will analyze the API of flexible.

ronisbr avatar May 20 '21 20:05 ronisbr

Hey @ronisbr , know you are busy but any updates on this piece?

Thanks!

TheCedarPrince avatar Oct 06 '22 03:10 TheCedarPrince

Hi @TheCedarPrince !

Now that we have v2, I will start thinking about this issue. We need to develop a good API that works in all backends.

ronisbr avatar Oct 06 '22 23:10 ronisbr

@ronisbr , would you wanna do a Discourse discussion on this or keep it to this issue? Happy to try thinking on an API for this as well!

TheCedarPrince avatar Oct 11 '22 14:10 TheCedarPrince

So, to "fake" merged tables, what I have been doing is this kind of process:

data = Any["0 - 9" "0.24 (0.0)" "0.14 (0.0)" "0.14 (0.1)" "0.06 (0.08)" "0.27 (-0.03)" "0.16 (-0.02)" "N/A" "N/A"; "10 - 19" "1.51 (0.0)" "1.53 (0.0)" "0.99 (0.52)" "0.99 (0.54)" "3.04 (-1.53)" "2.27 (-0.74)" "0.22 (1.29)" "N/A"; "20 - 29" "4.38 (0.0)" "2.82 (0.0)" "5.73 (-1.35)" "1.6 (1.22)" "4.27 (0.11)" "3.26 (-0.44)" "N/A" "0.69 (2.13)"; "30 - 39" "4.78 (0.0)" "5.68 (0.0)" "4.77 (0.01)" "2.78 (2.9)" "4.95 (-0.17)" "5.12 (0.56)" "N/A" "0.8 (4.88)"; "40 - 49" "4.08 (0.0)" "7.27 (0.0)" "3.96 (0.12)" "4.21 (3.06)" "6.06 (-1.98)" "9.53 (-2.26)" "N/A" "2.14 (5.13)"; "50 - 59" "3.38 (0.0)" "5.44 (0.0)" "3.04 (0.34)" "4.25 (1.19)" "3.83 (-0.45)" "7.35 (-1.91)" "N/A" "N/A"; "60 - 69" "1.59 (0.0)" "2.2 (0.0)" "1.15 (0.44)" "1.57 (0.63)" "1.76 (-0.17)" "3.35 (-1.15)" "N/A" "N/A"; "70 - 79" "0.71 (0.0)" "0.91 (0.0)" "0.29 (0.42)" "0.4 (0.51)" "0.36 (0.35)" "0.81 (0.1)" "N/A" "N/A"; "80 - 89" "0.39 (0.0)" "0.48 (0.0)" "N/A" "0.29 (0.19)" "N/A" "N/A" "N/A" "N/A"]

header = [" ", "White", " ", "Black or African American", " ", "Other Race", " ", "Asian", " "]

subheader = ["Age Groups", "Male Prev. (%)", "Female Prev. (%)", "Male Prev. (%)", "Female Prev. (%)", "Male Prev. (%)", "Female Prev. (%)", "Male Prev. (%)", "Female Prev. (%)"]

And then to fake the combined headers:

    open("test.html", "w") do pic
        pretty_table(
            pic,
            data;
            backend=Val(:html),
            header=(header, subheader),
            alignment=:l,
            maximum_columns_width="200px",
            highlighters = hl_diffs,
            standalone=true
        )
    end

Which produces the following kind of image:

depression_diff_table

So, I guess there is a couple questions:

  1. Should merging of cells occur only in headers?
  2. Should the API apply to subheaders?

image

  1. Should all options above be supported?

In terms of a possible API, I think the "length" of the headers must match the number columns initially. But then maybe there could be a sort of header dictionary like this that operates on the header key word:

# For a matrix with 5 columns
header = Dict("label1" => 1:2, "label2" => 3:5)
subheader = Dict("subheader1" => 1:4, "subheader2" => 5)

        pretty_table(
            data;
            backend=Val(:html),
            header=(header, subheader),
            alignment=:l,
        )

Rather than adding a new keyword, this could add a new dispatch on the header kwarg (trying to think in terms of simplicity + testing + ergonomics). What do you think?

P.S. That wkhtml workflow works so well you suggested - using that above table I generated at a conference this week. :smile:

TheCedarPrince avatar Oct 11 '22 14:10 TheCedarPrince

@ronisbr , would you wanna do a Discourse discussion on this or keep it to this issue? Happy to try thinking on an API for this as well!

We can discuss it here, no problem!

Should merging of cells occur only in headers?

I think we should develop an API that can support merging cells anywhere (headers, subheaders, tables cells, etc.).

Hence, IMHO, the API should be general enough to support merging cells horizontally and vertically in any table cell.

However, to make things easier, we can develop the feature in some stages:

  1. Only allow merging cells horizontally and in the header / subheader.
  2. Only allow merging cells horizontally in all table cells.
  3. Allow vertical merge.

Rather than adding a new keyword, this could add a new dispatch on the header kwarg (trying to think in terms of simplicity + testing + ergonomics). What do you think?

The problem is that every time we want only one merged cell, we need to change completely how we declare the header.

My proposal is to create a new keyword like merge_header_cells_horizontally = [(1, 2, 2), (2, 3, 2)]. The tuple inside the keyword is (i, j, n), which means horizontally merge the cells (i, j), (i, j + 1), (i, j + 2), ..., (i, j + n). The value that will be used will always be that of the first merged cell, including the alignment. What do you think?

P.S. That wkhtml workflow works so well you suggested - using that above table I generated at a conference this week. 😄

Perfect! I am glad to know :)

ronisbr avatar Oct 11 '22 17:10 ronisbr