Giter VIP home page Giter VIP logo

d3-jetpack's People

Contributors

1wheel avatar cedricsam avatar dwtkns avatar gka avatar moklick avatar sjockers 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  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  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

d3-jetpack's Issues

modular support

Hey, anyway I can just import the function I need ? In this case wordwrap ?
I've tried importing directly from the path, justl ike I do with d3's modules, but it gives me an error.

import scaleBand from 'd3-scale/src/band';
import scaleLinear from 'd3-scale/src/linear';
import { wordwrap } from 'd3-jetpack/src/wordwrap';
import { tspans } from 'd3-jetpack/src/tspans';

axisGroup.selectAll(...).text(...).tspans is not a function: Uncaught type error

change f character

Hi. I really like all functionaliities of this, but I'm having problem with the 'f' character. Please, there's some chance to change it to something more standard?

  • It complicate to write down, plus I get this error:

image

JavaScript console error:
image

System: Windows. Browser: Opera 41
at this moment it's unuseful :(

Thanks you

Switching to selectAppend in conventions?

I find myself wanting to encapsulate my entire viz into a single function which is made massively easier by selectAppend (thank you so much for saving me from writing my own ugly version another time) but have found the process of resetting the svg/scales to be awkward with conventions. Would there be interest in replacing the append('svg') with a selectAppend to allow for easy resizing?
I may be incorrect in my decision to put the SVG setup into the big draw. It seems like the best way to do it currently is something along the lines of

onResize = () => {
  const newWidth = getNewWidth();
  const newHeight = getNewHeight();
  c.svg.parent().at(...);
  // update scale ranges and reset the main g-container
  drawViz(c);
}

Which feels... not right. With selectAppend it seems it could be as easy as putting const c_new = d3.convention(...) inside drawViz().

This is asked with the idea of, if desired, I can submit a PR but I wanted to see if it was in keeping with the ethos of d3-jetpack.

enter().insert(...) doesn't preserve order

The d3 semantics of enter().insert(...) are such that when performing an insert on the enter selection of a join with a key, the "entering elements [should] be inserted immediately before the next following sibling in the update selection, if any."

However, when using d3-jetpack, the entering elements are merely appended to the end.

The following is a toy example:

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8">
        <title>Insert Order Bug</title>
        <script type="text/javascript" src="http://d3js.org/d3.v3.js"></script>
        <script src="https://raw.githubusercontent.com/gka/d3-jetpack/master/d3-jetpack.js"></script>
    </head>
    <body>
        <script type="text/javascript">
var identity = function (x) { return x; };

// Make a list of odd numbers less than 10
d3
    .select("body")
    .selectAll("div")
    .data([1, 3, 5, 7, 9], identity)
    .enter()
    .insert("div")
    .html(identity)
;

// Change the list to prime numbers less than 10
var update = d3
    .select("body")
    .selectAll("div")
    .data([2, 3, 5, 7], identity)
;

// Color the update selection yellow
update.style("background-color", "yellow");

// Insert and color the enter selection green
update
    .enter()
    .insert("div")
    .html(identity)
    .style("background-color", "green")
;

// Remove those pesky composite numbers
update
    .exit()
    .remove()
;
        </script>
    </body>
</html>

This page will show the list "3, 5, 7, 2", however commenting out the d3-jetpack script will preserve the d3 semantics and produce the list "2, 3, 5, 7".

v2 checklist

  • insert
  • ฦ’.call and ฦ’.not - still not sold on their implementation; why set d3.f.not = function(d){ return !d } instead of calling with a string?
  • translateX/translateY? Kind of annoying to add selection and transition for each
  • change loadData to not take an array
  • add links to source in docs
  • reorder docs - group selection modifiers, v3 functions and everything else?
  • docs for parent
  • okay to remove bower.json?
  • okay to use an adult license?
  • Manually add d3 dependencies to package.json

Missing functions

selection.prop

jetpack added selection.prop as alias for selection.property. Much faster to type, isn't it? Also only consistent with selection.attr, and familiar to jQuery folks.

// for everyone's sake, let's add prop as alias for property
d3.selection.prototype.prop = d3.selection.prototype.property;

selection.on

jetpack lets you set the same listener for multiple events at once, jQuery style.

