Comments (10)
Thanks, I will update the definitions for d3-geo to reflect the changes with 1.4.0. Once you update the D3 Standard Bundle to use d3-geo 1.4, I will bump that as well.
from d3-geo.
That seems like the expected behavior, as the defaults are null. Or are you saying it should return null instead of undefined? I suppose I am being lazy and treating them as equivalent. I’m not sure whether to fix the documentation to say the defaults are undefined, or to coerce the undefined to null… FWIW, it’s also the case that path.projection(undefined) will set the projection to undefined, and not null, and likewise with path.context.
from d3-geo.
I think there are a couple of things coming together here. One is pertinent to the API doc in and of itself:
The geoPath(...)
API states:
Creates a new geographic path generator with the default settings.
Which when looking at the corresponding API for the .projection(...)
method of the path generator leads one to:
If projection is not specified, returns the current projection, which defaults to null. The null projection represents the identity transformation: the input geometry is not projected and is instead rendered directly in raw coordinates.
and correspondingly for the `.context(...) method:
If a context is not specified, returns the current render context which defaults to null.
The second aspect relates to the expected usage of folks wanting to use all the goodness of D3 with TypeScript. There have been several asks to tie the definitions down to what is referred to as strictNullChecks
when compiling.
As of TypeScript 2, there is support for non-nullable types. I.e. before or without the said compiler option set, e.g, number
is implicitly widened to number | null | undefined
. By implication, developers are left to perform all the usual tests to ensure that variable/objects are not undefined
or null
before using them in operations or accessing members.
The drive behind validating the definitions is obvious, if the definitions reflect the underlying code, and the "contract" is for e.g. number
, then no additional testing code will need to be written to rule out null
or undefined
.
Obviously, libraries may in some cases make a semantic distinction between undefined
and null
, which may be critical in distinguishing "failure" modes of methods/functions.
So it's down to as tight as reasonable contracts that avoid unnecessary validation code, while instead relying on the type-safety of the compiler.
Apologies for the digression, as I said the validation for strictNullChecks
has been raised for the D3 definitions across the board. I have put it off to address other things in the interim.
IMHO, I would lean towards implementing the defaults as null
in line with the already published API, unless that creates some issues I might have overlooked?
from d3-geo.
Hmm. This issue applies quite a bit more generally than just to d3.geoPath.
There are quite a few places in D3 where an accessor expects a function, null or undefined, and will not coerce an undefined value to null. There are also some places that do coerce undefined to null, such as line.context. Generally, I make a minimum effort to validate the input arguments, so the places that replace undefined with null are doing so because they had some reason to check whether the input value was nully. For example, if you pass a nully value to line.context, it means you want to generate an SVG path string rather than render to a CanvasRenderingContext2D, so the line generator checks the specified context and branches the logic as appropriate.
It’s tempting to add some logic to D3 to coerce nully input values to null. But it’s more tempting to verify that non nully input values that should be functions are indeed typeof "function", so that an error can be thrown immediately on set rather than on subsequent use with TypeError: value is not a function. There are a few places where I do perform such type checks, such as d3.dispatch, but it does feel like a rabbit hole in the sense that you can never validate the input types perfectly and I don’t feel like I have a good sense in JavaScript of what degree of input validation is appropriate.
And yet, the nice thing about TypeScript is that this can be done statically rather than burdening the runtime implementation, right? And so all we really need to do is fix the places where D3 internally violates the type constraint (such as in d3.geoPath where it initializes to undefined rather than null)?
from d3-geo.
Apologies for the slight delay in getting back to this.
You are right on both counts, for one, the point I raised above regarding strictNullChecks
-validation is a bit broader than just geoPath(...)
. And secondly, it can be a bit of a rabbit hole 😟 .
That is the primary reason, why I initially deferred it when writing the definitions for the D3 Modules. I went after the low hanging, high value-add fruit first.
Nevertheless, yes, the benefit of "validate-once-compile-time-check-many" can be tremendous, where static type-checking is feasible. In particular, since it is possible to use interfaces, generics and function-signatures to set up fairly specific API contracts, where possible without being unnecessarily restrictive.
So it's the initial bump we are really talking about (e.g. DefinitelyTyped PR 12566 which is a starting point to refine the d3-selection and the modules most tightly coupled to it).
In a large number of cases the D3 API documentation is explicit enough (e.g. the rendering context
related references you made above), in others I found I had to go to the code to see what is being coerced, defaulted or returned in certain well-defined failure modes, like, loosely speaking, "could not be found" or "not applicable".
The new geoPath(...)
factory is an example, where there seems to be a very specific opportunity to narrow down to null
without loss of generality.
As for the broader validation, IMHO the best approach would be to prioritize the modules (in batches as necessary where they are coupled) and set up a mini project:
- to scrub through the API documentation vis-a-vis the corresponding TypeScript definition file,
- flag any line items (method signatures, return values) where it seems non-obvious, and
- decide on the appropriate action (definition refinement, API Doc update, minor code revisions to internally set defaults, whatever seems most appropriate).
Such a coordinated effort (spaced out to not overload anyone with cycles they need for other priorities would be great. Given your natural familiarity with the code and, more importantly, understanding of intent and context, it would be great to structure it with your input.
Open to suggestions.
from d3-geo.
Thanks—this is great feedback. I’m excited that your (and others’) work to support TypeScript will improve D3 even for non-TypeScript users.
from d3-geo.
So how about this: we limit this issue specifically to geoPath(...)
and open a new discussion/strategy issue for the broader topic of integrating/moving forward D3/JS/TS.
You could open up a thread on d3
, I can pour in a basic "level-setting" where the TS2 support is currently at and we can take it from there. You could frame it as widely or narrowly as you see fit.
At the narrow end of the spectrum is the scrub/validation listed above.
At the wider end is the strategic question of bringing the TS definitions into the respective D3 repos, while addressing the narrower needs along the way.
For what it's worth, it's about getting the most symbiotic arrangement for the user community and managing the scope/phasing along the way.
If you opened a thread up in d3
, it could also be set up as a github project in follow-up. One thing a middle of the road contributor to DefinitelyTyped cannot do. I mostly used tracking issues, but bundling them into a project/labels/milestones etc. are not really an option given the extensive shared scope.
from d3-geo.
Will update definitions for d3-geo to allow geoPath(...)
methods context()
and projecttion()
to return union type including both | null | undefined
for purposes of strictNullChecking
.
Corresponds to current behavior of module, no further action expected under this issue.
from d3-geo.
I’m fixing this to be null as we speak.
from d3-geo.
d3-geo definitions are updated and published.
from d3-geo.
Related Issues (20)
- How can I clamp a geodesic to between a max/min latitude? HOT 1
- fit-test.js Remove duplicate test HOT 1
- Geojson to SVG offset HOT 1
- Geojson to SVG offset
- Cannot import d3-geo in node with typescript HOT 8
- Geographic or Geodetic HOT 1
- D3 uses GeoJSON to represent geographic features in JavaScript HOT 2
- postclip with polygon path maybe... HOT 10
- Error [ERR_REQUIRE_ESM]: Must use import to load ES Module / require() of ES modules is not supported HOT 2
- geoAzimuthalEqualArea not rendering straight lines HOT 2
- clipCircle's precision is too low
- Configurable precision for d3.geoPath
- Mercator. Getting boundary values by longitude HOT 2
- Mercator with rotate. Incorrect conversion from projection to geographic coordinates HOT 3
- Сonvert geographic points considering antimeridian and pole HOT 1
- geoContains function doesn't seem to handle MultiPolygons HOT 9
- path.bounds should return numbers even when input coordinates are strings
- [Question] API for chekcing if point is in view or not given projection HOT 3
- Mercator Map centered on the Pacific HOT 1
- geoCircle produces an open LinearRing
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from d3-geo.