Coder Social home page Coder Social logo

d3-node's Introduction

D3-Node

Build Status Codecov npm npm

Server-side D3 with ease

Tested on Nodejs v10 & up

maps and charts with d3-node

see examples >

js-standard-style

Why?

Basic usage:

NPM

Create a SVG

 const D3Node = require('d3-node')
 const d3n = new D3Node()      // initializes D3 with container element
 d3n.createSVG(10,20).append('g') // create SVG w/ 'g' tag and width/height
 d3n.svgString() // output: <svg width=10 height=20 xmlns="http://www.w3.org/2000/svg"><g></g></svg>

Advanced usage

Setting container & insertion point via selector

 const options = { selector: '#chart', container: '<div id="container"><div id="chart"></div></div>' }
 const d3n = new D3Node(options) // initializes D3 with container element
 const d3 = d3n.d3
 d3.select(d3n.document.querySelector('#chart')).append('span') // insert span tag into #chart
 d3n.html()   // output: <html><body><div id="container"><div id="chart"><span></span></div></div></body></html>
 d3n.chartHTML()   // output: <div id="chart"><span></span></div>

Inline SVG styles

 const d3n = new D3Node({styles:'.test {fill:#000;}'})
 d3n.createSVG().append('g')
 d3n.svgString()

Output

