How to add a simple SVG using D3 and ES2015 - d3.js

I have a ES2015 project using Webpack. I am trying to add D3v4 so I add the following...
// Typescript
import { select } from 'd3';
...
select(".application").append("svg"); // line 22
I have also tried...
import { select } from 'd3-selection';
But this throws an exception...
ERROR in ./src/main/angular/app/app.component.ts
(22,12): error TS1138: Parameter declaration expected.
What is the correct way to do this? Is there any D3 documentation for ES2015?

Related

Cannot find module even though the cypress test runner is able to mount the component

I am trying to set up component tests with cypress, vue3 and vite. With the Getting Started guide, I was able to successfully mount my component, however in my editor (vscode), it tells me that I cannot find the module or corresponding type declarations ts(2307).
I have added the global styles file in support/component.ts and nothing else.
// Import commands.js using ES2015 syntax:
import "./commands";
// Import global styles
import "../../src/styles/style.scss";
// Alternatively you can use CommonJS syntax:
// require('./commands')
import { mount } from "cypress/vue";
// Augment the Cypress namespace to include type definitions for
// your custom command.
// Alternatively, can be defined in cypress/support/component.d.ts
// with a <reference path="./component" /> at the top of your spec.
declare global {
namespace Cypress {
interface Chainable {
mount: typeof mount;
}
}
}
Cypress.Commands.add("mount", mount);
How do I get rid of the linter warning?

Client-only Nuxt 3 D3 plugin

I'm trying to use the D3 extension in a Nuxt 3 project and for that I created a d3.client.js file in the plugins/ directory.
import * as d3 from "d3";
import { defineNuxtPlugin } from '#app'
export default defineNuxtPlugin(nuxtApp => {
nuxtApp.vueApp.use(d3)
})
However, when I try to use it gives me a 500 Internal Server Error document is not defined.
<script>
import * as d3 from "d3";
export default {
name: "globe",
created() {
d3.select("#globe");
}
}
</script>
How can I solve this?
d3.select() uses document.querySelector() under the hood. Since you're working server side, you don't have access to document yet. So you'll need to mock it or to avoid using it.
You can avoid using it all together by passing an element instead of a string to d3.select(), as it will then create a functioning d3 selection without running document.querySelector(). And since every other chained .select() or .selectAll() uses previousSelection.querySelector(), you can just continue from there.
If you do not have access to the DOM element directly, you might want to mock document. This article suggests using JSDOM:
import { JSDOM } from 'jsdom';
// create a new JSDOM instance for d3-selection to use
const document = new JSDOM().window.document;
d3.select(document.body)
.append('div');
I managed to solve it by using the d3.select with a Vue reference.
const globe = d3.select(this.$refs.globe)

Error constructing an rxjs/Observable

Why does the following TypeScript code compile, but systemjs fails to load the dependencies correctly at runtime?
import { Observable } from 'rxjs';
let temp123 = new Observable<String>();
However, this works:
import { Observable } from 'rxjs/Observable';
let temp123 = new Observable<String>();
Specifically, the first code results in a .js file that contains the code:
var Observable_1 = require('rxjs');
var temp123 = new Observable_1.Observable();
but the second code generates this:
var Observable_1 = require('rxjs/Observable');
var temp123 = new Observable_1.Observable();
the line require('rxjs') fails with a 404 error because there is no file there. Why is the typescript compiler able to resolve this, but systemjs cannot load it at runtime?
Also noteworthy: This problem only happens if I do certain things with the Observable. For example, the following code works:
import { Observable } from 'rxjs';
let temp123: Observable<String> = null;
let xyz = temp123.first();
I can use the Observable, and call methods on it, without the TypeScript compiler generated a require('rxjs'). But I can't construct one, and I can't extend it either.
Versions:TypeScript 2.0.3, Systemjs 0.19.27, rxjs 5.0.0-beta.12
Why is the typescript compiler able to resolve this, but systemjs
cannot load it at runtime?
That's the way it works:
when you write import { Observable } from 'rxjs'; typescript finds rxjs folder in node_modules with package.json in it, which has
"typings": "Rx.d.ts"
that's type declarations file for rxjs, and that file contains
export { Observable } from './Observable';
which makes typescript to find another type declaration file in the same folder, Observable.d.ts, which has exported declaration for Observable class.
That's enough for your code to compile without errors.
If your code does not actually try to use Observable as a value, it will work, because typescript does unused reference elision - if Observable is used for type checking only, as in your second example, there will be no require('rxjs') call in generated javascrpt.
Now, SystemJS.
SystemJS does not have any default location to look for modules - it does not even recognise node_modules convention about package.json file with main property.
So, most likely, SystemJS in your example is configured like this:
SystemJS.config({
paths: {'npm:': 'node_modules/'},
map: {'rxjs': 'npm:rxjs'},
packages: {
rxjs: {
}
}
});
So, the module rxjs/Observable imported by this line
import { Observable } from 'rxjs/Observable';
is mapped to
node_modules/rxjs/Observable.js
because rxjs prefix matches map entry which together with paths maps it to node_modules/rxjs
Observable part comes through as is
.js extension is added because rxjs matches with rxjs package in systemjs config, and for any module that belongs to a package, SystemJS adds .js extension automatically unless defaultExtension is set to something else in that package config.
And it works, because the file node_modules/rxjs/Observable.js exists.
And that import works with typescript too, because node_modules/rxjs/Observable.d.ts exists too.
Finally, this does not work at runtime
import { Observable } from 'rxjs';
because it's mapped to node_modules/rxjs url, and there is no actual file there.
You can fix it by using main property in SystemJS package config:
packages: {
rxjs: {
main: 'Rx.js'
}
}
Now it's mapped to node_modules/rxjs/Rx.js, and that file actually exists and exports something named Observable, so it should work.
Checked with SystemJS 0.19.43, rxjs 5.0.3, typescript 2.1.5.

