CHANGES.md 71.8 KB
Newer Older
Mike Bostock's avatar
Mike Bostock committed
1001
1002
1003
1004
* d3.time.fridayOfYear.utc ↦ [d3.utcFriday](https://github.com/d3/d3-time#utcFriday).[count](https://github.com/d3/d3-time#interval_count)
* d3.time.saturdayOfYear.utc ↦ [d3.utcSaturday](https://github.com/d3/d3-time#utcSaturday).[count](https://github.com/d3/d3-time#interval_count)
* d3.time.weekOfYear.utc ↦ [d3.utcWeek](https://github.com/d3/d3-time#utcWeek).[count](https://github.com/d3/d3-time#interval_count)

Mike Bostock's avatar
Mike Bostock committed
1005
D3 4.0 now also lets you define custom time intervals using [d3.timeInterval](https://github.com/d3/d3-time#timeInterval). The [d3.timeYear](https://github.com/d3/d3-time#timeYear), [d3.utcYear](https://github.com/d3/d3-time#utcYear), [d3.timeMillisecond](https://github.com/d3/d3-time#timeMillisecond) and [d3.utcMillisecond](https://github.com/d3/d3-time#utcMillisecond) intervals have optimized implementations of [*interval*.every](https://github.com/d3/d3-time#interval_every), which is necessary to generate time ticks for very large or very small domains efficiently. More generally, the performance of time intervals has been improved, and time intervals now do a better job with respect to daylight savings in various locales.
Mike Bostock's avatar
Mike Bostock committed
1006

Mike Bostock's avatar
Mike Bostock committed
1007
## [Timers (d3-timer)](https://github.com/d3/d3-timer/blob/master/README.md)
Mike Bostock's avatar
Mike Bostock committed
1008

Mike Bostock's avatar
Mike Bostock committed
1009
In D3 3.x, the only way to stop a timer was for its callback to return true. For example, this timer stops after one second:
Mike Bostock's avatar
Mike Bostock committed
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028

```js
d3.timer(function(elapsed) {
  console.log(elapsed);
  return elapsed >= 1000;
});
```

In 4.0, use [*timer*.stop](https://github.com/d3/d3-timer#timer_stop) instead:

```js
var t = d3.timer(function(elapsed) {
  console.log(elapsed);
  if (elapsed >= 1000) {
    t.stop();
  }
});
```

Mike Bostock's avatar
Mike Bostock committed
1029
The primary benefit of *timer*.stop is that timers are not required to self-terminate: they can be stopped externally, allowing for the immediate and synchronous disposal of associated resources, and the separation of concerns. The above is equivalent to:
Mike Bostock's avatar
Mike Bostock committed
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040

```js
var t = d3.timer(function(elapsed) {
  console.log(elapsed);
});

d3.timeout(function() {
  t.stop();
}, 1000);
```

Mike Bostock's avatar
Mike Bostock committed
1041
This improvement extends to [d3-transition](#transitions-d3-transition): now when a transition is interrupted, its resources are immediately freed rather than having to wait for transition to start.
Mike Bostock's avatar
Mike Bostock committed
1042

Mike Bostock's avatar
Mike Bostock committed
1043
4.0 also introduces a new [*timer*.restart](https://github.com/d3/d3-timer#timer_restart) method for restarting timers, for replacing the callback of a running timer, or for changing its delay or reference time. Unlike *timer*.stop followed by [d3.timer](https://github.com/d3/d3-timer#timer), *timer*.restart maintains the invocation priority of an existing timer: it guarantees that the order of invocation of active timers remains the same.
Mike Bostock's avatar
Mike Bostock committed
1044
1045
1046
1047
1048
1049
1050
1051
1052

Some usage patterns in D3 3.x could cause the browser to hang when a background page returned to the foreground. For example, the following code schedules a transition every second:

```js
setInterval(function() {
  d3.selectAll("div").transition().call(someAnimation); // BAD
}, 1000);
```

Mike Bostock's avatar
Mike Bostock committed
1053
If such code runs in the background for hours, thousands of queued transitions will try to run simultaneously when the page is foregrounded. D3 4.0 avoids this hang by freezing time in the background: when a page is in the background, time does not advance, and so no queue of timers accumulates to run when the page returns to the foreground. Use d3.timer instead of transitions to schedule a long-running animation, or use [d3.timeout](https://github.com/d3/d3-timer#timeout) and [d3.interval](https://github.com/d3/d3-timer#interval) in place of setTimeout and setInterval to prevent transitions from being queued in the background:
Mike Bostock's avatar
Mike Bostock committed
1054
1055
1056
1057
1058
1059
1060

```js
d3.interval(function() {
  d3.selectAll("div").transition().call(someAnimation); // GOOD
}, 1000);
```

Mike Bostock's avatar
Mike Bostock committed
1061
By freezing time in the background, timers are effectively “unaware” of being backgrounded. It’s like nothing happened! 4.0 also now uses high-precision time ([performance.now](https://developer.mozilla.org/en-US/docs/Web/API/Performance/now)) where available; the current time is available as [d3.now](https://github.com/d3/d3-timer#now).
Mike Bostock's avatar
Mike Bostock committed
1062

Mike Bostock's avatar
Mike Bostock committed
1063
The d3.timer.flush method has been renamed to [d3.timerFlush](https://github.com/d3/d3-timer#timerFlush).
Mike Bostock's avatar
Mike Bostock committed
1064

Mike Bostock's avatar
Mike Bostock committed
1065
## [Transitions (d3-transition)](https://github.com/d3/d3-transition/blob/master/README.md)
Mike Bostock's avatar
Mike Bostock committed
1066

Mike Bostock's avatar
Mike Bostock committed
1067
1068
TODO

Mike Bostock's avatar
Mike Bostock committed
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
* transitions are immutable, too; *transition*.merge
* *transition*.each ↦ *transition*.on
* *transition*.each is now the same as *selection*.each
* new d3.active for chaining transitions / modifying in-progress transitions
* new *selection*.transition(*transition*); searches ancestors
* new d3.interrupt
* change *transition*.transition semantics in regards to *transition*.delay
* strict state machine to enforce when transitions can be modified; more robust
* enforces *t* = 1 on end
* functions passed to transition methods take the same standard arguments as selections
* optimize transitions to re-use tweens and interpolators to improve performance!
* *transition*.attrTween gets standard arguments (not current attribute value)
* *transition*.styleTween gets standard arguments (not current style value)
* call *transition*.{tween,attrTween,styleTween} in getter mode
* uses optimized interpolator rather than d3.interpolate
* fix *transition*.remove if multiple transition names are in use
* new *transition*.selection
Mike Bostock's avatar
Mike Bostock committed
1086
1087
1088
* changed *transition*.ease to always take an easing function, not a name
* see also d3-timer, d3-ease, d3-interpolate
* in particular note that transitions are now frozen in the background! and there’s d3.timeout, d3.interval
Mike Bostock's avatar
Mike Bostock committed
1089

Mike Bostock's avatar
Mike Bostock committed
1090
## [Voronoi Diagrams (d3-voronoi)](https://github.com/d3/d3-voronoi/blob/master/README.md)
Mike Bostock's avatar
Mike Bostock committed
1091

Mike Bostock's avatar
Mike Bostock committed
1092
1093
TODO

Mike Bostock's avatar
Mike Bostock committed
1094
* d3.geom.voronoi ↦ d3.voronoi
Mike Bostock's avatar
Mike Bostock committed
1095
1096
1097
1098
1099
1100
1101
1102
* *voronoi*.clipExtent ↦ *voronoi*.extent
* *voronoi* now returns the full Voronoi diagram
* new *voronoi*.polygons returns clipped polygons
* *voronoi*.polygons and *diagram*.polygons require an extent
* the diagram can be used to compute Voronoi & Delaunay simultaneously
* the diagram also exposes topology, which is useful for TopoJSON applications
* well-defined behavior for coincident vertices: subsequent cells are null
* input data exposed as *polygon*.data, not *polygon*.point
Mike Bostock's avatar
Mike Bostock committed
1103

Mike Bostock's avatar
Mike Bostock committed
1104
## [Zooming (d3-zoom)](https://github.com/d3/d3-zoom/blob/master/README.md)
Mike Bostock's avatar
Mike Bostock committed
1105

Mike Bostock's avatar
Mike Bostock committed
1106
1107
TODO

Mike Bostock's avatar
Mike Bostock committed
1108
* d3.behavior.zoom ↦ d3.zoom
Mike Bostock's avatar
Mike Bostock committed
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
* ignore wheel events if at limits of scale extent
* ignores right-click by default
* new *zoom*.translateExtent!
* consume handled events
* new *zoom*.transform replaces *zoom*.event; *zoom* behavior is stateless
* new *zoom*.translateBy
* new *zoom*.scaleBy
* new *zoom*.scaleTo
* new *zoom*.filter
* removed *zoom*.center; use programmatic zooming instead
* *zoom*.size ↦ *zoom*.extent; better default extent using the DOM
* *zoomstart* event ↦ *start* event
* *zoomend* event ↦ *end* event

new d3.zoomTransform API

* *event*.scale, *event*.translate ↦ *event*.transform
* *zoom*.x ↦ *transform*.rescaleX
* *zoom*.y ↦ *transform*.rescaleY