Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DataTable - cleanup - fragile code #1721

Open
kum-deepak opened this issue Jul 18, 2020 · 4 comments
Open

DataTable - cleanup - fragile code #1721

kum-deepak opened this issue Jul 18, 2020 · 4 comments
Labels
Milestone

Comments

@kum-deepak
Copy link
Collaborator

kum-deepak commented Jul 18, 2020

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

_doColumnHeaderFnToString (f) {
// columnString(f) {
let s = String(f);
const i1 = s.indexOf('return ');
if (i1 >= 0) {
const i2 = s.lastIndexOf(';');
if (i2 >= 0) {
s = s.substring(i1 + 7, i2);
const i3 = s.indexOf('numberFormat');
if (i3 >= 0) {
s = s.replace('numberFormat', '');
}
}
}
return s;
}

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 kum-deepak added this to the dc-v5 milestone Jul 18, 2020
@gordonwoodhull
Copy link
Contributor

gordonwoodhull commented Jul 21, 2020

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:

let bAllFunctions = true;
this._columns.forEach(f => {
bAllFunctions = bAllFunctions & (typeof f === 'function');
});
if (!bAllFunctions) {

(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.

@mr23
Copy link
Contributor

mr23 commented Jul 21, 2020 via email

@gordonwoodhull
Copy link
Contributor

gordonwoodhull commented Jul 22, 2020

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.

@kum-deepak
Copy link
Collaborator Author

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants