Giter Site home page Giter Site logo

d3-selection-multi's Introduction

d3-selection-multi

This module adds multi-value syntax to selections and transitions, allowing you to set multiple attributes, styles or properties simultaneously with more concise syntax. For example:

d3.select("body").append("div")
    .attrs({
      title: "A cheery, timeless greeting.",
      class: "greeting"
    })
    .text("Hello, world!");

This is equivalent to:

d3.select("body").append("div")
    .attr("title", "A cheery, timeless greeting.")
    .attr("class", "greeting")
    .text("Hello, world!");

Like selection.attr, the values in the multi-value object can be functions of data:

d3.select("body").append("div")
    .attrs({
      title: function(d) { return d.title; },
      id: function(d, i) { return "id-" + i; },
    });

Alternatively, you can pass a function which returns an object, allowing you to share some computational effort across multiple attributes, or to determine which attribute to set dynamically:

d3.select("body").append("div")
    .attrs(function(d, i) { return {title: d.title, id: "id-" + i}; });

This module is not included in the default D3 bundle for parsimony’s sake: the single-value methods such as selection.attr are recommended for most users, as there is little benefit to the shorter syntax provided by these convenience method.

Installing

If you use NPM, npm install d3-selection-multi. Otherwise, download the latest release or load directly from d3js.org as a standalone library. AMD, CommonJS, and vanilla environments are supported. In vanilla, a d3 global is exported:

<script src="https://d3js.org/d3-color.v1.min.js"></script>
<script src="https://d3js.org/d3-dispatch.v1.min.js"></script>
<script src="https://d3js.org/d3-ease.v1.min.js"></script>
<script src="https://d3js.org/d3-interpolate.v1.min.js"></script>
<script src="https://d3js.org/d3-selection.v1.min.js"></script>
<script src="https://d3js.org/d3-timer.v1.min.js"></script>
<script src="https://d3js.org/d3-transition.v1.min.js"></script>
<script src="https://d3js.org/d3-selection-multi.v1.min.js"></script>
<script>

var div = d3.selectAll("div")
    .attrs({title: "Hello, world!"})
    .styles({"color": "red"});

</script>

Or, in combination with the D3 default bundle:

<script src="https://d3js.org/d3.v4.min.js"></script>
<script src="https://d3js.org/d3-selection-multi.v1.min.js"></script>
<script>

var div = d3.selectAll("div")
    .attrs({title: "Hello, world!"})
    .styles({"color": "red"});

</script>

Try d3-selection-multi in your browser.

API Reference

# selection.attrs(values)

A convenience method on top of selection.attr for setting multiple attributes. If the specified values is an object, the values may be specified either as strings or functions. For example:

selection.attrs({foo: "foo-value", bar: function(d) { return d.bar; }});

If a value is a constant, all elements are given the same attribute value; otherwise, if a value is a function, the function is evaluated for each selected element, in order, being passed the current datum (d), the current index (i), and the current group (nodes), with this as the current DOM element. The function’s return value is then used to set each element’s attribute. A null value will remove the specified attribute.

If the specified values is a function, the function is evaluated for each selected element, in order, being passed the current datum (d), the current index (i), and the current group (nodes), with this as the current DOM element. The function’s return value must be an object with string values, which are then used to set attributes on the current element. For example:

selection.attrs(function(d) { return {foo: "foo-value", bar: d.bar}; });

Passing a function to selection.attrs is convenient for sharing some computational effort or state across multiple attributes, or for specifying dynamically which attributes to set.

# selection.styles(values[, priority])

A convenience method on top of selection.style for setting multiple style properties. If the specified values is an object, the values may be specified either as strings or functions. For example:

selection.styles({fill: "red", stroke: function(d) { return d.stroke; }});

If a value is a constant, all elements are given the same style property value; otherwise, if a value is a function, the function is evaluated for each selected element, in order, being passed the current datum (d), the current index (i), and the current group (nodes), with this as the current DOM element. The function’s return value is then used to set each element’s style properties. A null value will remove the specified style properties.

If the specified values is a function, the function is evaluated for each selected element, in order, being passed the current datum (d), the current index (i), and the current group (nodes), with this as the current DOM element. The function’s return value must be an object with string values, which are then used to set style properties on the current element. For example:

selection.styles(function(d) { return {fill: "red", stroke: d.stroke}; });

Passing a function to selection.styles is convenient for sharing some computational effort or state across multiple style properties, or for specifying dynamically which style properties to set.

# selection.properties(values)

A convenience method on top of selection.property for setting multiple element properties. If the specified values is an object, the values may be specified either as strings or functions. For example:

selection.properties({foo: "foo-value", id: function(d, i) { return "id-" + i; }});

