d3 / d3-plugins Goto Github PK
View Code? Open in Web Editor NEW[DEPRECATED] A repository for sharing D3.js V3 plugins.
Home Page: https://github.com/d3/d3/wiki/Plugins
License: Other
[DEPRECATED] A repository for sharing D3.js V3 plugins.
Home Page: https://github.com/d3/d3/wiki/Plugins
License: Other
It would be nice to provide a set of standard interruptions e.g. avoiding the oceans or avoiding continents, as well as making it easy to define arbitrary interruptions.
I think d3.geo.graticule could support interruptions better. Here's a simple example of interrupting the sinusoidal projection: http://bl.ocks.org/3737384. You can see that I had to use two graticule instances, with the second beginning at 1e-9
° longitude. It would be nice to just use a single graticule instance here.
Certain values cause interpolateZoom to return NaN:
var f = d3.interpolateZoom([6317.937500000001,9242.5,2790.2034898924603], [6317.9375,9242.5,5945.00368923611 ]);
f(1)
[NaN, NaN, NaN]
This is tricky to handle as attrTween('transform', ...) would normally expect at least something valid.
Bergaus Star - http://bl.ocks.org/mbostock/4463049
Wiechel - http://bl.ocks.org/mbostock/4463155
I would like to use the CIE D3 plugin in my project but I need it to be available under an equivalent license to that of D3 itself.
https://github.com/mbostock/d3/blob/master/LICENSE
Currently there is no license listed for d3-plugins either as a whole or for individual plugins.
It would be handy to have an easy way to lookup GIS-style projection definitions. For example, EPSG:2163 could map to:
d3.geo.azimuthalEqualArea().rotate([100, -45])
while ESRI:102003 would map to
d3.geo.albers().rotate([-96, 0]).center([0, 37.5]).parallels([29.5, 45.5])
And likewise maybe even support for parsing Proj4-style projection definitions of the form
+proj=aea +lat_1=29.5 +lat_2=45.5 +lat_0=37.5 +lon_0=-96 +x_0=0 +y_0=0
I would like to just use the robinson geo projection. Can you provide documentation on how to use the make-file to produce a usable projections file containing only the projects I need?
This means it will work correctly with projection.center. Also, it would be nice if it could share some code with d3.geo.gringorten for a quincuncial configuration.
Not a bug, just a question: how would I modify the mercator example (http://bl.ocks.org/4132797) such that the map wraps around when panning left or right (like Google do with their map)?
Using the exact same code as the example http://bost.ocks.org/mike/sankey/, it work fine on my computer.
However, when i just change the json link to point to the above json that has the same structure it makes all types of explorer crash. The force layout renders this graph perfectly so I don't see where the problem is.
{"nodes": [
{"name": "United-Kingdom"},
{"name": "Lithuania"},
{"name": "France"},
{"name": "Italia"},
{"name": "Slovakia"},
{"name": "Ireland"},
{"name": "Norway"},
{"name": "Slovenia"},
{"name": "Germany"},
{"name": "Belgium"},
{"name": "Spain"},
{"name": "Ukraine"},
{"name": "Netherlands"},
{"name": "Bosnia"},
{"name": "Denmark"},
{"name": "Poland"},
{"name": "Finland"},
{"name": "Macedonia"},
{"name": "Sweden"},
{"name": "Latvia"},
{"name": "Czech-Republic"},
{"name": "Hungary"},
{"name": "Swiss"},
{"name": "Bulgaria"},
{"name": "Romania"},
{"name": "Albania"},
{"name": "Portugal"},
{"name": "Estonia"},
{"name": "Serbia"},
{"name": "Austria"},
{"name": "Greece"},
{"name": "Croatia"}],
"links": [
{"source": 0, "target": 12, "value": 0.0},
{"source": 0, "target": 5, "value": 394.27152014652034},
{"source": 0, "target": 2, "value": 1710.389120879121},
{"source": 1, "target": 19, "value": 562.4308424908422},
{"source": 2, "target": 22, "value": 3060.7918864468857},
{"source": 2, "target": 3, "value": 2994.6647161172173},
{"source": 2, "target": 9, "value": 1689.7085164835162},
{"source": 2, "target": 8, "value": 4572.282133699634},
{"source": 2, "target": 10, "value": 1270.9172527472526},
{"source": 3, "target": 22, "value": 5728.591043956041},
{"source": 3, "target": 7, "value": 1081.7596245421255},
{"source": 3, "target": 29, "value": 240.58763736263728},
{"source": 3, "target": 30, "value": 452.9039926739924},
{"source": 4, "target": 21, "value": 1857.8078296703286},
{"source": 4, "target": 15, "value": 703.173772893773},
{"source": 4, "target": 20, "value": 1562.1682783882788},
{"source": 6, "target": 14, "value": 1117.9031593406592},
{"source": 6, "target": 12, "value": 604.1978663003666},
{"source": 6, "target": 16, "value": 37.00898351648352},
{"source": 6, "target": 6, "value": 71.36014652014653},
{"source": 6, "target": 18, "value": 136.60347985347985},
{"source": 7, "target": 29, "value": 598.8780402930406},
{"source": 7, "target": 31, "value": 642.6279761904757},
{"source": 8, "target": 12, "value": 1715.58423992674},
{"source": 8, "target": 14, "value": 755.765723443224},
{"source": 8, "target": 15, "value": 1227.313434065934},
{"source": 8, "target": 18, "value": 167.16668498168497},
{"source": 8, "target": 29, "value": 1797.8848351648357},
{"source": 8, "target": 20, "value": 1778.5800549450541},
{"source": 8, "target": 22, "value": 2771.7167673992694},
{"source": 9, "target": 12, "value": 1900.7907600732606},
{"source": 10, "target": 26, "value": 1371.0025366300367},
{"source": 11, "target": 21, "value": 833.2233791208791},
{"source": 11, "target": 24, "value": 357.0193131868132},
{"source": 13, "target": 31, "value": 627.9329212454212},
{"source": 14, "target": 14, "value": 180.27889194139192},
{"source": 14, "target": 18, "value": 167.17994505494505},
{"source": 15, "target": 18, "value": 109.07065934065933},
{"source": 15, "target": 20, "value": 1706.4577472527467},
{"source": 16, "target": 18, "value": 305.363717948718},
{"source": 16, "target": 27, "value": 489.7703205128206},
{"source": 17, "target": 30, "value": 333.4131868131865},
{"source": 17, "target": 28, "value": 0.0},
{"source": 17, "target": 23, "value": 0.0},
{"source": 18, "target": 18, "value": 0.8676739926739928},
{"source": 19, "target": 27, "value": 579.218553113553},
{"source": 20, "target": 29, "value": 2266.835540293041},
{"source": 21, "target": 24, "value": 259.5148076923077},
{"source": 21, "target": 28, "value": 216.2569230769231},
{"source": 21, "target": 29, "value": 431.3127930402932},
{"source": 21, "target": 31, "value": 1405.1164102564105},
{"source": 22, "target": 29, "value": 1193.6274908424919},
{"source": 23, "target": 24, "value": 444.2263095238097},
{"source": 23, "target": 28, "value": 0.0},
{"source": 23, "target": 30, "value": 633.9733333333336},
{"source": 24, "target": 28, "value": 546.0507326007325},
{"source": 25, "target": 30, "value": 492.10853479853455},
{"source": 28, "target": 31, "value": 273.98855311355305}]}
A public API for invoking d3.geo.rotate directly. Takes as input GeoJSON, returns rotated GeoJSON. The rotated GeoJSON may be split or rejoined to account for the antemeridian (and ideally the poles). For example, a Polygon might be converted into a MultiPolygon.
I'm using bullet charts for monitoring solar production:
While one measure denotes today's performance, the other shows yesterday.
Unfortunately, bullet.js reoders the measures. Once today > yesterday, the colors in the chart get swapped. Instead I'd need yesterday to be hidden below today.
I've looked at preventing the sorting in bullet.js but unsuccessfully. Any ideas how to make this possible with bullet.js?
Why does the json make Chrome crash? How can I avoid crashes?
var nodes = [
{"name":"Depósito"},
{"name":"Gas-Oil"},
{"name":"Cisterna"},
{"name":"020600 Pestillo Correa BR"},
{"name":"En uso por personal"},
{"name":"010030 Correa SRZ-120 100"},
{"name":"CC Maquinarias"},
{"name":"028710 Carro Desplaz"},
{"name":"018060 Grupilla"},
{"name":"Electric Light"},
{"name":"Picadora de carne"},
{"name":"Carni"},
{"name":"Balanza para carnes"},
{"name":"Botines de Seguridad"},
{"name":"En uso por personal"},
{"name":"Anteojos de seguridad"},
{"name":"Cono de seguridad vial"}];
var links = [
{"source":0,"target":1,"value":2.0},
{"source":1,"target":2,"value":2.0},
{"source":4,"target":3,"value":12.0},
{"source":3,"target":0,"value":12.0},
{"source":0,"target":5,"value":1.0},
{"source":5,"target":6,"value":1.0},
{"source":0,"target":3,"value":2.0},
{"source":3,"target":6,"value":2.0},
{"source":0,"target":7,"value":3.0},
{"source":7,"target":6,"value":3.0},
{"source":9,"target":8,"value":8.0},
{"source":8,"target":0,"value":100.0},
{"source":11,"target":10,"value":1.0},
{"source":10,"target":0,"value":1.0},
{"source":11,"target":12,"value":2.0},
{"source":12,"target":0,"value":2.0},
{"source":0,"target":13,"value":1.0},
{"source":13,"target":14,"value":1.0},
{"source":0,"target":15,"value":1.0},
{"source":15,"target":14,"value":1.0},
{"source":0,"target":16,"value":2.0},
{"source":16,"target":14,"value":2.0}];
Add .origin() to enable spinny globes.
Loving the sankey plugin! But apparently it won't handle networks with cycles, for example:
http://locecon.org/clusters/network/8/
Any ideas about how to fix, work around, or otherwise grapple with the problem?
If so, I will happily try them.
If not, I'll tinker a little and see what I can do...
Topological simplification is awesome, but what would make it even more awesome is access to the topological edge data with references back to the features that contain them. I've been trying to figure out how to get a data structure like this out of it:
[
// this edge borders two features
{
"features": [
<feature>,
<feature>
],
"coordinates": [...]
}
// other edges
]
Which would pave a very clear path to building interactive cartograms, as well as building visualizations of the algorithm itself that could highlight individual edges.
My first attempt involved setting a "topology" property on the feature object inside simplify.project()
to export the current state of all the algorithm, like so:
feature.topology = {
idByPoint: idByPoint,
idByRings: idByRings,
ringsByPoint: ringsByPoint,
sharedPoints: sharedPoints,
isShared: isShared,
lastRingByPoint: lastRingByPoint,
graph: graph
};
I thought that by iterating over each of the features in a collection, then each of their rings, I could then look up each point in idByPoint
and group the points by their edge id within each feature. What I end up with, though, is an incomplete list of points for each edge and some bad connections between them.
Ideally the simplify API would expose a method to get the edges:
var edges = simplify.edges(feature);
But I'm not sure how this would work, because simplify.project()
unsets all of the state variables, and I'm not even sure if the state variables that I'm tracking contain the information necessary to build that structure by the time simplify.project()
is finished.
Can somebody point me in the right direction?
Do we want to support inverse projections?
It would be nice to have a transverse Mercator projection with the 90° rotation built-in. That way, you can easily use a transverse Mercator without needing to also apply a 90° rotation to the rendered result. Should be a pretty simple transformation of d3.geo.mercator.raw.
in line 130, it seems to access global variable "width"
It works in the example but it might cause errors in other cases.
I suggest to change it to "size[0]"
Thanks
When the implementations are mature, we should probably take another pass over them and see if we can optimize anything (for example, pulling out constants such as 2 / 3 * π). This makes the code less readable but it could be worth doing since projections are often in the inner loop.
It might be cleaner (I'd like to try and see) if the projection implementation functions were all immutable. This is already the case for the non-configurable projections such as winkel3 and wagner6. However projections such as cylindricalEqualArea and conicConformal take configurable parallels to change their behavior.
So rather than each projection defining its own parallel or parallels method, I was thinking a projection could be implemented like so:
function bonne(φ0) {
var cotφ0 = 1 / Math.tan(φ0);
return function(λ, φ) {
var ρ = cotφ0 + φ0 - φ,
E = λ * Math.cos(φ) / ρ;
return [
ρ * Math.sin(E),
cotφ0 - ρ * Math.cos(E)
];
};
}
Then to make a usable projection, you would say:
function singleParallelProjection(projectAt) {
var φ0 = 0,
project = newProject(φ0),
p = projection(function(λ, φ) { return project(λ, φ); });
p.parallel = function(_) {
if (!arguments.length) return φ0 / π * 180;
project = projectAt(φ0 = _ * π / 180);
return p;
};
return p;
}
This should simplify the projection implementations slightly, and also make it easier to support copying a projection because the projection implementation is immutable. (Having a projection.copy function would make it easier to do enter and exit with changing projections.)
/cc @jasondavies
Kind of a long term low-priority thing for now, but one of the last features d3.geo does not yet support!
I can't seem to figure out how one would graph multiple bands using the horizon plugin. Is the point to just create multiple graphs, or is there a way to handle multiple graphs.
The current documentation would suggest that the graticule code should be in the geo/projection directory, and even the README.md file in this directory has something about the graticule code. There is no graticule code in the geo/projection/projection.js file, nor in any file in the d3-plugins tree.
I wonder if this is worth adding:
d3.geo.interpolatedProjection = function(a, b) {
var projection = d3.geo.projection(raw).scale(1),
center = projection.center,
translate = projection.translate,
α;
function raw(λ, φ) {
var pa = a([λ *= 180 / Math.PI, φ *= 180 / Math.PI]), pb = b([λ, φ]);
return [(1 - α) * pa[0] + α * pb[0], (α - 1) * pa[1] - α * pb[1]];
}
projection.alpha = function(_) {
if (!arguments.length) return α;
α = +_;
var ca = a.center(), cb = b.center(),
ta = a.translate(), tb = b.translate();
center([(1 - α) * ca[0] + α * cb[0], (1 - α) * ca[1] + α * cb[1]]);
translate([(1 - α) * ta[0] + α * tb[0], (1 - α) * ta[1] + α * tb[1]]);
return projection;
};
delete projection.scale;
delete projection.translate;
delete projection.center;
return projection.alpha(0);
};
Taken from http://bl.ocks.org/mbostock/5731632
It would be great to have a Dymaxion map. Its absence is puzzling, especially since it was implemented in Protovis: http://mbostock.github.io/protovis/ex/dymax.html
please fix the Boxplot plug-in to work in IE 8 too.
regards.
Guyou - http://bl.ocks.org/mbostock/3763867
Mercator - http://bl.ocks.org/mbostock/3757132
Craig retroazimuthal - http://bl.ocks.org/mbostock/4459466
Larrivée - http://bl.ocks.org/mbostock/3719042
Eisenlohr - http://bl.ocks.org/mbostock/3797585
Eckert III - http://bl.ocks.org/mbostock/3734325
Required items:
Nice-to-have:
e.g., for d3.simplify:
var path = d3.geo.path()
.projection({
polygon: function(polygon, context) {
polygon.forEach(function(ring) {
var n = ring.length,
i = 0,
point;
context.moveTo((point = ring[0])[0], point[1]);
while (++i < n) context.lineTo((point = ring[i])[0], point[1]);
context.closePath();
});
}
});
Related: it should be possible to use d3.simplify and output latitude & longitude.
My new clipping code in the clip branch is a modified version of Weiler–Atherton that clips against a great circle. The great thing is that it can handle holes, and can also be modified further to clip against a great semicircle e.g. for the splitting required in #9.
However:
It can't handle self-intersecting polygons. Self-intersecting lines should be okay. Unfortunately, self-intersecting polygons can arise when using most line-simplification algorithms e.g. d3.simplify. It's possible to detect and "unsimplify" offending segments (I've made some headway with this via Bentley–Ottmann) but it's not quite there yet.
This is why examples like http://bl.ocks.org/3734168 break! It would be nice to break more gracefully.
Another related issue is that due to precision errors it very occasionally exhibits the above problem because two intersection points that are very close can become "swapped". This is more easily fixed by adjusting the sorting of intersection points to operate on small chunks to maintain the correct order. It's possible that this kind of solution could be used to work around self-intersections, although I'm not sure if the output would be correct in that case.
Both issues currently cause an error like "Uncaught TypeError: Cannot read property 'angle' of undefined". This is because there is a linked list that expect intersections to be in in-out order, and self-intersections (or precision errors) can break this assumption.
I'm using Sankey and it is great!
I do however need to display the dropouts at each node.
For example, if there is an inbound link with a value of 100 and an outbound link with a value of 75,
I need to display a 25 dropout (like in Google's Multi-Channel Funnel).
Any thought on how this can be done?
This question came up when attempting to rewrite d3.geo.gilbert. Gilbert’s “projection” is really a conformal transformation of the sphere onto a hemisphere, which can then be projected using any projection, most commonly the orthographic projection.
Similarly, we have the concept of an “auxiliary sphere”, implemented in #54 and mentioned in d3/d3#1293, which transforms coordinates from a given ellipsoidal datum to a sphere, while preserving a given property (area, angles, etc.)
Mike suggested making d3.geo.gilbert into a constructor taking a raw projection function, defaulting to d3.geo.orthographic.raw. However, this would exclude more exotic projections, which have custom streams not created by d3.geo.projection(raw). In other words, a map projection is fully defined not only by a point-wise function, but its (clip) stream, too.
Moreover, the auxiliary sphere branch makes me think that we should have a way to perform arbitrary geographic transformations (that is, in “unprojected” coordinates) prior to projection.
I think this would have to be supported by d3.geo.projection itself so that projection.center takes coordinates in the source datum, which are then transformed to the projection datum. Originally I was thinking of adding d3.geo.projection.auxiliary as discussed in d3/d3#1293, but perhaps the name “auxiliary” is too restrictive?
Either way, something like d3.geo.orthographic().auxiliary(gilbert) is a potential solution.
d3.geo.tile holds promise, but right now it's seriously lacking for all but demo maps because there's no built-in support for working with geographic coordinates. E.g.:
var tile = d3.geo.tile()
.center([-76.3429, 38.7351]) // geographic center
.zoom(12); // in tile coordinates
Are there plans to support this? I'm wondering aloud if @tmcw, @migurski, or @RandomEtc might be working on this already.
I think returning new features (rather than simplifying in place) is still the right thing, but it would be great if d3.simplify returned features exactly as given, except for the simplified geometry.
Right now simplifyFeature
creates a new Feature
. At the very least it should copy the GeoJSON properties
(deep copy?), but the given feature may also have it's own keys e.g. id
that it would be nice to preserve as well.
Example: http://bl.ocks.org/justinvdm/3676778
I know some of these are difficult to compute (requiring Newton’s method, say), but I thought it would be worthwhile to track. Here are the projections that are missing an inverse:
I can immediately add inverses for sinuMollweide and homolosine since those are fairly easy and also common projections. After that, next on my list would probably be robinson, winkel3 and aitoff. I know robinson & winkel3 require numeric integration, though.
I am seeing some tearing in some browsers using Winkel 3, apparently in places where geographic features wrap from the right side of the map to the left.
You can see this in action at: http://concept.newcitystaging.com/ccmap/
I've seen this in Firefox 16.0.2 and Safari on my iOS6 iPad.
The path data is from NaturalEarth, so it's a different data set than you are using in the Readme documentation.
bullet.orient("top" | "bottom")
...which means that attempting to install d3-plugins via Bowser fails because it can't find the 3.0 tag.
@jasondavies, what was your rationale for changing the d3 dependency in package.json to point to git://github.com/mbostock/d3.git#3.0
?
This way, if the graticule extent is changed to some irregular value, you still get meaningful grid lines.
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.