gka / d3-jetpack Goto Github PK
View Code? Open in Web Editor NEW๐ Nifty convenience wrappers that speed up your daily work with d3.js
License: BSD 3-Clause "New" or "Revised" License
๐ Nifty convenience wrappers that speed up your daily work with d3.js
License: BSD 3-Clause "New" or "Revised" License
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
such as the infamous <feGaussianBlur stdDeviation="4">
https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/stdDeviation
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?
System: Windows. Browser: Opera 41
at this moment it's unuseful :(
Thanks you
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.
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".
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 eachloadData
to not take an arrayparent
bower.json
?package.json
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;
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;
};
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.
Can leave the old functions in while updating the docs and adding new aliases.
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})
.
I think dataAppend
is easier to teach; the first argument is the data
, the second is what you're append
ing. Or manyAppend
?
Not sure this is necessary anymore with ES6. Maybe remove from the examples?
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
just read the code and was wonderingโฆ
d3.selection.append can also accept a function. The patched version of append breaks this functionality.
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')
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.
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]+')';
}) :
d3.wordwrap('Make permanent the look-thru rule for related...', 25)
> ["Make permanent the look-", "thrurule for related..."]
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.
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.
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);
I love the translate
function that you've added, but it would be awesome if it could also do scale
and rotate
. I like the way that this project does it, but that's just an idea.
d3.functor and d3.rebind have been removed with the entire Internals module for v4.
https://github.com/d3/d3/blob/abdcb7e88d390627d6bc9ab3aec8f182002f647e/CHANGES.md#internals
These are useful utility functions. Perhaps they belong in the Jetpack.
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
.
the following doesn't seem to exist anymore: https://rawgit.com/gka/d3-jetpack/master/build/d3v4%2Bjetpack.js
Jetpack doesn't seem to work on d3 v4. I will try to see if I can take a look at this.
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?
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:
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);
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.
Hey!
What do you think about adding those functions to the lib ? http://stackoverflow.com/a/14426477/649896
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()
.
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!
loadData
cache files; useful for hot reloading big thingsif (window.resCache){
fmtData()
init()
} else{
d3.loadData('round-1.csv', 'round-2.csv', (err, res) => {
window.resCache = res
fmtData()
init()
})
}
.key
, nestBy
should have sortBy
on array elements. The top level array should expose the map used to construct it. 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
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']})
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})
}
<!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>
Same error when using only d3v4+jetpack.js
the startOffset
attribute for a textPath
should remain startOffset
, and not be transformed to start-offset
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
aspectRatio:
set height equal to width/aspectRatio
margin: 0
equivalent to margin: {top: 0, left: 0, bottom: 0, right: 0}
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})
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
@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
Previous thoughts: 1wheel/d3-jetpack-module#19
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 itsvg
and div
, but a context
for canvas?c.svg
is returned by defaultposition: relative
@mhkeller is also working on this. maybe just copy what he does?
I try to use zero margins (for a map), but conventions always forces me into 20px margin
Using .st() for the "order" attribute doesn't work when a number is provided as the value, but works when a string is provided as a value.
https://codepen.io/keithng/pen/jOEoBZB
The DOM element style is not changing at all when a number is provided.
Is it possible to include this library into a project via the import syntax?
import { wordwrap } from 'd3-jetpack'
And just pull off one function like wordwrap
?
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)
. 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.
If parentSel
is defined, use parentSel.node().offsetWidth
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.