d3 / d3-scale

Encodings that map abstract data to visual representation.
https://d3js.org/d3-scale
ISC License
1.59k stars 286 forks source link

Add type names to scales #274

Closed mhkeller closed 1 year ago

mhkeller commented 1 year ago

Per https://github.com/d3/d3-scale/issues/25#issuecomment-1426350113, this proposal adds a type field to each scale that returns a string name. I called it type for now but have no opinion on what that would end up being. Maybe scaleType or something else is better.

I added tests but, for now, only where the existing defaults were being tested. For example, I didn't immediately see where scales like sequentialLog were being tested for defaults. I can add those tests where most appropriate.

Let me know if you think this is a worthwhile addition. It would definitely help my use case with a minimal footprint on the original library. Thanks for your time in reviewing it.

mhkeller commented 1 year ago

I added a test to check that the type for all scale functions matches

mhkeller commented 1 year ago

@mbostock Just wanted to check if this was something you would consider as a PR. It would be very useful in the chart framework I maintain.

mbostock commented 1 year ago

Apologies but I don’t intend on supporting this for now.

mhkeller commented 1 year ago

Thanks for letting me know

mhkeller commented 1 year ago

@mbostock do you have any advice on differentiating between a scaleTime and scaleUtc? That's the last one I'm stuck on.

mbostock commented 1 year ago

@mhkeller Here’s a hack…

const d = new Date;
d.getDay = () => console.log("time");
d.getUTCDay = () => console.log("utc");
const scale = d3.scaleUtc(); // or d3.scaleTime();
scale.tickFormat(0, "%a")(d);

Basically, override a Date object, and see what methods are called when you try to format it. That way you can tell what the scale type is.

mhkeller commented 1 year ago

Thanks that's much appreciated!

mhkeller commented 1 year ago

For anyone coming across this in the future, I tweaked this slightly so my function would return and added a .copy to preserve any tickFormat set by the user.

const d = new Date;
let s;
d.getDay = () => s = 'time';
d.getUTCDay = () => s = 'utc';

scale.copy().tickFormat(0, '%a')(d);
return s;
mbostock commented 1 year ago

Calling scale.tickFormat doesn’t mutate the scale, so no copy is necessary. It only affects the returned format function, not future calls to scale.tickFormat.