npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

d3-component

v3.1.0

Published

A D3 component system.

Downloads

117

Readme

d3-component

A lightweight component abstraction for D3.js.

Features:

Examples:

Using this component abstraction, you can easily encapsulate data-driven user interface components as conceptual "boxes-within-boxes", cleanly isolating concerns for various levels of your DOM tree. This component abstraction is similar in concept and functionality to React Stateless Functional Components. Everything a component needs to render itself and interact with application state gets passed down through the component tree at render time. Components don't store any local state; this is the main difference between d3-component and the Towards Reusable Charts pattern. No special treatment is given to events or event delegation, because the intended use is within a unidirectional data flow architecture like Redux.

Installing

If you use NPM, npm install d3-component. Otherwise, download the latest release. You can also load directly from unpkg.com as a standalone library. AMD, CommonJS, and vanilla environments are supported. In vanilla, a d3 global is exported:

<script src="https://unpkg.com/d3@4"></script>
<script src="https://unpkg.com/d3-component@3"></script>
<script>
  var myComponent = d3.component("div");
</script>

API Reference

Note: There was a recent major version release, and along with it there were substantial API Changes.

In summary, the API looks like this:

var myComponent = d3.component("div", "some-class")
  .create((selection, d, i) => { ... }) // Invoked for entering component instances.
  .render((selection, d, i) => { ... }) // Invoked for entering AND updating component instances.
  .destroy((selection, d, i) => { ... }); // Invoked for exiting instances, may return a transition.

// To invoke the component,
d3.select("body") // create a selection with a single element,
  .call(myComponent, "Hello d3-component!"); // then use selection.call().

To see the full API in action, check out this "Hello d3-component" example.

# component(tagName[, className]))

Creates a new component generator that manages and renders into DOM elements of the specified tagName.

The optional parameter className determines the value of the class attribute on the DOM elements managed.

# component.create(function(selection, d, i))

Sets the create function of this component generator, which will be invoked whenever a new component instance is created, being passed a selection containing the current DOM element, the current datum (d), and the index of the current datum (i).

# component.render(function(selection, d, i))

Sets the render function of this component generator. This function will be invoked for each component instance during rendering, being passed a selection containing the current DOM element, the current datum (d), and the index of the current datum (i).

# component.destroy(function(selection, d, i))

Sets the destroy function of this component generator, which will be invoked whenever a component instance is destroyed, being passed a selection containing the current DOM element, the current datum (d), and the index of the current datum (i).

When a component instance gets destroyed, the destroy function of all its children is also invoked (recursively), so you can be sure that this function will be invoked before the compoent instance is removed from the DOM.

The destroy function may optionally return a transition, which will defer DOM element removal until after the transition is finished (but only if the parent component instance is not destroyed). Deeply nested component instances may have their DOM nodes removed before the transition completes, so it's best not to depend on the DOM node existing after the transition completes.

# component.key(function)

Sets the key function used in the internal data join when managing DOM elements for component instances. Specifying a key function is optional (the array index is used as the key by default), but will make re-rendering more efficient in cases where data arrays get reordered or spliced over time.

# component(selection[,data[,context]])

Renders the component to the given selection, a D3 selection containing a single DOM element. A raw DOM element may also be passed in as the selection argument. Returns a D3 selection containing the merged Enter and Update selections for component instances.

  • If data is specified and is an array, one component instance will be rendered for each element of the array, and the render function will receive a single element of the data array as its d argument.
    • Useful case: If data is specified as an empty array [], all previously rendered component instances will be removed.
  • If data is specified and is not an array, exactly one component instance will be rendered, and the render function will receive the data value as its d argument.
  • If data is not specified, exactly one component instance will be rendered, and the render function will receive undefined as its d argument.

In summary, components can be rendered using the following signatures:

  • selection.call(myComponent, dataObject) → One instance, render function d will be dataObject.
  • selection.call(myComponent, dataArray)dataArray.length instances, render function d will be dataArray[i]
  • selection.call(myComponent) → One instance, render function d will be undefined.

If a context object is specified, each data element in the data array will be shallow merged into a new object whose prototype is the context object, and the resulting array will be used in place of the data array. This is useful for passing down callback functions through your component tree. To clarify, the following two invocations are equivalent:

var context = {
  onClick: function (){ console.log("Clicked!");
};
selection.call(myComponent, dataArray.map(function (d){
  return Object.assign(Object.create(context), d);
}));
var context = {
  onClick: function (){ console.log("Clicked!");
};
selection.call(myComponent, dataArray, context);