selection.on('click touchend', function() {
    console.log('this works on desktop AND mobile!');
});
// this tweak allows setting a listener for multiple events, jquery style
var d3_selection_on = d3.selection.prototype.on;
d3.selection.prototype.on = function(type, listener, capture) {
    if (typeof type == 'string' && type.indexOf(' ') > -1) {
        type = type.split(' ');
        for (var i = 0; i<type.length; i++) {
            d3_selection_on.apply(this, [type[i], listener, capture]);
        }
    } else {
        d3_selection_on.apply(this, [type, listener, capture]);
    }
    return this;
};

Github release for 2.0.7

Hi, do you plan to add a Github release for 2.0.7? It appears 1.0.6 is the last tagged. Thanks so much for the fantastic and helpful work. For reference, we are including in the R package d3r (see pull), and we would like to test to insure that we are on the current release.

api tweaks

Can leave the old functions in while updating the docs and adding new aliases.

parentSel

I usually do var sel = d3.select('.graph').html() at the start of my render function. d3.conventions({sel}) is cleaner than d3.conventions({parentSel: sel}).

appendMany

I think dataAppend is easier to teach; the first argument is the data, the second is what you're appending. Or manyAppend?

ฦ’

Not sure this is necessary anymore with ES6. Maybe remove from the examples?

Categories

Hi,

What happens when the scale in conventions need to use a category instead of a measure (using another scale instead of a linear scale) ? Is there an option for this ?

Regards,
Rezpe

translate on single axis

export default function(xy, dim) {
  return this.attr('transform', function(d,i) {
    var p = [typeof xy == 'function' ? xy.call(this, d,i) : xy];
    if (dim == 'x') p = p[p, 0]); else if (dim == 'y') p = [0, p];
    return 'translate(' + p[0] +','+ p[1]+')';
  });
}

so I can do

sel.translate(d3.f('x'), 'x')

unify translate and line api

It'd be nice if there was a consistent way of mapping data to a 2D space. Currently we switch between

  c.svg.appendMany(d, 'circle')
    .translate(d => [c.x(d.components), c.y(d.elements)])

and

  var line = d3.line()
    .x(d => c.x(d.components))
    .y(d => c.y(d.elements))

Ideally, line and selection would expose a translate or a pos method that did this. I'm not sure how to do that without forking d3-shape - I think you need access to variables captured in a closure.

Something like this would work:

  function setTranslate(line, fn){
    return line.x(d => fn(d)[0]).y(d => fn(d)[1])
  }

  setTranslate(d3.line().curve(d3.curveLinear), d => [c.x(d.components), c.y(d.elements)])

But that's not nearly as readable as

  d3.line()
    .curve(d3.curveLinear)
    .translate(d => [c.x(d.components), c.y(d.elements)])

Maybe a fork of d3.line would be best; that could also avoid calling the translate function once for x and once for y.

translate breaks if selection is empty

need to exit early from this if node doesn't exist

 return this.node().getBBox ?
    this.attr('transform', function(d,i) {
      var p = typeof xy == 'function' ? xy.call(this, d,i) : xy;
      if (dim === 0) p = [p, 0]; else if (dim === 1) p = [0, p];
      return 'translate(' + p[0] +','+ p[1]+')';
    }) :

wordwrap removing spaces

d3.wordwrap('Make permanent the look-thru rule for related...', 25)
> ["Make permanent the look-", "thrurule for related..."]

SVG element has position:absolute. Why?

The SVG element that is created in the constructor has a style property position: 'absolute'. Why? Currently this messes up my design, and I have to disable it explicitly. It would be great if this would be removed, and if you want it, you can set it yourself.

No tag on the repo

The repo is missing a tag, so it isn't possible to bower install with a specific version, although the bower.json does have a tag on it.

ฦ’ ?

Why is there a non-standard ascii-symbol used inside the code?

Firefox complains about it. Programmers on the other hand, get struggle to finde the symbol on their keyboard.

I replaced ฦ’ by f, which makes it easier.

How about d3.indexBy(array, key)

Identical behaviour as in _.indexBy.

var indexed = d3.nest()
  .key(d => d.FIPS)
  .rollup(values => values[0])
  .object(data);

would become

var indexed = d3.indexBy(data, d => d.FIPS);

Provide d3-jetpack via npm

