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

adopt InternMap for ordinal scales #237

Merged
merged 3 commits into from Jun 5, 2021
Merged

adopt InternMap for ordinal scales #237

merged 3 commits into from Jun 5, 2021

Conversation

Fil
Copy link
Member

@Fil Fil commented Mar 15, 2021

No description provided.

@Fil Fil requested a review from mbostock March 15, 2021 10:35
Copy link
Contributor

@curran curran left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I notice that when I run npm test on this branch, there are 6 failing tests.

$ npm test |grep "not ok"

src/index.js → dist/d3-scale.js...
created dist/d3-scale.js in 286ms

src/index.js → dist/d3-scale.min.js...
created dist/d3-scale.min.js in 1.2s
not ok 699 should be equal
not ok 702 should be equal
not ok 703 should be equal
not ok 719 should be equivalent
not ok 721 should be equal
not ok 722 should be equal

@Fil
Copy link
Member Author

Fil commented Mar 15, 2021

Yes it fails because keys were coerced to strings, but now we can distinguish 0 and "0"—which risks to break a lot of applications.

A solution is to keep coercing everything to string when looking in the index:

diff --git a/src/ordinal.js b/src/ordinal.js
index f4513c5..0a34644 100644
--- a/src/ordinal.js
+++ b/src/ordinal.js
@@ -10,19 +10,21 @@ export default function ordinal() {
       unknown = implicit;

   function scale(d) {
-    if (!index.has(d)) {
+    const key = "" + d;
+    if (!index.has(key)) {
       if (unknown !== implicit) return unknown;
-      index.set(d, domain.push(d));
+      index.set(key, domain.push(d));
     }
-    return range[(index.get(d) - 1) % range.length];
+    return range[(index.get(key) - 1) % range.length];
   }

   scale.domain = function(_) {
     if (!arguments.length) return domain.slice();
     domain = [], index = new InternMap();
     for (const value of _) {
-      if (index.has(value)) continue;
-      index.set(value, domain.push(value));
+      const key = "" + value;
+      if (index.has(key)) continue;
+      index.set(key, domain.push(value));
     }
     return scale;
   };

This fixes the tests, but then it's not better than the current implementation…

@curran
Copy link
Contributor

curran commented Mar 15, 2021

now we can distinguish 0 and "0"—which risks to break a lot of applications.

This feels like a highly desirable breaking change that merits a major version bump on d3-scale.

@mbostock
Copy link
Member

We could pass String as the second argument to the InternMap constructor, but I think the whole goal here is to rely on valueOf instead of string coercion. Making it a major version bump sounds fine to me, although it’ll be a pain to update hundreds of notebooks for such a tiny change.

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

Successfully merging this pull request may close these issues.

None yet

3 participants