<svg xmlns="http://www.w3.org/2000/svg">
   <defs>
     <style type="text/css"><![CDATA[ .test{fill:#000;} ]]></style>
   </defs>
   <g></g>
<svg>

Create a canvas (for generating a png)

 const canvasModule = require('canvas'); // supports node-canvas v1 & v2.x
 const d3n = new D3Node({ canvasModule }); // pass it node-canvas
 const canvas = d3n.createCanvas(960, 500);
 const context = canvas.getContext('2d');
 // draw on your canvas, then output canvas to png
 canvas.pngStream().pipe(fs.createWriteStream('output.png'));

Run Tests:

$ npm test

TODOs:

  • Add more examples: (remote data, world map)
  • Create Gulp task
  • Add option to inject css/js into html output

d3-node's People

Contributors

bradoyler avatar dependabot[bot] avatar eranm6 avatar ffarzat avatar hems avatar t3db0t 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

d3-node's Issues

Can we publish the package as precompiled because npm production builds are failing because module has failed to compile

I am trying to use d3-node along with react js to plot chorolpleth maps. But it is not able to compile properly. It is failing because of jsdom dependency not getting resolved properly.

I am getting the following error

Failed to compile.

Failed to minify the code from this file: 

 	./node_modules/d3-node/node_modules/jsdom/lib/jsdom/living/generated/utils.js:5 

Can we have this package pre compiled.

Upgrade JSDOM version

The version of jsdom used by this project has a security vulnerability. In order to resolve this currently it looks like d3-node would have to use a more recent version of jsdom.

Any plans to upgrade so npm audit is happy?

Thanks


jsdom <=16.4.0
Severity: moderate
Insufficient Granularity of Access Control in JSDom - GHSA-f4c9-cqv8-9v98

split the examples to modules?

Hi,

Thanks for your awesome repo. I have a small tip that to split the examples to modules. It makes d3-node more scalable and minimal. Every example module can published to the npm which can be maintained independent, and more people could create the example. You also can have your own organization as a container to list these module.

Just my advice. thanks again ๐Ÿ‘

Add svg to canvas prior to png creation with pngStream()

Hi
I like d3-node to create inline svg server side with d3n.svgString()
I like d3-node to create png file from canvas server side with canvas.pngStream()
But i'm getting confused how to embed the svg into the canvas prior to the png file creation ...
Could you please help me to bridge the gap ?
Thanks in advance

Add new append

I'm trying to do this using d3-node to speed it up. But I'm encountering some issues, I'm basically trying to use the techanJS lib for creating candlestick graphics (http://bl.ocks.org/andredumas/27c4a333b0e0813e093d).
I used d3n.createSVG() for the creation of the first svg. However, it seems that this function only executes and returns nothing. And I'd like to know how I do to give a later append.

Example:

const svg = d3n.createSVG().append('g')
  .attr("width", 50)
  .attr("height", 50)
  .append("circle")
  .attr("cx", 25)
  .attr("cy", 25)
  .attr("r", 25)
  .style("fill", "purple")

After being created I can add some new information (append).
For example: svg.append(...)

Congratulations on the lib, it looks pretty promising.

Legend Issues

When trying to add a simple legend to my graph it throws the following error:
TypeError: Cannot read property 'apply' of undefined
From the following location: d3-selection/build/d3-selection.js:500:11

svg.append('g')
        .attr('class','legend')
        .attr('transform','translate(50,30)')
	.style('font-size','12px')
	.call(d3.legend)

Blurry PNG.

I am able to run the pie-canvas example to export a PNG image. However, the image looks blurry.

I then try the following approach:
1 enlarge the canvas dimensions so that we get a larger PNG;
2 limit the PNG to a smaller size when displayed in browser;
This way, the image looks sharper, but now a new issue arises: the labels appear smaller than desired, possibly because the image is down-sized when displayed.

How can I generate/display a sharp PNG image with properly-sized labels?

Thanks!

is mouse event non-available?

As this is a server side version of d3, so mouse event (eg. .on('mouseover', (d, i) => {...}) is not available even export the svg/html to frontend (web), right? The best we can do is to add a class attr so frontend can add style to it?

Upgrade to latest d3 version?

I'd like to use this with force graph but it looks like that was added in D3 6.0 and the current version of D3 is 5.0.

I tried forking and upgrading d3 7.0, but I quickly run into the fact that d3 is now only an ECMAScript modules (i.e. import) and not a CommonJS module (e.g. require). Trying to fix imports quickly turns into a mess with mocha and eslint.

I'm wondering if anyone has tried this before and gave up? Or if it's still worthwhile to keep going down this path?

How to add negative values to bar graph using d3 node?

I want to add negative values in bar graph using d3 node.
My code is


const D3Node = require('d3-node');
const fs = require('fs');
const sharp = require('sharp');


const options = {
    selector: '#chart',
    container: '<div id="container"><div id="chart"></div></div>'
  };
  
  // Create a d3-node object with the selector and the required d3 module. 
  const d3n = new D3Node(options);

  const d3=d3n.d3
  
  const margin = {
   top: 10, right: 5, bottom: 30, left: 5 
  };
  const width = 1000 - margin.left - margin.right;
  const height = 450 - margin.top - margin.bottom;
  const svgWidth = width + margin.left + margin.right;
  const svgHeight = height + margin.top + margin.bottom;
  
  // Create an svg element with the width and height defined.
  const svg = d3n.createSVG(svgWidth, svgHeight);


  const tempData = [{ year: 2020, value: 100 }, { year: 2019, value: -200 }, { year: 2018, value: 30 }, { year: 2017, value: 50 }, { year: 2016, value: 80 }];


  // Create the scales for x-axis and y-axis.
  const xScale = d3.scaleBand().range([0, width]).padding(0.4);
const yScale = d3.scaleLinear().range([height, 0]);

let yMax = d3.max(tempData, (d) => { return d.value; });
yMax += yMax * 0.3;


let yMin = d3.max(tempData, (d) => { return d.value; });
yMin += yMin * 0.3;
xScale.domain(tempData.map((d) => { return d.year; }));
yScale.domain([0, yMax]);




// Set the background of the entire svg to a desired color. This will make the background look uniform on everyone's computer.
svg.append('rect')
    .attr('width', '100%')
    .attr('height', '100%')
    .style('fill', 'white');

// Add a title text to your bar chart. 
svg.append('text')
  .attr('transform', 'translate(150,0)')
  .attr('x', 50)
  .attr('y', 50)
  .attr('font-size', '24px')
  .text('Node and D3 Bar chart');

// Append a group element to which the bars and axes will be added to.
svg.append('g').attr('transform', `translate(${ 100 },${ 100 })`);




// Appending x-axis
svg.append('g')
.attr('transform', `translate(50,${ height })`)
.call(d3.axisBottom(xScale))
.append('text')
.attr('y', height - 380)
.attr('x', width - 500)
.attr('text-anchor', 'end')
.attr('stroke', 'black')
.attr('font-size', '20px')
.text('Year');


// Appending y-aixs
svg.append('g')
  .attr('transform', 'translate(50,0)')
  .call(d3.axisLeft(yScale).tickFormat((d) => {
    return `$${ d }`;
  })
    .ticks(5))
  .append('text')
  .attr('transform', 'rotate(-90)')
  .attr('y', 150)
  .attr('x', -150)
  .attr('dy', '-9.1em')
  .attr('text-anchor', 'end')
  .attr('stroke', 'black')
  .attr('font-size', '20px')
  .text('Cost');


    // Appending the bars
    svg.selectAll('.bar')
    .data(tempData)
    .enter().append('rect')
    .attr('transform', 'translate(50,0)')
    .attr('class', 'bar')
    .attr('x', (d) => { return xScale(d.year); })
    .attr('y', (d) => { return yScale(d.value); })
    .attr('width', xScale.bandwidth())
    .attr('height', (d) => { return height - yScale(d.value); })
    .style('fill', 'orange');


    
// Create a SVG. 
fs.writeFileSync('out.svg', d3n.svgString());

// Convert the SVG into a PNG. 
sharp('out.svg')
    .png()
    .toFile('sharp.png')
    .then((info) => {
        console.log('Svg to Png conversion completed', info);
    })
    .catch((err) => {
        console.log(err);
    });

The negative values which i am using in dataset are displaying as zero in graph

How to bind event?

try to run following js file:

const D3Node = require('d3-node')
const output = require('d3node-output')
const d3n = new D3Node()
const d3 = d3n.d3

const svg = d3n.createSVG()
      .attr('width', 960)
      .attr('height', 500)
      .append('g')

const rect = svg.selectAll('rect')
      .data([0, 1, 2, 3, 4])
      .enter()
      .append('rect')
      .attr('width', 100)
      .attr('height', 50)
      .attr('transform', (d, i) => `translate(${i * 120}, 0)`)

rect.on('click', (d) => {
  console.log(d, 'clicked')
})

output('./example/output', d3n)

and nothing logged in the console when clicked the rect.

How to work with canvas-prebuilt?

I tried repeatedly and failed to get canvas installed on my OSX El Capitan machine, and so installed canvas-prebuilt.

I'm trying to do:

const canvasModule = require('canvas-prebuilt');
const d3n = new D3Node({ canvasModule });

But I'm getting Error: Install node-canvas for HTMLCanvasElement support. I've tried all kinds of variations of the destructured argument, but nothing's working. What am I missing?

Is this package still working for recent versions?

I'm new at D3 and was very pleased to find this package to help me produce SVG or PNG charts on the server. But I can't get going with it, and I wonder if it still works?
Here's what I have loaded (on macOS 11.6 with node 17.0.1):

d3tests:
โ”œโ”€โ”€ [email protected]
โ”œโ”€โ”€ [email protected]
โ”œโ”€โ”€ [email protected]
โ”œโ”€โ”€ [email protected]
โ””โ”€โ”€ [email protected]

Here's my minimal case, cobbled together from your various docs:

const fs = require('fs');
const d3 = require('d3-node')().d3;
const output = require('d3node-output');
const d3nBar = require('d3node-barchart');
// const d3nPie = require('d3node-piechart');
const csvString=`key,value
Bob,33
Robin,12
...
Charles,13
Mary,29`
const csvData = d3.csvParse(csvString);

const selector = `#chart`
const container = `<div id="container"><h2>Bar Chart</h2><div id="chart"></div></div>`
const style = `.bar{fill: steelblue;}
.bar:hover{fill: brown;}
.axis{font: 10px sans-serif;}
.axis path,.axis line{fill: none;stroke: #000;shape-rendering: crispEdges;}
.x.axis path{display: none;}`

// create output files
// const pie = d3nPie(csvData, selector, container, style)
const bar = d3nBar(csvData, selector, container, style)
output('output', bar);

I (and a friend on a completely different modern system) get this error:

/Users/jonathan/Dropbox/NPSummaries/NP-other-tests/node_modules/d3node-barchart/index.js:55
  x.domain(data.map((d) => d.key));
                ^

TypeError: Cannot read properties of undefined (reading 'map')
    at bar (/Users/jonathan/Dropbox/NPSummaries/NP-other-tests/node_modules/d3node-barchart/index.js:55:17)

If I comment out the barchart lines and use piechart instead I get this error:

/Users/jonathan/Dropbox/NPSummaries/NP-other-tests/node_modules/d3node-piechart/node_modules/d3-shape/build/d3-shape.js:504
        n = data.length,
                 ^

TypeError: Cannot read properties of undefined (reading 'length')
    at pie (/Users/jonathan/Dropbox/NPSummaries/NP-other-tests/node_modules/d3node-piechart/node_modules/d3-shape/build/d3-shape.js:504:18)

Any advice, please?

.svgString() automatically lowercases tags?

To reproduce, insert any element with a tag containing uppercase using selection.html(), and print it with the svg.svgString() function.

This is a sample output I'm getting :
<svg xmlns="http://www.w3.org/2000/svg" width="500" height="50"><radialgradient id="grad1" x1="10%" y1="10%" x2="80%" y2="90%"> <stop offset="0%" style="stop-color:#627AAD;stop-opacity:0.9"></stop> <stop offset="100%" style="stop-color:#3B5998;stop-opacity:0.9"></stop> </radialgradient><circle cx="25" cy="25" r="5" fill="url(#grad1)"></circle><circle cx="75" cy="25" r="10" fill="url(#grad1)"></circle><circle cx="125" cy="25" r="15" fill="url(#grad1)"></circle><circle cx="175" cy="25" r="20" fill="url(#grad1)"></circle><circle cx="225" cy="25" r="25" fill="url(#grad1)"></circle></svg>

Because svgString() lowercases the g in radialGradient, it will break the file, and the above svg does not get rendered.

You can take the above svg and change the radialgradient to radialGradient, it renders correctly.

no layout

    var pie=d3.layout.pie()
      .value(function(d){return d.percent})
      .sort(null);

this fails. d3.layout is undefined.

edit: nevermind. I found the issue:

    var D3Node = require('d3-node');
    var d3n = new D3Node();    // create instance
    var d3 = d3n.d3;

This solves my problem.

I see d3-node requires v3 of d3. Any plans to support v4?

How can we add events?

In D3 usually we can add events with the bind data, is there any way even a workaround to achieve that in a node project where D3 is being created on the server side and sent to client using d3N. Thanks

path.merge is not a function

Getting the following error.

TypeError: path.merge is not a function
at Array.axis (C:\Users\udaya\Projects\nodejsprojects\Mindy\node_modules\d3-
axis\build\d3-axis.js:68:19)
at Array.d3_selectionPrototype.call (C:\Users\udaya\Projects\nodejsprojects
Mindy\node_modules\d3-node\node_modules\d3\d3.js:975:14)
at Object.module.exports.genChart (C:\Users\udaya\Projects\nodejsprojects\Mi
ndy\d3chartgen\lib\lineChart.js:78:8)
at Object.module.exports.genChart (C:\Users\udaya\Projects\nodejsprojects\Mi
ndy\d3chartgen\chartgen.js:40:19)

I think there is d3 v3 and v4 compatibility problem. I am using d3 node along with d3 v4. even the examples dont work.

Issue with createCanvas

In index.js

In function D3Node.prototype.createCanvas

const canvas = new Canvas(width, height)
Is not working. It returns the error:
TypeError: Canvas is not a constructor

However
const canvas = new Canvas.Canvas(width, height)
works.

Error: Select

TypeError: Cannot read property 'select' of undefined

 var d3 = D3Node.d3
 var d3n = new D3Node()
 d3.select(d3n.document.body).append('span')
 console.log(d3n.html())```

I just copied the documentation.

Node 7.3.0

update to latest version of d3?

I'm getting the error

.attrs is not a function

when trying to simply run:

svg.append('rect').attrs({x:10})

i believe because this module depends on an older version of d3?

Lib is not compatible with node-canvas 2.5.0

There is missing the static "version" field on the Canvas class.
I need to hack node-canvas to make it work with d3-node:

import * as fs from 'fs';
const D3Node = require('d3-node');
import { Canvas } from 'canvas';
(Canvas as any).version = 1; // monkey patching to make it work with d3-node!

export const getScatterPlot = () => {
  const d3n = new D3Node({canvasModule: Canvas});
  const canvas = d3n.createCanvas(960, 500);
  const context = canvas.getContext('2d');
  canvas.pngStream().pipe(fs.createWriteStream('output.png'));
};

npm install stuck while trying update to run tests?

i tried to clone the repo and run the tests with the latest version but for some reason npm install is getting stuck when i try to run the tests.

perhaps some issue with devDependency: "git://github.com/bradoyler/d3.git#v3.5.17-pre" ?

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.