TypeScript and d3 domain type - d3.js

I have a problem, when I want to use domain.
So, I try to use next part of my code
var x = d3.time.scale()
.domain([new Date('2016-06-10'), new Date('2016-06-25')])
.rangeRound([0, 1000]);
And I get error about error types for domain...
Argument of type 'Scale' is not assignable to parameter of type 'Scale'.
Types of property 'domain' are incompatible.
Type '{ (): Date[]; (dates: number[]): Scale; (dates: Date[]): Scale; }' is not assignable to type '{ (): number[]; (values: number[]): Scale; }'.
Type 'Date[]' is not assignable to type 'number[]'.
Type 'Date' is not assignable to type 'number'.
But If we look d3 typings
domain(): Date[];
domain(dates: number[]): Scale<Range, Output>;
domain(dates: Date[]): Scale<Range, Output>;
domain can take Date array!
If we disable types, then all works fine.
And I have similar problem with another part of my code:
var drag = d3.behavior.drag()
.on('drag', function (d) {
d3.event.sourceEvent.stopPropagation();
})
.on('dragstart', function () {
//
});
I get error about:
Property 'sourceEvent' does not exist on type 'Event | BaseEvent'.
But If we look in types
export var event: Event | BaseEvent;
and
interface BaseEvent {
type: string;
sourceEvent?: Event;
}
I use typings:
"d3": "registry:dt/d3#0.0.0+20160614091820"
and awesome-typescript-loader for webpack
So, what's wrong with me?

Is your intent to use D3 v4 or D3 v3?
The code snippets you posted seem to imply D3 v3. In line with what Jake said.
There are current D3 version 4 definitions available, assuming you are using TypeScript 2.
The repo he referenced has been completely migrated to DefintitelyTyped (currently types-2.0 branch), we had mostly used it for collaborative development, while the ecosystem was still in flux...
Now to get the definitions by module simply use
npm install #types/d3-selection --save (or --save-dev if you do not publish for third party use)
As of yesterday, npm install #types/d3 --save will also get you definitions corresponding to the Standard D3 Bundle.
There was some technical debt in the publication process from DefinitelyTyped to npm #types as we did not want to break libraries that still needed the legacy D3 v3.5 definitions. This is now resolved.
Once you install the relevant definitions, you simple use TypeScript/ES6 import statements for the corresponding D3 modules (or the d3 standard bundle).
import { select, Selection } from 'd3-selection';
import * as d3Drag from 'd3-drag';
Or similar. You can also create your own TypeScript module to bundle as subset of the modules, if it makes it more convenient for you see my answer to https://stackoverflow.com/questions/40314024/typescript-d3-v4-import-not-working
Things are slightly different, if you want to use the definitions in a vanilla script with a global
If that is your use case let me know, and I can add more info.

This happened to me yesterday using Typescript 2.0 and the latest #types/d3-drag.
I think its just an issue with the typings, check here for updates: https://github.com/tomwanzek/d3-v4-definitelytyped/issues
My crud band-aid:
let drag:any = d3.behavior.drag()...

Related

Does the main D3 module namespace not get updated with bleeding edge submodule additions?

I'm trying to use d3.group, a very new addition to the d3-array submodule that got released a few days ago. I am using a yarn/webpack workflow and import statements to pull in D3 like so:
import * as d3 from 'd3';
However, when I tried to use d3.group, it didn't work.
console.log(d3.group)
Returns undefined.
I to solve this, I had to install the newest version of d3-array and assign that to a new namespace.
import * as d3Array from 'd3-array';
console.log(d3Array.group)
This successfully returned the function.
So my question is, when Bostock or the other D3 developers update the submodules, do the updates not get added to the main D3 namespace until a major update? Is it necessary to pull from the submodules every time I want to use a really new feature?
Considering that the newest d3-array is not it on the latest d3 bundle, and you're using webpack/yarn
You can easily loads the modules on the d3.*, install the latest modules and wrap then together,
example:
// select all your d3 modules and save it on d3.js
// then load it on your script -> import d3 from './d3';
import { select, selectAll } from 'd3-selection'
import { group } from 'd3-array'
const d3 = Object.assign(
{},
{
select,
selectAll,
group,
}
)
export default d3;
ref: https://www.giacomodebidda.com/how-to-import-d3-plugins-with-webpack/

d3 liquidfilledguage does not work with d3 version 4

specifically, it fails on this code:
waveGroup.attr('transform','translate('+waveGroupXPosition+','+waveRiseScale(0)+')')
.transition()
.duration(config.waveRiseTime)
.attr('transform','translate('+waveGroupXPosition+','+waveRiseScale(fillPercent)+')')
.each("start", function(){wave.attr('transform','translate(1,0)'); });
Where waveGroup results from a call to d3.select and is a d3 object.
the fail occurs on the call to ".each" which has apparently changed in d3 version 4. It nolonger accepts a string as the first parameter.
The error is "callback.call is not a function"
Simply removing the first parameter causes errors elsewhere.
Is their a version of liquidfilledguages what works with d3 version 4?
I am assuming you are referring to this
Use this change log to migrate from v3 to v4.
change .each("start", ... ) to .on("start",....)
Along with that you need to do all the migration changes.

How to get isHealthDataAvailable from angular2 nativescript using api