Although d3 is mostly a frontend library, many developers use npm with browserify or simply build scripts to install frontend libraries. Case-in-point... d3!

It would be very helpful if d3-jetpack did the same so we can retrieve it via npm install d3-jetpack.

d3 v4

Jetpack doesn't seem to work on d3 v4. I will try to see if I can take a look at this.

Explain how use d3-jetpack :(

I really searched ... but impossible to integrate d3-jetpack with the version of d3 7.3.0 . I install jetpack with yarn add d3-jetpack . But can't import or whatever.. can't call wordwrap/not import d3-jetpack in .ts . I'm really lost here. Is it still compatible suddenly or it is necessary to do something which is not explained for linked to d3?

Don't patch d3-selection and d3-transition globally

We recently ran into a problem where we had the following scenario: Module A was using d3-jetpack and d3-selection, and it was also importing module B which was using d3-jetpack and d3-selection. But it turned out that if B is importing a different version of d3-selection than A, but both are using the same version of d3-jetpack, only one version of d3-selection got patched (the one B was using). So all the imports from d3-selection in A did not have the jetpack patch.

There is really no good way to fix this from the outside so I think we should fix this here. I see two possible strategies:

  1. The consumer module passed the selection and transition objects (or their prototypes?) to a sort of initialize() method exported by d3-jetpack:
// module A
import { selection, select } from 'd3-selection';
import { transition } from 'd3-transition';
import { initJetpack, drawAxis } 'd3-jetpack';

initJetpack(selection, transition);
  1. d3-jetpack exports the stuff from d3-selection and d3-transition:
// module A
import { drawAxis } from 'd3-jetpack';
import { select } from 'd3-jetpack/selection';

Since I am nowadays bundling all my code using rollup anyway I think I am leaning to option 2.

Some features are not working with d3v6

Looks like there hasn't been much activity here in a while, is this still being developed?

Latest release, d3v6 is out since Fall 2020, and the migration guide has a lot of observations around some of the functions that are referenced in the docs here - like d3.nest().

translateCSS for html elements

something like:

export default function(xy) {
  return this.style('transform', function(d,i) {
    var p = [typeof xy == 'function' ? xy.call(this, d,i) : xy]
    return 'translate(' + p[0] + 'px, ' + p[1] + 'px)';
  });
}

gpu accelerated!

misc ideas

  • Option to have loadData cache files; useful for hot reloading big things
if (window.resCache){
  fmtData()
  init()
} else{
  d3.loadData('round-1.csv', 'round-2.csv', (err, res) => {
    window.resCache = res
    fmtData()
    init()
  })
}
  • Fix named timers
  • Besides .key, nestBy should have sortBy on array elements. The top level array should expose the map used to construct it.
  • Pass object to nestBy:
  var stateData = d3.nestBy(may11, d => d.prediction_date + d.target_date + d.state)
  stateData.forEach(d => {
    var f = d[0]
    d.prediction_date = d[0].prediction_date
    d.target_date = d[0].target_date
    d.state = d[0].state
  • If d attribute is an array, join it with a space

.at({d: d => ['M', c.x(d.i), , 'H 0'].join(' ')})

.at({d: d => ['M', c.x(d.i), , 'H 0']})

  • addAxisLabel

Maybe incorporate into drawAxis

function addAxisLabel(c, xText, yText){
  c.svg.select('.x').append('g')
    .translate([c.width/2, 35])
    .append('text')
    .text(xText)
    .at({textAnchor: 'middle'})
    .st({fill: '#000', fontWeight: 600})

  c.svg.select('.y')
    .append('g')
    .translate([-50, c.height/2])
    .append('text')
    .text(yText)
    .at({textAnchor: 'middle', transform: 'rotate(-90)'})
    .st({fill: '#000', fontWeight: 600})

}

Jetpack insert is breaking d3

<!DOCTYPE html>
<meta charset="utf-8">
<style>

body {
  font: 14px sans-serif;
}

</style>
<body>
<script src="//d3js.org/d3.v4.min.js"></script>
<script src="//unpkg.com/[email protected]"></script>
<script>

var c = d3.conventions()
c.drawAxis()

</script>

screen shot 2017-03-31 at 1 32 15 pm

Same error when using only d3v4+jetpack.js

recalculate width and height

It would be nice to have a function to update for instance the totalHeight or totalWidth on the conventions object, and so that the width and height are recalculated. Right now this is done for the initialization, but if you want to update these settings, this calculation is not done automatically

How to actually use?

The information isn't present at all in the readme. Here's what I've tried:

var d3 = require('d3');
require('d3-jetpack');
var sel = d3.select('body');

After Webpacking, I get Uncaught TypeError: d3.select is not a function. I have both d3 and d3-jetpack modules installed.

If I do

var d3 = require('d3');
var jetpack = require('d3-jetpack');
// ...
c.svg.append('rect').at({width: c.width, height: c.height, opacity: 0})

I get Uncaught TypeError: c.svg.append(...).at is not a function.

The same also occurs with

var d3 = Object.assign({}, require('d3'), require('d3-jetpack'));
// ...
c.svg.append('rect').at({width: c.width, height: c.height, opacity: 0})

attachTooltip: Flow tooltip towards top, unless it overflows viewport and there's space below to accommodate tooltip

Haven't fully explored every use case, but it seems like a better user experience if the tooltip is above the cursor at all times, except when it overflows (towards the top) and there's space below it to accommodate it.

So, if I were to have a super-tall tooltip that doesn't fit the entire height of viewport, the tooltip would never flow over at the bottom, but may flow over at the top. There's probably no ideal solution (and could be parametrized), but it works well for regular bottom-aligned bar charts, where the bars trigger the tooltip.

Going to submit a PR in a sec. cc: @1wheel

Namespaced timers

@gka thoughts on this? d3/d3-timer#30

Not sure if we should monkey patch timer, interval and timeout:

var oldD3Interval = exports.interval
var prevIntervals = {}
exports.interval = function(fn, delay, time, name){
  if (prevIntervals[name]) prevIntervals[name].stop()

  var interval = oldD3Interval(fn, delay, time, name)
  if (name) prevIntervals[name] = interval
  
  return interval
}

Or make new functions timerNS, intervalNS, timeoutNS

adding multiple layers to conventions

Previous thoughts: 1wheel/d3-jetpack-module#19

  • customize order, maybe just pass in a string?
  • svg/canvas/div
  • synchronize margins and width/height
  • set scaling on canvas

To make a canvas/svg/div/canvas stack:

var c = d3.conventions({layers: 'csdc'})

c.ctx0 // bottom canvas context
c.svg1 // svg selection
c.div2 // div selection
c.ctx3 // top canvas context

Some issues:

  • c is a little over used, but I can live with it
  • is it weird to set return a selection for svg and div, but a context for canvas?
  • c.svg is returned by default
  • will change parent selection to position: relative
  • not sure how i'd do this with regl or something; probably leave them out for now

@mhkeller is also working on this. maybe just copy what he does?

Include license information

You should consider including license information (MIT, BSD, Apache2... etc) to help minimize friction for developers who wish to leverage your wonderful library in an environment where things like that matter (enterprise... etc).

Neither .st() nor .at() work after .transition().duration(time)

Neither .st() nor .at() work after .transition().duration(time). However both .styles() and .attrs() work after transition.

For example, the below code does not work:

<--! I'm using a local copy of jetpack that i downloaded  about a month ago -->

<script src = 'd3v4+jetpack.js'> 
  var svg = d3.select('body').append('svg').at({width: 1000, height: 1000});

  var newDim = {hw: 500, fill: 'purple', stroke: 'yellow'};

  svg.append('rect#reproduction')
    .at({height: newDim.hw, width: newDim.hw})
    .st({fill: newDim.fill, stroke: newDim.stroke, 'stroke-width': 5})
    .on('click', change);

  function change(){
            newDim.hw == 900 ? newDim = {hw: 500, fill: 'purple', stroke: 'yellow'} : newDim = {hw: 900, fill: 'yellow', stroke: 'purple'};
        
            svg.selectAll('rect#reproduction')
              .transition().duration(500)
              .at({height: newDim.hw, width: newDim.hw})
              .st({fill: newDim.fill, stroke: newDim.stroke});
  }
</script>`  

However, the code does work once you change the post transition .at() and .st() to .attrs() and .styles(). I'm not sure if this is a big deal, but i thought I'd bring it to your attention.

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.