dc.js icon indicating copy to clipboard operation
dc.js copied to clipboard

DataTable - cleanup - fragile code

Open kum-deepak opened this issue 4 years ago • 4 comments

_doColumnHeaderFnToString (https://github.com/dc-js/dc.js/blob/develop/src/charts/data-table.js#L92) is quite fragile.

https://github.com/dc-js/dc.js/blob/82469c9c9cdc27bdca1d5b1b4f1e8ac79c41f9d9/src/charts/data-table.js#L92-L107

It is there to maintain backward compatibility in the columns argument.

Currently, the chart supports three different ways (http://dc-js.github.io/dc.js/docs/html/DataTable.html#columns__anchor) to specify columns. I think we can drop the only functions option and stick to the other two. Even though possible to maintain current behavior in the compat layer, since the code is quite fragile we should not offer backward compatibility.

kum-deepak avatar Jul 18 '20 15:07 kum-deepak

I agree this is horrible code and should be removed.

The story is that the original .columns() only took an array of functions, and it didn't generate the table header automatically. At that time, the user had to provide a table element with headers already in it.

When automatic generation of the header was added in #560 / #668, the author added this code to allow a mixture of functions, string field names, and full column definitions. I remember discussing this fragile code, and the author pointing out that it does work across browsers, but I can't find that discussion now.

Note that the all-function case is special:

https://github.com/dc-js/dc.js/blob/82469c9c9cdc27bdca1d5b1b4f1e8ac79c41f9d9/src/charts/data-table.js#L117-L122

(could be cleaned up with Array.every)

I'd prefer to deprecate and move the fragile code to the compatibility layer, but if you can't conscience that, we could disallow functions when there is a mix while still preserving compatibility with old examples. Hopefully the mixed case isn't used all that much.

gordonwoodhull avatar Jul 21 '20 16:07 gordonwoodhull

I'm all for deprecate and replace with good design. 560/668 was just trying to make programmability possible without the needed rewrite.

Chris aka mr23 aka ChrisMeierRT

mr23 avatar Jul 21 '20 21:07 mr23

Thanks @mr23, the design for column headers has held up really well over all these years. It's just the reading of the text of the function that is fragile. I agree that there's no other way to automatically determine the column name from just a function.

Well, there is one other way: if the functions aren't arrow functions, they could have names, like

dataTable.columns([
    function date(d) { return d.date; },
    function open(d) { return d.open; },
    function close(d) { return d.close; },
    function change(d) { return numberFormat(d.close - d.open); },
    {
      name: 'volume',
      format: d => d.volume;
    }
]);

I don't know if it's worth pursuing - it's not backward-compatible but it allows another terse way to specify columns.

gordonwoodhull avatar Jul 22 '20 07:07 gordonwoodhull

We should recommend the following syntax, which is explict at the same quite succint:

chart.columns([
    "date",    // d["date"], ie, a field accessor; capitalized automatically
    "open",    // ...
    "close",   // ...
    {
        label: "Change",
        format: function (d) {
            return numberFormat(d.close - d.open);
        }
    },
    "volume"   // d["volume"], ie, a field accessor; capitalized automatically
]);

The other alternate we should move to the compat layer. I will do a PR when I through with the current round of typings.

kum-deepak avatar Jul 22 '20 12:07 kum-deepak