If a value is a constant, all elements are given the same property value; otherwise, if a value is a function, the function is evaluated for each selected element, in order, being passed the current datum (d), the current index (i), and the current group (nodes), with this as the current DOM element. The function’s return value is then used to set each element’s properties. A null value will remove the specified properties.

If the specified values is a function, the function is evaluated for each selected element, in order, being passed the current datum (d), the current index (i), and the current group (nodes), with this as the current DOM element. The function’s return value must be an object with string values, which are then used to set properties on the current element. For example:

selection.properties(function(d, i) { return {foo: "foo-value", id: "id-" + i}; });

Passing a function to selection.properties is convenient for sharing some computational effort or state across multiple properties, or for specifying dynamically which properties to set.

# transition.attrs(values)

Like selection.attrs, but for transition.attr.

# transition.styles(values[, priority])

Like selection.styles, but for transition.style.

d3-selection-multi's People

Contributors

jfsiii avatar mbostock avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

d3-selection-multi's Issues

How to integrate with existing d3 build?

I'm wondering how this should be integrated with the entire d3 4.0 package.

My project is using ES6 import and export (via Babel).

Another way of framing this question is: How should a custom plugin be integrated into the existing d3 library – using ES6 import and export?

Would this require a customized version of the d3 index.js file?
And if so, what would that look like?

I tried doing this:

import selection from 'd3-selection';
import 'd3-selection-multi';
import d3 from 'd3';
Object.assign(d3, selection);

But that's obviously wrong – and it ended up breaking event handling.

Transitions need multi-methods, too.

styles after a transition doesn't work. Changing index.js to update the transition prototype fixes the problem:

import {selection} from "d3-selection";
import selection_attrs from "./src/selection_attrs";
import selection_styles from "./src/selection_styles";
import selection_properties from "./src/selection_properties";

selection.prototype.attrs = selection_attrs;
selection.prototype.styles = selection_styles;
selection.prototype.properties = selection_properties;

if (selection.prototype.transition){
  selection.prototype.transition.attrs = selection_attrs;
  selection.prototype.transition.styles = selection_attrs;
  selection.prototype.transition.properties = selection_attrs;
}

But it seems a bit hacky since it there's an unspecified dependency on loading d3-transition before d3-selection-multi. I'm not sure if there should be a separate d3-selection-transition-multi module to handle this? Creating two modules for everything you'd like to stick onto selection.prototype seems like overkill.

pretest script not working on Windows

Hi,
I just forked this repository, and after npm install, the pretest script failed on my computer (Windows 10). This seems to be due to the rm -rf build command, not recognized (though rm is supported by powerShell...).
By using rimraf, the pretest command works fine. Shall I submit this change as a PR?

d3-selection-multi + default d3 doesn't play well with bundlers

Pulling in d3 followed by d3-selection-multi doesn't work with a bundler (e.g. webpack):

var d3 = require("d3");
require("d3-selection-multi");

d3.select().attrs({}) // undefined error!

This is because d3's package.json specifies browser: "build/d3.js", which bundlers will choose over the main or module fields (which is the expected behavior). Then, d3-selection-multi's require("d3-selection") is seen as a separate module (and the bundle will have the selection code twice) -- the end result is that there's no way to load d3-selection-multi (without special bundler configuration). Is this expected behavior?

This is painful since I'm writing a mid-level library that uses d3-selection-multi, and as is, I have to tell all my webpack consumers to add resolve { alias: { d3: "d3/index"; } } before they can use the library.

Use attrs(), styles(), properties() as getters

I tried this module by hacking d3's index.js like this:

export {
  mouse,
  namespace,
  namespaces,
  select,
  selectAll,
  selection,
  touch,
  touches,
  event
} from "./d3-selection-multi/selection";

and bundling it with rollup: .attrs(), .styles(), .properties() work perfectly as setters but would it be possible to turn them to getters if used without arguments?

I'd use it to harvest all attributes/properties/styles from a certain selection, like this:

selection.selectAll('*')
.each(function() {
  console.log(this, d3.select(this).attrs());
  // should print the attributes object: {id: "id", class:"foo bar", ...}
})

I could produce a PR but I'm not sure if this is the intended behavior. Thanks!

using multi select with d3 v5 and es6

I like how multi select allows you to style nodes using objects but how can I include this library in my d3 v5 and es6 project?

I imagine I need to import it somehow ?!

import * as d3 from 'd3';
import * as d3-selection-multi from 'd3-selection-multi' // ????

Ultimately, I want to be able to use v5 and pass in an object without having to use snapSVG:

 g
    .styles({fill:'blue',stroke:'#CCC'})

I see multi select was part of v4 - is it still relevant in v5?

For now, I built a simple lodash helper to apply the style object to an element

const styleElement = (el, style) => {
  _.forIn(style, (val, key) => {
    el.style(key, val);
  });
};

styleElement(g,{fill:'blue',stroke:'#CCC'})

webpack not working?

I am seeing the same issue as reported here:
#9