d3 V4.2.1 TypeScript 2.0 error importing d3-selection-multi

I am trying to import d3 v4 into a typescript project using jspm and systemjs. I can get d3 imported correctly using this
import * as d3 from 'd3';
This works and it allows me to make selections etc. I tried using the attr function and passing it an object which did not work. I found that d3 v4 includes that as a separate module.
After downloading that module d3-selection-multi with jspm. I try to import it into my project like so.
import * as d3 from 'd3';
import 'jspm_packages/npm/d3-selection-multi#1.0.0';
I then try and use the attrs function but the console logs the following error
(index):40 Error: (SystemJS)
d3.selectAll(...).data(...).style(...).attrs is not a function(…)
I am also getting some compile error which i get all the time but yet they always still compile and the code runs
error TS2307: Cannot find module 'd3'
error TS1110: Type expected
Can any one explain what I am doing wrong and offer a solution?
The following should work
import * as d3 from 'd3';
import 'd3-selection-multi';
I ended up having to create a 'bundle' file and import that instead of importing individual d3 packages. This is probably not ideal, but it works (I've commented out packages which I do not need, in order to save on space):
// export * from 'd3-array';
// export * from 'd3-axis';
// export * from 'd3-brush';
// export * from 'd3-chord';
// export * from 'd3-collection';
// export * from 'd3-color';
// export * from 'd3-dispatch';
// export * from 'd3-drag';
// export * from 'd3-dsv';
// export * from 'd3-ease';
// export * from 'd3-force';
// export * from 'd3-format';
// export * from 'd3-geo';
// export * from 'd3-hierarchy';
// export * from 'd3-interpolate';
// export * from 'd3-path';
// export * from 'd3-polygon';
// export * from 'd3-quadtree';
// export * from 'd3-queue';
// export * from 'd3-random';
// export * from 'd3-request';
// export * from 'd3-scale';
export * from 'd3-selection';
export * from 'd3-selection-multi';
export * from 'd3-shape';
// export * from 'd3-time';
// export * from 'd3-time-format';
// export * from 'd3-timer';
// export * from 'd3-transition';
// export * from 'd3-voronoi';
// export * from 'd3-zoom';
To use this, I just have to:
import * as D3 from './d3.bunde.ts';
P.S. Probably doesn't matter, but I'm building my project using angular-cli.
Working "jspm + d3-selection-multi" example: https://github.com/jakeNiemiec/jspm_d3
If you need to import all of D3, use jspm install npm:d3. This will add quite a bit of bloat. Remember that jspm comes with rollup, take a look at the build script in package.json.

Call a method of a web component and respond to events

I'm working on a Dart project where I have created a custom element with the Web_ui package that has some animation. What I was hoping to do is to have within the dart code for the element something like this....
class MyElement extends WebComponent {
...
void StartAnimation() { ... }
...
}
and then in the main() function of the dart app itself I have something like this...
void main() {
MyElement elm = new MyElement();
elm.StartAnimation(); // Kicks off the animation
}
The Dart editor tells me that Directly constructing a web component is not currently supported. It then says to use WebComponent.forElement -- but I'm not clear on how to use that to achieve my goal.
While you can't yet import web components into a Dart file, you can access them via query() and .xtag. xtag gives you a reference the web component instance that the element is associated with. You do have to be careful that you allow the Web UI setup to complete so that xtag is given a value.
Here's an example:
import 'dart:async';
import 'dart:html';
import 'package:web_ui/web_ui.dart';
main() {
Timer.run(() {
var myElement = query('#my-element').xtag;
myElement.startAnimation();
});
}
This will get better with the ability to import components, directly subclass Element and maybe some lifecycle events that guarantee that you get the correct class back from a query(). This is what the exemple should look like in the future:
import 'dart:async';
import 'dart:html';
import 'package:web_ui/web_ui.dart';
import 'package:my_app/my_element.dart';
main() {
MyElement myElement = query('#my-element');
myElement.startAnimation();
}

Resources