Since that is no nativescript support with ios HealthKit..I am trying to work with the api.
To start I am trying to get a simple bool for isHealthDataAvailable():
How?
declare var NSBundle: any;
constructor() {
if (Platform.isIOS){
let healthStore = NSBundle.mainBundle.HKHealthStore();
let is_avail = healthStore.isHealthDataAvailable();
}
}
(in promise): TypeError: NSBundle.mainBundle.HKHealthStore is not a function. (In 'NSBundle.mainBundle.HKHealthStore()', 'NSBundle.mainBundle.HKHealthStore' is undefined)
This is a quote from NativeScript:
https://www.nativescript.org/blog/how-to-enable-healthkit-in-your-nativescript-application
var healthStore = HKHealthStore.new();
And this is how to use HealthKit API in NativeScript. Yes, it is THAT simple.
I beg differ...
That's not where HKHealthStore lives, please see my answer to your other question where I suggest you install the platform declarations (npm i tns-platform-declarations --save-dev). It will help you tremendously: nativescript, angular2 and heaththkit - HKHealthStore not found;
To answer this question: it should be HKHealthStore.isHealthDataAvailable() as can be seen in the screenshot below (which is a snippet of those aforementioned TypeScript declarations for iOS:
You will need to use the proper syntax for data conversion (between the Objective-C Apple API and JavaScript) as described here
e.g.
var healthStore = HKHealthStore.new();
Great detailed step by step explanation can be found in this blog post

Fable D3 map sample

I'm trying to run a Fable D3 map sample and I see it requires a browser server module.
When I try to
npm run build
under the d3 folder it compiles
npm run build
> # build C:\...\d3
> node ../node_modules/fable-compiler
fable-compiler 0.7.50: Start compilation...
Compiled fable-import-d3\Fable.Import.D3.js at 03:00:47
Compiled d3\d3map.js at 03:00:48
Bundling...
Bundled out\bundle.js at 03:00:48
but then after
npm start
the browser at http://localhost:8080/ gets an Uncaught Error, SCRIPT5009 'Symbol' not defined:
if (typeof globalObj.__FABLE_CORE__ === "undefined") {
globalObj.__FABLE_CORE__ = {
types: new Map(),
symbols: {
reflection: Symbol("reflection"),
}
};
Edit
above problem was only related to IE11 (not to Chrome) and it's solved by adding
<script src="node_modules/core-js/client/core.js"></script>
in index.html
Now both IE11 and latest Chrome version raise
queue.v1.js:14 Uncaught Error
at newQueue (queue.v1.js:14)
at queue (queue.v1.js:109)
at d3.d_map (d3map.fsx:201)
at d3map.fsx:201
where queue.v1.js:14 is
function newQueue(concurrency) {
if (!(concurrency >= 1)) throw new Error;
because concurrency is zero... (all this refers to fable-compiler 0.7.50).
The server module is just a custom local server to host the sample. Fable 1.0 beta integrates with Webpack and Webpack Dev Server so that's not necessary. I've updated the d3 sample here, can you please give it a try? The new sample also includes the transform-runtime Babel plugin which automatically inserts the necessary polyfills (like Symbol) in your bundle so you don't have to worry about the core.js dependency :)
I've solved the error (queue.v1.js:14 Uncaught Error) in my edit (for fable-compiler 0.7.50) by defining (line 33)
let queue = importDefault<int->obj> "queue"
with int instead of unit and then calling
queue(2)
at line 201 instead of the empty c.tor queue()
Alternative, more elegant solution
As per line 33 of the new d3 sample linked to Alfonso Garcia-Caro's answer, we can just replace the queue definition with
let queue() = importDefault "queue"
and then use the simple queue() c.tor without arg
minor note
Notice that restoring the old line with
let queue = importDefault<unit->obj> "queue"
into the new sample with Fable 1.0 (integrated with Webpack Dev Server) doesn't cause any error. Oddly enough, IMHO it's only a strange behavior of the importDefault in fable-compiler 0.7.50

Typescript Type definition for d3 sankey

I have some javascript code which uses d3 sankey plugin for creating a chart. In my new project, I need to reuse the same code, but the new project is in typescript. I am looking for a DefinitelyTyped file for the plugin. I browsed through https://github.com/DefinitelyTyped/DefinitelyTyped, but couldn't find it.
Is there any other location where I can get this file from?
Sankey plugin link: https://github.com/d3/d3-sankey
Also, without a d.ts file for this plugin, is there a way to access it through typescript?
The code in d3 plugin looks something like this:
d3.sankey = function () {
// Rest of the code goes here
}
The way I use it in javascript is as below:
d3.sankey().nodeWidth(30).size([100,100]);
Would appreciate any help or guidance.
Thanks!
As a heads-up, I have just submitted a Pull Request #16051 to DefinitelyTyped which contains TS definitions for d3-sankey.
Once they are merged, they will be published as per standard process to npm/#types. I.e. npm install --save-dev #types/d3-sankey will do.
IMPORTANT: When I wrote them up, I noticed that the current API documentation in the d3-sankey repo appears to be in some need of rectification (e.g. missing methods, mentioning of accessor functions, which are not used in the code base)
When I have a second, I will file an issue there/submit a PR.
UPDATE (2017-05-01):
The "official" TypeScript definitions for d3-sankey are now available (see npm #types/d3-sankey). Simply use them with npm as indicated above.
The PR to update the actual API documentation of d3-sankey to reflect the source code is still awaiting a merge here.
You need to expand the definition of the d3 type to include the sankey() method and the methods it accepts.
At the absolute minimum, you need to extend the d3 module with a declaration file to make clear that d3 has been extended with the d3-sankey module. You do so by creating a definition file that you place within the #types directly with the following contents:
declare module 'd3' {
export function sankey(...args[]) : any;
}
This tells TS that there is a d3 module, and that it exports the function listed. If the d3 module already exists, it extends that module.
So you can then import the d3 service and use it:
import dd3 = require('d3');
dd3.sankey();
If you want to expand on the type file, you instead write the definition file as so:
declare module 'd3' {
interface ISankey {
nodeWidth() : number;
nodeWidth(width : number|{(arg: number) : number}) : void;
// Add Other d3.sankey Methods Here
}
export function sankey() : ISankey;
}

Resources