npm ls gives me:

─┬ [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├─┬ [email protected]
│ │ ├── [email protected]
│ │ └── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├─┬ [email protected]
│ │ └── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ └── [email protected]
├── [email protected]

Running your test from a node command line does indeed show that the attrs, styles etc functions have been added when doing:

var d3  = require("d3");
 require("d3-selection-multi")
d3.selection.prototype
Selection {
  constructor: [Function: Selection],
  select: [Function],
  selectAll: [Function],
  filter: [Function],
  data: [Function],
  enter: [Function],
  exit: [Function],
  merge: [Function],
  order: [Function],
  sort: [Function],
  call: [Function],
  nodes: [Function],
  node: [Function],
  size: [Function],
  empty: [Function],
  each: [Function],
  attr: [Function],
  style: [Function],
  property: [Function],
  classed: [Function],
  text: [Function],
  html: [Function],
  raise: [Function],
  lower: [Function],
  append: [Function],
  insert: [Function],
  remove: [Function],
  datum: [Function],
  on: [Function],
  dispatch: [Function],
  interrupt: [Function],
  transition: [Function],
  attrs: [Function],
  styles: [Function],
  properties: [Function] }

However using webpack, with the following js code does not work:
(file = /examples/examples.js)

var d3 = require('d3');
require('d3-selection-multi');
console.log(d3.selection.prototype);

in that attrs, and styles are not available in the d3 selection prototype object.

Here's the webpack config I am using:

var webpack = require('webpack'),
  libraryName = 'cl-react-graph',
  path = require('path'),
  entry = [
    './examples/examples.js'
  ],
  plugins = [
    new webpack.NoEmitOnErrorsPlugin()
  ],
  loaders = [
    {test: /\.js$/, exclude: /(node_modules)/, loader: 'babel-loader'}
  ];

module.exports = {
  devtool: 'cheap-module-source-map',
  entry: entry,
  output: {
    path: path.join(__dirname, 'examples'),
    publicPath: '/',
    filename: 'index.js',
    library: libraryName,
    libraryTarget: 'umd',
    umdNamedDefine: true
  },
  module: {
    loaders: loaders
  },
  plugins: plugins,
  watchOptions: {
    poll: true
  },
  externals: [
    {
      react: {
        root: 'React',
        commonjs2: 'react',
        commonjs: 'react',
        amd: 'react'
      }
    },
    {
      'react-dom': {
        root: 'ReactDOM',
        commonjs2: 'react-dom',
        commonjs: 'react-dom',
        amd: 'react-dom'
      }
    }
  ]
};

How to make d3-selection and d3-selection-multi work together?

I've installed both d3-selection and d3-selection-multi with npm, and using rollout with the rollout-plugin-node-resolve.

This is my code.

import select from 'd3-selection';
import 'd3-selection-multi';
import { default as range } from 'lodash-es/range';

var chart = select('svg');

var days = chart.selectAll('rect.day')
        .data(range(365));

days.enter()
    .append('rect')
    .merge(days)
    .attrs({
        'x': d =>d * 12,
        'y': 10,
        'width': 10,
        'height': 10,
        'class': 'day',
    });

I get, in the browser:

TypeError: days.enter(...).append(...).merge(...).style(...).attr(...).attr(...).attr(...).attr(...).attrs is not a function

I tried explicitly importing selection:

import {selection, select} from 'd3-selection';
import 'd3-selection-multi';

Still same error. Howewer, If I change select('svg') with selection().select('svg') it works, but I don't think that's how we are supposed to do it.
What's the correct way to import both selection and multi-selection and have the latter apply to the imported methods of the first?

.attrs is not a function

Having error with d3 v5.
Error:
Error in /~/index.js (39:10) svg.selectAll(...).data(...).enter(...).append(...).text(...).attrs is not a function
Versions used:

"d3": "5.7.0", "d3-selection-multi": "1.0.1"

Example: stackblitz

How to import d3-selection-multi along with default d3 bundle?

Hi, i am using SystemJS to import and load modules with minified js in the library folder(not using npm):

/libs/d3/d3.v4.min.js
/libs/d3/d3-selection-multi.v1.min.js

Here is my config

{
    packages: {
        'd3': {
            main: './d3.v4.min',
            defaultExtension: 'js',
            map: {
                    './multi-select': './d3-selection-multi.v1.min.js'
            }
       }
    }
}

Loading the packages:

import * as d3 from 'd3';
import 'd3/multi-select';

However, this will give me 404 on

.../d3-selection.js 
.../d3-transition.js

I checked the d3-selection-multi.js and found that tthat those two modules are the dependencies.

So, here are my two questions:

  1. Isn't the default d3 bundle providing d3-selection.js and d3-transition.js?

  2. how can I make this thing work so that I can use the plugin methods in d3-selection-multi?

Thanks!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.