unkleho / d3-render Goto Github PK
View Code? Open in Web Editor NEWDeclarative and reusable D3. Replace select, append, data and more with one function.
License: MIT License
Declarative and reusable D3. Replace select, append, data and more with one function.
License: MIT License
require()
, and had to run it through a local instance of packd to get a usable format.default
and renderSelection
; not sure what default
is for, and I would expect to have render
.In d3, when I process an event like mouseOver, the data passed into the event is the data that is bound to the DOM element.
When using d3-render, when I look at the data that is passed to the event, it is actually the data for d3-render element and not the actual data used to generate the render data.
For example, in d3, on a mouseover event, I can get the value to display in a tooltip to be the actual data (using d):
so I can show d.value
But when I look at the d passed to the event in d3-render, it is
Any suggestions for how to get to the actual d.value?
This may not be possible, because the data is abstracted away from the rendering, but that poses a bit of a challenge for how to render tooltips...
I was trying to use render to draw an axis, but I must be doing something wrong.
How do I translate this to a declarative object that I can render:
svg.append("g")
.attr("transform", `translate(${margin.left},0)`)
.call(d3.axisLeft(y))
.append("text")
.attr("style", `fill:black; font-weight: 700; font-size: 12px`)
.attr("text-anchor", "middle")
.attr("transform",`translate(-35,${(height-margin.bottom-margin.top)/2 + margin.top}),rotate(-90)`)
.text("Month");
I tried this:
{
append: "g",
transform: `translate(${margin.left},0)`,
call: d3.axisLeft(y)
}
But I get an error. Any help would be appreciated. I think I will find d3-render very useful, but am obviously missing a few concepts.
Thank you for the very interesting library.
I would like to implement it with a d3 force directed graph, where on every tick the current position of the nodes and links must be updated. https://observablehq.com/@ms007/fruits
Do I have to change the data and call render on every tick?
And must the nodes and links each have its own render function?
Thanks for your assistance
Hi,
I am using d3-render
for a project where I am displaying a time udpated with new data points on an interval. (So every x millisecond a data point gets pushed at the end of the series, and the graph shows the last y minutes).
I started with using a static axis (showing ticks for "now", "1 minute ago", "2 minutes ago" and so on) but have been looking into sliding axis (showing actual time, and sliding right as time moves on)
I started with this:
function renderGraph () {
d3Render([
{
append: "g",
transform: myAxisTranslate
call: d3.axisBottom(xScale) // xScale is a timeScale
}
]);
}
However the axis gets drawn correctly only once (the first time) and isn't sliding afterwards. I have looked at how d3Render
handles the call
key and gathered this would be because the function passed to call
is only executed once, when the element is added. Since my axis is only added once, the generator is only called once, and the axis is static.
I have worked around my problem like so:
function renderGraph () {
d3Render([
{
append: "g",
class: "x-axis"
transform: myAxisTranslate,
}
]);
d3.select(".x-axis").call(d3.axisBottom(xScale));
}
And the axis slides beautifully.
If this pattern is deemed okay then perhaps it could be mentioned somewhere in the doc (not just for dynamic axis, anything that uses a generator applied to a d3 element could benefit)
Alternatively one thing that could be done to address this would be maybe a forceCall
key? If provided it would call the supplied function each time the d3Render
function is called.
Either way happy to submit a PR.
Hi,
I see that d3Render changes camel-case in JavaScript to kebab-case. I am wondering how I should specify properties like markerHeight that must appear as a camel-case attribute in the SVG?
Ref: https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/markerHeight
Thanks!
I was following the first example in the README to create a page with the rectangle and it didn't work. Only when I proceeded to the example related to the "Updating Elements" I saw that something get rendered.
This does not work (svg element is not getting appended with the ellipse), however I see my console log:
import render from 'd3-render';
// Initial data
const data = [
{ append: 'ellipse', fill: 'red', rx: 200, ry: 150, duration: 1000 },
];
// Initial render on <svg id="#root"></svg>
render('#root', data);
console.log('boom!')
While this works:
import render from 'd3-render';
// After 20ms, change ellipse to blue
setTimeout(() => {
// Set some updated data
const newData = [
{ append: 'ellipse', fill: 'blue', rx: 200, ry: 150, duration: 1000 },
];
// Call render again
render('#root', newData);
console.log('boom boom')
}, 20);
It could easily be that I'm missing some assumption which prevents me from seeing the result, please let me know if that's the case.
Steps to reproduce:
npm init -y
npm install d3-render d3-selection d3-transition
dist/index.html
and src/index.js
npx webpack --mode=development
dist/index.html
in the browserThis is my html:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Getting Started</title>
<script src="main.js"></script>
</head>
<body>
<svg id="root" width="1000" height = "1000"></svg>
</body>
</html>
I'm trying to use this with Next.js, and when I import it using import render from "d3-render"
I get this error:
./node_modules/d3-render/dist/d3-render.esm.js
Attempted import error: 'event' is not exported from 'd3-selection'.
I looked at d3-selection
in my node-modules
and it looks like event
is no longer exported from it.
For now, I just remove event
from import { select, namespace, event, selection } from 'd3-selection'
in d3-render/dist/d3-render.esm.js
, and it works (but obviously without whatever events
did).
I don't really need events right now for my use case. I also want to say thank you for this module and your great tutorial on your bubble chart!
Hi,
I'm experimenting with this amazing library and I wanted to talk about some features that I would like to be present.
Most of them concern transitions.
Let's imagine that we wish the width to change in 100ms and the height in 1000ms (maybe allow this behaviour with delay
but that may be too much)
const datum = {
append: "rect",
- width: {enter: 100, exit: 0},
+ width: {enter: 100, exit: 0, duration: 100},
height: 100,
duration: 1000 // default duration
};
duration
, delay
and ease
.I found myself using the same values in different components, which boils down to something like
const t = {duration: 250, delay: 10, ease: d3.easeQuadInOut};
// later
const ExampleComponent = (c) => ({
append: "g",
// ...
...t,
...c
})
I feel that it could be more esthetic to directly pass a d3.transition object
const transition = d3.transition()
.duration(250)
.delay(10)
.ease(d3.easeQuadInOut);
// or
// const transition = {duration: 250, delay: 10, ease: d3.easeQuadInOut};
// ...later
const ExampleComponent = (c) => ({
append: "g",
// ...
transition,
...c
})
Which might also allow for transition chaining shenanigans.
When using d3-render
, I cannot interact the with the component I have currently selected:
const $svg = d3.create('svg')
.attr('width', "100")
.attr('height', '100')
.attr('viewBox', [0, 0, 50, 50]);
render($svg, [/*data*/]);
If I want to animate $svg
's attributes, i need to use $svg.transtion()...
, where something like this is waay better.
// by the power of d3-render
render(d3.create('svg'), {
width: 100,
height, 100,
viewBox: [0, 0, 50, 50],
duration: 100,
children: [/*data*/]
})
This is placed last, because it goes against the data->render flow. Because it might be an interesting case.
I wish my components had a react-like state/props approach. Where I could have some data which is passed down by data
and the rest is self managed.
working example : https://observablehq.com/@stardisblue/d3-render-self-controlled-components
In this example, the components are setup using call. But call is not triggered during "update" state. So I cannot do a state/props setup (as in react for example).
This is more a defaultstate/state approach.
This issue might be arguably the worst issue github as ever seen, as it presents no errors to fix and proposes way too much features. I was tempted to make several issues out of this one, but that felt like spam. So here are several features that I will be more that happy to see included. I can pull request you some of them but I feel like these [propositions] need an Okay from your side.
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.