Requiring Additional d3 Plugins in d3 v4 Extension: A guide

I am currently working on developing a d3 v4 plugin by following the guidelines provided at . My main objective is to be able to npm install the plugin and seamlessly use it within an Angular 2/4 component.

The repository for my project can be found here:

https://github.com/denisemauldin/d3-timeline

Check out some examples:

One of the challenges I'm facing is integrating other necessary d3 components. The current setup does not provide guidance on utilizing other d3 elements. I specifically require d3.timeFormat, d3.timeHour, d3.scaleOrdinal, d3.schemeCategory, d3.mouse, d3.select, d3.axisTop, d3.axisBottom, and d3.scaleLinear.

These functionalities are part of d3-axis, d3-scale, d3-selection, d3-time, and d3-time-format. I have attempted a couple of approaches:

1) Including them as imports in index.js

 import "d3-axis";
 import "d3-scale";
 import "d3-selection";
 import "d3-time";
 import "d3-time-format";
 export {default as timeline} from "./src/timeline";

2) Integrating them directly in the timeline.js source:

var d3 = Object.assign({}, require("d3-axis"), require("d3-scale"), require("d3-selection"), require("d3-time"), require("d3-time-format"));
(function() {
    d3.timeline = function() {
                //variable definitions
                function timeline (gParent) {};
                //method definitions
                return timeline;
        };
})();
export default d3.timeline;

Currently, the plugin loads successfully in the browser and functions properly, but I am struggling to get the npm install to work in order to create a npm package for usage with my Angular 2 site.

I have experimented with various options in the rollup.config.js file using rollup-plugin-commonjs. I am unsure if this is the correct path as it seems to generate a bundled file containing all the required d3 code. The rollup call (included in the d3 plugin starter bundle) is failing:

rm -rf build && mkdir build && rollup -c -f umd -n d3 -o build/d3-timeline.js -- index.js

'default' is not exported by 'd3-timeline/src/timeline.js' (imported by 'd3-timeline/index.js')

If I remove the rollup.config.js, the same error persists, along with the message:

Treating 'd3-axis' as external dependency
Treating 'd3-scale' as external dependency
Treating 'd3-selection' as external dependency
Treating 'd3-time' as external dependency
Treating 'd3-time-format' as external dependency

So, how can I update the src/timeline.js file to correctly export as default for use with npm install d3-timeline in Angular and also ensure compatibility for browser usage? Alternatively, how should I configure rollup to enable the current src/timeline.js functionality?

Your help is greatly appreciated!

Answer №1

One issue could be that the d3 dependencies should be imported in your src/timeline.js file, not in your rollup.config.js file.

Additionally, make sure to export your timeline function from the src/timeline.js file instead of using an IIFE.

Here is a sample code snippet:

// src/timeline.js
import { axisBottom, axisTop } from 'd3-axis';
import { timeFormat } from 'd3-time-format';
import { timeHour } from 'd3-time';
import { scaleOrdinal, scaleLinear, schemeCategory20 } from 'd3-scale';
import { select } from 'd3-selection';

export default function timeline() {
  // implement your function here...
}

Then in your index.js file, only include:

export { default as timeline } from "./src/timeline";

Lastly, in your package.json file, specify the d3 modules you're using as dependencies:

// in package.json
dependencies: {
  "d3-axis": "^1.0.0",
  "d3-time-format": "^2.0.0",
  "d3-time": "^1.0.0",
  "d3-scale": "^1.0.0",
  "d3-selection": "1.0.0"
}

To get inspiration on configuring d3 plugins, you can check out examples like Susie Lu's plugin d3.legend.

Answer №2

Thanks to the assistance of @clhenrick, I was able to successfully implement this solution. To achieve this, I made modifications to my index.js file by including only the export for timeline.

I then proceeded to update src/timeline.js as follows:

import * as d3 from 'd3';

var timeline = function() { <code> };
export default timeline;

If I attempted to import the d3 packages individually (d3-axis, d3-selection, etc.), I encountered a

Cannot read property 'sourceEvent' of null
error when using the d3.mouse(this) call within the on("click") events.

Next, adjustments were required in my rollup.config.js:

import nodeResolve from 'rollup-plugin-node-resolve';

let pkg = require("./package.json");
let external = Object.keys(pkg.peerDependencies);

export default {
    entry: 'index.js',
    dest: 'bundle.js',
    format: 'umd',
    moduleName: 'd3-timeline',
    external: external,
    plugins: [nodeResolve({ jsnext: true, main: true})]
};

Executing npm install generates a umd module that can be loaded into the browser and incorporates the peerDependencies section (including d3) from the package.json as external dependencies (which prevents them from being included in the d3-timeline.js bundle).

Lastly, I relocated the d3-timeline.js file from the build directory to the dist directory for use in the example HTML files since src/timeline.js is no longer compatible with direct browser usage.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Creating a production-ready installation of Tailwind CSS with Vue 3

Although I primarily develop in Python, I found myself struggling with npm after trying to integrate Tailwindcss with 'Vue 3'. Following the installation steps outlined on the Tailwind+Vue 3 website, I ran into some issues. npm init @vitejs/app m ...

npm install is throwing a permission denied error

