# d3-3d
**d3-3d** is meant for 3d visualizations. **d3-3d** allows the projection of 3d data onto the screen in the webbrowser. It is specially designed to work with **[d3.js](https://d3js.org/)**.
[![Codecov](https://img.shields.io/codecov/c/github/niekes/d3-3d)](https://app.codecov.io/gh/niekes/d3-3d)
[![Travis (.org) branch](https://travis-ci.com/Niekes/d3-3d.svg?branch=master)](https://travis-ci.com/github/Niekes/d3-3d)
[![npm](https://img.shields.io/npm/dt/d3-3d)](https://www.npmjs.com/package/d3-3d)
[![npm](https://img.shields.io/npm/dw/d3-3d)](https://www.npmjs.com/package/d3-3d)
[![npm](https://img.shields.io/npm/l/d3-3d)](https://github.com/Niekes/d3-3d/blob/master/LICENSE)
[![npm bundle size](https://img.shields.io/bundlephobia/minzip/d3-3d)](https://bundlephobia.com/result?p=d3-3d)
[![npm](https://img.shields.io/npm/v/d3-3d)](https://www.npmjs.com/package/d3-3d)
See more examples.
## Installing
If you use npm, `npm install d3-3d`. You can also download the [latest release](https://github.com/Niekes/d3-3d/releases). Otherwise use [unpkg](https://unpkg.com/d3-3d/) to get the latest release. For example:
```html
```
For a specific version:
```html
```
## Import
ES6:
```js
import { _3d } from 'd3-3d' ;
```
## API Reference
* [d3._3d](#_3d) - create a new 3d function object.
* [*_3d*.shape](#shape) - set the shape.
* [*_3d*.x](#x) - set the x accessor.
* [*_3d*.y](#y) - set the y accessor.
* [*_3d*.z](#z) - set the z accessor.
* [*_3d*.scale](#scale) - sets the scale for the projected points.
* [*_3d*.rotateX](#rotateX) - set the angle for the x rotation.
* [*_3d*.rotateY](#rotateY) - set the angle for the y rotation.
* [*_3d*.rotateZ](#rotateZ) - set the angle for the z rotation.
* [*_3d*.rotateCenter](#rotateCenter) - set the the rotation center.
* [*_3d*.sort](#sort) - sort the 3d elements by the centroid.
* [*_3d*.draw](#draw) - draw the 3d elements.
### Overview
**d3-3d** uses the [browser's coordinate system](https://www.w3.org/TR/css-transforms-1/#transform-rendering) and [orthographic projection](https://en.wikipedia.org/wiki/Orthographic_projection) to display your data on the screen. It will calculate the centroid for all elements and the orientation for your polygons. Due to the fact that SVG isn't very 3d compatible **d3-3d** adds 3d transformations to SVG.
With **d3-3d** you can easily visualize your 3d data.
```js
var data3D = [ [[0,-1,0],[-1,1,0],[1,1,0]] ];
var triangles3D = d3._3d()
.scale(100)
.origin([480, 250])
.shape('TRIANGLE');
var projectedData = triangles3D(data3D);
init(projectedData);
function init(data){
var triangles = svg.selectAll('path').data(data);
// add your logic here...
}
```
# d3.**_3d**() [<>](https://github.com/Niekes/d3-3d/blob/master/src/3d.js#L58 "Source")
Constructs a new function object with the default settings.
### Shapes
Depending on the shape the input data array has to be accordingly to the shape.
* **POINT** A point is represented by the `` element. It does not have a draw function because it can be represented as a ``. The input data array has to be an array of points where each point has three coordinates which can be accessed via the [x](#x), [y](#y) and [z](#z) accessors.
* **LINE** A line is represented by the `` element. It does not have a draw function because it can be represented as a ``. The input data array has to be an array of lines where each line is defined by a start- and an endpoint.
* **LINE_STRIP** A continuous line is represented by the `` element. The input data array has to be an array of points. Every point will be connected to the next point in the input data array.
* **TRIANGLE** A triangle represented by the `` element. The input data array has to be an array of triangles where each triangle is defined by three points in counter-clockwise order.
* **PLANE** A plane is represented by the `` element. The input data array has to be an array of planes where each plane is defined by four points in counter-clockwise order.
* **GRID** A grid is represented by x planes. The input data array has to be an array of points. The [shape](#shape) function aspects the amount of points per row as a second argument. **d3-3d** will construct planes out of the passed data.
_NOTE:_ A grid has to have always the same number of points per row. Otherwise the code will break.
* **SURFACE** equivalent to `GRID`
* **CUBE** A grid is represented by 4 planes. The input data array has to be an array of cubes where each cube is defined by 8 vertices. To get the orientation and centroid calculation right you should pass in the data like so:
![cube](assets/cube.png "Cube")
# _3d.**shape**(shape) [<>](https://github.com/Niekes/d3-3d/blob/master/src/3d.js#L87 "Source")
_Default:_ `'POINT'`
Sets the shape to *shape*. If *shape* is not specified the current shape will be returned.
If *shape* is specified, sets the shape to the specified shape and returns the **d3-3d** function object. If *shape* is not specified, returns the current shape.
```js
var triangles3D = d3._3d().shape('TRIANGLE');
```
# _3d.**x**([x]) [<>](https://github.com/Niekes/d3-3d/blob/master/src/point.js#L1 "Source")
If *x* is specified, sets the x accessor to the specified function or number and returns the **d3-3d** function object. If *x* is not specified, returns the current x accessor, which defaults to:
```js
function x(p) {
return p[0];
}
```
This function will be invoked for each point in the input data array.
# _3d.**y**([y]) [<>](https://github.com/Niekes/d3-3d/blob/master/src/point.js#L5 "Source")
If *y* is specified, sets the y accessor to the specified function or number and returns the **d3-3d** function object. If *y* is not specified, returns the current y accessor, which defaults to:
```js
function y(p) {
return p[1];
}
```
This function will be invoked for each point in the input data array.
# _3d.**z**([z]) [<>](https://github.com/Niekes/d3-3d/blob/master/src/point.js#L9 "Source")
If *z* is specified, sets the z accessor to the specified function or number and returns the **d3-3d** function object. If *z* is not specified, returns the current z accessor, which defaults to:
```js
function z(p) {
return p[2];
}
```
This function will be invoked for each point in the input data array.
# _3d.**scale**(scale) [<>](https://github.com/Niekes/d3-3d/blob/master/src/3d.js#L71 "Source")
_Default:_ `1`
If *scale* is specified, sets the scale to the specified number and returns the **d3-3d** function object. If *scale* is not specified, returns the current scale.
# _3d.**rotateX**(angle) [<>](https://github.com/Niekes/d3-3d/blob/master/src/3d.js#L75 "Source")
_Default:_ `0`
If *angle* is specified, sets rotateX to the specified number and returns the **d3-3d** function object. If *angle* is not specified, returns the current angle.
# _3d.**rotateY**(angle) [<>](https://github.com/Niekes/d3-3d/blob/master/src/3d.js#L79 "Source")
_Default:_ `0`
If *angle* is specified, sets rotateY to the specified number and returns the **d3-3d** function object. If *angle* is not specified, returns the current angle.
# _3d.**rotateZ**(angle) [<>](https://github.com/Niekes/d3-3d/blob/master/src/3d.js#L83 "Source")
_Default:_ `0`
If *angle* is specified, sets rotateZ to the specified number and returns the **d3-3d** function object. If *angle* is not specified, returns the current angle.
# _3d.**rotateCenter**(point) [<>](https://github.com/Niekes/d3-3d/blob/master/src/3d.js#L87 "Source")
_Default:_ `[0, 0, 0]`
If *point* is specified, sets rotateCenter to the specified point and returns the **d3-3d** function object. If *rotateCenter* is not specified, returns the current rotateCenter.
# _3d.**sort**(a,b) [<>](https://github.com/Niekes/d3-3d/blob/master/src/3d.js#107 "Source")
Sorts the elements accordingly to the z coordinate of the calculated centroid.
# _3d.**draw**(shape) [<>](https://github.com/Niekes/d3-3d/blob/master/src/3d.js#107 "Source")
Constructs a string for the SVG `` element. Depending on the [shape](#shape) this function will take care how the elements get drawn. For instance, if you choose `'TRIANGLE'` **d3-3d** aspects that you want to draw a triangle with three points and each point has three coordinates. The [*_3d*.draw](#draw) method will draw a triangle with these three points. If you want to draw a plane, you have to pass in four points and so on.
# Funding