After performing a fresh reinstallation of my Ubuntu system and installing essential components like nodejs and npm, I encountered an error when trying to run sudo npm install after cloning a project. Has anyone else experienced a similar issue? System In ...

What is the best way to add query parameters to router.push without cluttering the URL?

In my current project, I am using NextJS 13 with TypeScript but not utilizing the app router. I am facing an issue while trying to pass data over router.push to a dynamically routed page in Next.js without compromising the clarity of the URL. router.push({ ...

Adding TypeScript types to an array within a function parameter: A step-by-step guide

Having some trouble defining the array type: The code below is functioning perfectly: const messageCustomStyles: Array<keyof IAlertMessage> = [ 'font', 'margin', 'padding' ]; r ...

Issues with tracking changes in Vue.js when using reactive variables

After triggering a click event, I am attempting to choose a message from a json file. However, I am encountering an issue where the first click does not seem to select anything. Upon the second click, the selected messages are duplicated, and this pattern ...

Can a custom subscribe() method be implemented for Angular 2's http service?

Trying my hand at angular2, I discovered the necessity of using the subscribe() method to fetch the results from a get or post method: this.http.post(path, item).subscribe( (response: Response)=> {console.log(response)}, (error: any)=>{console.l ...

Utilize the gsap ScrollTrigger in conjunction with React's useRef() and Typescript, encountering issues with type mism

Recently, I've been trying to add some animation to a simple React Component using the GreenSock ScrollTrigger plugin. However, I ran into an issue due to types mismatch in my Typescript project. Here's a snippet of the code: import React, {useRe ...

An error occurred due to a class being instantiated within a module, resulting in an overflow of the

On line 7, the console.log statement prints out correctly. host.js "use strict"; var engine = require('./engine.js'); var base = require('./base.js'); var player = new base.Avatar(); console.log(player.x); class PillarGame extends ...

Error Encountered during Compilation of React TypesIs this okay

Currently, I am working on an MVC project that involves the use of TypeScript. To access the types required for this project, I have also integrated React. To obtain the React types, I performed an npm install --save-dev @types/react (similarly for react-d ...

List of items:1. The first item is elevated in its position

Can anyone explain why the first li item is displaying higher than the rest when I assign an id or class to the div element? Take a look at the code snippet below: <div id="pickList"> <ul *ngFor="let channel of currentPickSelection"> ...

Universal Module Identifier

I'm trying to figure out how to add a namespace declaration to my JavaScript bundle. My typescript class is located in myclass.ts export class MyClass{ ... } I am using this class in other files as well export {MyClass} from "myclass" ... let a: M ...

Securing Single Page Applications

Have you ever wondered how SPA ensure the security of their sites? With all the embedded scripts, it seems like anyone could access and analyze the code. Do you have any thoughts on this? Additionally, when connecting to other web services that require sp ...

"Encountering an 'Access-Control-Allow-Origin' error in the VSCode Debug Console, even though the network tab in Chrome DevTools displays a 200OK

In my Angular 7 project, I encountered an issue while using HttpClient. When I click a button, the following code snippet is executed: this.http .get('http://localhost:30123/api/identity/name/' + this.name) .subscribe((answer: Identit ...

What is causing this CORS error in my Angular request?

I currently have a Controller implemented in Angular 4 that makes a request to the NBA API Stats. When I test this request in Postman, I can see all the data without any issues. However, when I execute the same request in my Angular application, I encounte ...

Encountered an error while trying to install Drivelist: Module 'C:Program Files odejs ode_modules pm ode_modules ode-gypin' not found

My electron project relies on the drivelist dependency. However, when I attempt to run "npm install," I encounter an error indicating that the node-gyp\bin folder is missing. Surprisingly, I do have the node-gyp\bin in my node modules and even in ...

Switch up the CSS variable within an embedded iframe

I'm in a predicament with a specific issue. I am currently utilizing Angular to incorporate an Iframe. Let's imagine the angular app as A and the Iframe as B. B is being loaded within A. Within B, I have utilized CSS variables to define colors. I ...

Elevate your frontend development game with the powerful combination of Vue js 3

I've been attempting to add this dependency, but I keep receiving an error message stating that it doesn't exist and Vue 3 is unable to resolve the component. Click here to visit the npm page for vue-phone-number-input Any assistance you can pr ...

Is Angular4 preloaded with bootstrap library?

I started a new angular4 project and wrote the code in app.component.html <div class="container"> <div class="row"> <div class="col-md-1">.col-md-1</div> <div class="col-md-1">.col-md-1</div> <div class ...

Is it possible to provide unrestricted support for an infinite number of parameters in the typing of the extend function from Lodash

I am utilizing the "extend" function from lodash to combine the objects in the arguments as follows: import { extend } from 'lodash'; const foo1 = { item: 1 }; const foo2 = { item: 1 }; const foo3 = { item: 1 }; const foo4 = { item: 1 }; const f ...

Working with floating point numbers in Node.js with a zero decimal place

NodeJS interprets float values with a zero after the decimal point as integers, but this behavior occurs at the language level. For example: 5.0 is considered as 5 by NodeJS. In my work with APIs, it's crucial for me to be able to send float values w ...