D3 V3 与V4的变化

Changes in D3 4.0

D3 4.0 is modular. Instead of one library, D3 is now many small libraries that are designed to work together. You can pick and choose which parts to use as you see fit. Each library is maintained in its own repository, allowing decentralized ownership and independent release cycles. The default bundle combines about thirty of these microlibraries.

<script src="https://d3js.org/d3.v4.js"></script>

As before, you can load optional plugins on top of the default bundle, such as ColorBrewer scales:

<script src="https://d3js.org/d3.v4.js"></script>
<script src="https://d3js.org/d3-scale-chromatic.v0.3.js"></script>

You are not required to use the default bundle! If you’re just using d3-selection, use it as a standalone library. Like the default bundle, you can load D3 microlibraries using vanilla script tags or RequireJS (great for HTTP/2!):

<script src="https://d3js.org/d3-selection.v1.js"></script>

You can also cat D3 microlibraries into a custom bundle, or use tools such as Webpack and Rollup to create optimized bundles. Custom bundles are great for applications that use a subset of D3’s features; for example, a React chart library might use D3 for scales and shapes, and React to manipulate the DOM. The D3 microlibraries are written as ES6 modules, and Rollup lets you pick at the symbol level to produce smaller bundles.

Small files are nice, but modularity is also about making D3 more fun. Microlibraries are easier to understand, develop and test. They make it easier for new people to get involved and contribute. They reduce the distinction between a “core module” and a “plugin”, and increase the pace of development in D3 features.

If you don’t care about modularity, you can mostly ignore this change and keep using the default bundle. However, there is one unavoidable consequence of adopting ES6 modules: every symbol in D3 4.0 now shares a flat namespace rather than the nested one of D3 3.x. For example, d3.scale.linear is now d3.scaleLinear, and d3.layout.treemap is now d3.treemap. The adoption of ES6 modules also means that D3 is now written exclusively in strict mode and has better readability. And there have been many other significant improvements to D3’s features! (Nearly all of the code from D3 3.x has been rewritten.) These changes are covered below.

Other Global Changes

The default UMD bundle is now anonymous. No d3 global is exported if AMD or CommonJS is detected. In a vanilla environment, the D3 microlibraries share the d3 global, even if you load them independently; thus, code you write is the same whether or not you use the default bundle. (See Let’s Make a (D3) Plugin for more.) The generated bundle is no longer stored in the Git repository; Bower has been repointed to d3-bower, and you can find the generated files on npm or attached to the latest release. The non-minified default bundle is no longer mangled, making it more readable and preserving inline comments.

To the consternation of some users, 3.x employed Unicode variable names such as λ, φ, τ and π for a concise representation of mathematical operations. A downside of this approach was that a SyntaxError would occur if you loaded the non-minified D3 using ISO-8859-1 instead of UTF-8. 3.x also used Unicode string literals, such as the SI-prefix µ for 1e-6. 4.0 uses only ASCII variable names and ASCII string literals (see rollup-plugin-ascii), avoiding encoding problems.

Table of Contents

Arrays (d3-array)

The new d3.scan method performs a linear scan of an array, returning the index of the least element according to the specified comparator. This is similar to d3.min and d3.max, except you can use it to find the position of an extreme element, rather than just calculate an extreme value.

var data = [
  {name: "Alice", value: 2},
  {name: "Bob", value: 3},
  {name: "Carol", value: 1},
  {name: "Dwayne", value: 5}
];

var i = d3.scan(data, function(a, b) { return a.value - b.value; }); // 2
data[i]; // {name: "Carol", value: 1}

The new d3.ticks and d3.tickStep methods are useful for generating human-readable numeric ticks. These methods are a low-level alternative to continuous.ticks from d3-scale. The new implementation is also more accurate, returning the optimal number of ticks as measured by relative error.

var ticks = d3.ticks(0, 10, 5); // [0, 2, 4, 6, 8, 10]

The d3.range method no longer makes an elaborate attempt to avoid floating-point error when step is not an integer. The returned values are strictly defined as start + i * step, where i is an integer. (Learn more about floating point math.) d3.range returns the empty array for infinite ranges, rather than throwing an error.

The method signature for optional accessors has been changed to be more consistent with array methods such as array.forEach: the accessor is passed the current element (d), the index (i), and the array (data), with this as undefined. This affects d3.min,d3.maxd3.extentd3.sumd3.meand3.mediand3.quantiled3.variance and d3.deviation. The d3.quantile method previously did not take an accessor. Some methods with optional arguments now treat those arguments as missing if they are null or undefined, rather than strictly checking arguments.length.

The new d3.histogram API replaces d3.layout.histogram. Rather than exposing bin.x and bin.dx on each returned bin, the histogram exposes bin.x0 and bin.x1, guaranteeing that bin.x0 is exactly equal to bin.x1 on the preceeding bin. The “frequency” and “probability” modes are no longer supported; each bin is simply an array of elements from the input data, so bin.length is equal to D3 3.x’s bin.y in frequency mode. To compute a probability distribution, divide the number of elements in each bin by the total number of elements.

The histogram.range method has been renamed histogram.domain for consistency with scales. The histogram.bins method has been renamed histogram.thresholds, and no longer accepts an upper value: n thresholds will produce n + 1 bins. If you specify a desired number of bins rather than thresholds, d3.histogram now uses d3.ticks to compute nice bin thresholds. In addition to the default Sturges’ formula, D3 now implements the Freedman-Diaconis rule and Scott’s normal reference rule.

Axes (d3-axis)

To render axes properly in D3 3.x, you needed to style them:

<style>

.axis path,
.axis line {
   
  fill: none;
  stroke: #000;
  shape-rendering: crispEdges;
}

.axis text {
   
  font: 10px sans-serif;
}

</style>
<script>

d3.select(".axis")
    .call(d3.svg.axis()
        .scale(x)
        .orient("bottom"));

</script>

If you didn’t, you saw this:

D3 4.0 provides default styles and shorter syntax. In place of d3.svg.axis and axis.orient, D3 4.0 now provides four constructors for each orientation: d3.axisTopd3.axisRightd3.axisBottomd3.axisLeft. These constructors accept a scale, so you can reduce all of the above to:

<script>

d3.select(".axis")
    .call(d3.axisBottom(x));

</script>

And get this:

As before, you can customize the axis appearance either by applying stylesheets or by modifying the axis elements. The default appearance has been changed slightly to offset the axis by a half-pixel; this fixes a crisp-edges rendering issue on Safari where the axis would be drawn two-pixels thick.

There’s now an axis.tickArguments method, as an alternative to axis.ticks that also allows the axis tick arguments to be inspected. The axis.tickSize method has been changed to only allow a single argument when setting the tick size. The axis.innerTickSize andaxis.outerTickSize methods have been renamed axis.tickSizeInner and axis.tickSizeOuter, respectively.

Brushes (d3-brush)

Replacing d3.svg.brush, there are now three classes of brush for brushing along the x-dimension, the y-dimension, or both:d3.brushXd3.brushYd3.brush. Brushes are no longer dependent on scales; instead, each brush defines a selection in screen coordinates. This selection can be inverted if you want to compute the corresponding data domain. And rather than rely on the scales’ ranges to determine the brushable area, there is now a brush.extent method for setting it. If you do not set the brush extent, it defaults to the full extent of the owner SVG element. The brush.clamp method has also been eliminated; brushing is always restricted to the brushable area defined by the brush extent.

Brushes no longer store the active brush selection (i.e., the highlighted region; the brush’s position) internally. The brush’s position is now stored on any elements to which the brush has been applied. The brush’s position is available as event.selection within a brush event or by calling d3.brushSelection on a given element. To move the brush programmatically, use brush.movewith a given selection or transition; see the brush snapping example. The brush.event method has been removed.

Brush interaction has been improved. By default, brushes now ignore right-clicks intended for the context menu; you can change this behavior using brush.filter. Brushes also ignore emulated mouse events on iOS. Holding down SHIFT (⇧) while brushing locks the x- or y-position of the brush. Holding down META (⌘) while clicking and dragging starts a new selection, rather than translating the existing selection.

The default appearance of the brush has also been improved and slightly simplified. Previously it was necessary to apply styles to the brush to give it a reasonable appearance, such as:

.brush .extent {
  stroke: #fff;
  fill-opacity: .125;
  shape-rendering: crispEdges;
}

These styles are now applied by default as attributes; if you want to customize the brush appearance, you can still apply external styles or modify the brush elements. (D3 4.0 features a similar improvement to axes.) A new brush.handleSize method lets you override the brush handle size; it defaults to six pixels.

The brush now consumes handled events, making it easier to combine with other interactive behaviors such as dragging andzooming. The brushstart and brushend events have been renamed to start and end, respectively. The brush event no longer reports a event.mode to distinguish between resizing and dragging the brush.

Chords (d3-chord)

Pursuant to the great namespace flattening:

For consistency with arc.padAnglechord.padding has also been renamed to ribbon.padAngle. A new ribbon.context method lets you render chord diagrams to Canvas! See also d3-path.

Collections (d3-collection)

The d3.set constructor now accepts an existing set for making a copy. If you pass an array to d3.set, you can also pass a value accessor. This accessor takes the standard arguments: the current element (d), the index (i), and the array (data), with thisundefined. For example:

var yields = [
  {yield: 22.13333, variety: "Manchuria",        year: 1932, site: "Grand Rapids"},
  {yield: 26.76667, variety: "Peatland",         year: 1932, site: "Grand Rapids"},
  {yield: 28.10000, variety: "No. 462",          year: 1931, site: "Duluth"},
  {yield: 38.50000, variety: "Svansota",         year: 1932, site: "Waseca"},
  {yield: 40.46667, variety: "Svansota",         year: 1931, site: "Crookston"},
  {yield: 36.03333, variety: "Peatland",         year: 1932, site: "Waseca"},
  {yield: 34.46667, variety: "Wisconsin No. 38", year: 1931, site: "Grand Rapids"}
];

var sites = d3.set(yields, function(d) { return d.site; }); // Grand Rapids, Duluth, Waseca, Crookston

The d3.map constructor also follows the standard array accessor argument pattern.

The map.forEach and set.forEach methods have been renamed to map.each and set.each respectively. The order of arguments formap.each has also been changed to valuekey and map, while the order of arguments for set.each is now valuevalue and set. This is closer to ES6 map.forEach and set.forEach. Also like ES6 Map and Set, map.set and set.add now return the current collection (rather than the added value) to facilitate method chaining. New map.clear and set.clear methods can be used to empty collections.

The nest.map method now always returns a d3.map instance. For a plain object, use nest.object instead. When used in conjunction with nest.rollupnest.entries now returns {key, value} objects for the leaf entries, instead of {key, values}. This makesnest.rollup easier to use in conjunction with hierarchies, as in this Nest Treemap example.

Colors (d3-color)

All colors now have opacity exposed as color.opacity, which is a number in [0, 1]. You can pass an optional opacity argument to the color space constructors d3.rgbd3.hsld3.labd3.hcl or d3.cubehelix.

You can now parse rgba(…) and hsla(…) CSS color specifiers or the string “transparent” using d3.color. The “transparent” color is defined as an RGB color with zero opacity and undefined red, green and blue channels; this differs slightly from CSS which defines it as transparent black, but is useful for simplifying color interpolation logic where either the starting or ending color has undefined channels. The color.toString method now likewise returns an rgb(…) or rgba(…) string with integer channel values, not the hexadecimal RGB format, consistent with CSS computed values. This improves performance by short-circuiting transitions when the element’s starting style matches its ending style.

The new d3.color method is the primary method for parsing colors: it returns a d3.color instance in the appropriate color space, or null if the CSS color specifier is invalid. For example:

var red = d3.color("hsl(0, 80%, 50%)"); // {h: 0, l: 0.5, s: 0.8, opacity: 1}

The parsing implementation is now more robust. For example, you can no longer mix integers and percentages in rgb(…), and it correctly handles whitespace, decimal points, number signs, and other edge cases. The color space constructors d3.rgb, d3.hsl, d3.lab, d3.hcl and d3.cubehelix now always return a copy of the input color, converted to the corresponding color space. Whilecolor.rgb remains, rgb.hsl has been removed; use d3.hsl to convert a color to the RGB color space.

The RGB color space no longer greedily quantizes and clamps channel values when creating colors, improving accuracy in color space conversion. Quantization and clamping now occurs in color.toString when formatting a color for display. You can use the new color.displayable to test whether a color is out-of-gamut.

The rgb.brighter method no longer special-cases black. This is a multiplicative operator, defining a new color r′, g′, b′ where r′ = r× pow(0.7, k), g′ = g × pow(0.7, k) and b′ = b × pow(0.7, k); a brighter black is still black.

There’s a new d3.cubehelix color space, generalizing Dave Green’s color scheme! (See also d3.interpolateCubehelixDefault fromd3-scale.) You can continue to define your own custom color spaces, too; see d3-hsv for an example.

Dispatches (d3-dispatch)

Rather than decorating the dispatch object with each event type, the dispatch object now exposes generic dispatch.call anddispatch.apply methods which take the type string as the first argument. For example, in D3 3.x, you might say:

dispatcher.foo.call(that, "Hello, Foo!");

To dispatch a foo event in D3 4.0, you’d say:

dispatcher.call("foo", that, "Hello, Foo!");

The dispatch.on method now accepts multiple typenames, allowing you to add or remove listeners for multiple events simultaneously. For example, to send both foo and bar events to the same listener:

dispatcher.on("foo bar", function(message) {
  console.log(message);
});

This matches the new behavior of selection.on in d3-selection. The dispatch.on method now validates that the specifier listener is a function, rather than throwing an error in the future.

The new implementation d3.dispatch is faster, using fewer closures to improve performance. There’s also a new dispatch.copymethod for making a copy of a dispatcher; this is used by d3-transition to improve the performance of transitions in the common case where all elements in a transition have the same transition event listeners.

Dragging (d3-drag)

The drag behavior d3.behavior.drag has been renamed to d3.drag. The drag.origin method has been replaced by drag.subject, which allows you to define the thing being dragged at the start of a drag gesture. This is particularly useful with Canvas, where draggable objects typically share a Canvas element (as opposed to SVG, where draggable objects typically have distinct DOM elements); see the circle dragging example.

A new drag.container method lets you override the parent element that defines the drag gesture coordinate system. This defaults to the parent node of the element to which the drag behavior was applied. For dragging on Canvas elements, you probably want to use the Canvas element as the container.

Drag events now expose an event.on method for registering temporary listeners for duration of the current drag gesture; these listeners can capture state for the current gesture, such as the thing being dragged. A new event.active property lets you detect whether multiple (multitouch) drag gestures are active concurrently. The dragstart and dragend events have been renamed tostart and end. By default, drag behaviors now ignore right-clicks intended for the context menu; use drag.filter to control which events are ignored. The drag behavior also ignores emulated mouse events on iOS. The drag behavior now consumes handled events, making it easier to combine with other interactive behaviors such as zooming.

The new d3.dragEnable and d3.dragDisable methods provide a low-level API for implementing drag gestures across browsers and devices. These methods are also used by other D3 components, such as the brush.

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
好的,根据您提供的图和要求,我们可以使用距离矩阵法来求解从起点Vs到终点Vt的最短路径。具体步骤如下: 1. 初始化距离矩阵D0,将距离矩阵中Vs到自己的距离设为0,其他节点之间的距离根据图中的路径来设置。 ``` 距离矩阵D0: | Vs V1 V2 V3 V4 Vt --|------------------ Vs| 0 3 1 ∞ ∞ ∞ V1| ∞ 0 2 4 ∞ ∞ V2| ∞ 2 0 3 7 ∞ V3| ∞ ∞ ∞ 0 3 6 V4| ∞ ∞ ∞ ∞ 0 1 Vt| ∞ ∞ ∞ ∞ ∞ 0 ``` 2. 迭代更新距离矩阵,每次选择距离起点Vs最近的未访问节点进行更新。 - 第一轮迭代,选择起点Vs,将Vs标记为已访问。 ``` 距离矩阵D1: | Vs V1 V2 V3 V4 Vt --|------------------ Vs| 0 3 1 ∞ ∞ ∞ V1| ∞ 0 2 4 ∞ ∞ V2| ∞ 2 0 3 7 ∞ V3| ∞ ∞ ∞ 0 3 6 V4| ∞ ∞ ∞ ∞ 0 1 Vt| ∞ ∞ ∞ ∞ ∞ 0 已访问节点集合S:{Vs} ``` - 第二轮迭代,选择距离起点Vs最近的节点V2,将V2标记为已访问,更新距离矩阵中V1、V3V4的距离。 ``` 距离矩阵D2: | Vs V1 V2 V3 V4 Vt --|------------------ Vs| 0 3 1 ∞ ∞ ∞ V1| 3 0 2 4 ∞ ∞ V2| ∞ 2 0 3 7 ∞ V3| ∞ 4 3 0 3 6 V4| ∞ ∞ 7 ∞ 0 1 Vt| ∞ ∞ ∞ ∞ ∞ 0 已访问节点集合S:{Vs, V2} ``` - 第三轮迭代,选择距离起点Vs最近的节点V1,将V1标记为已访问,更新距离矩阵中V3V4的距离。 ``` 距离矩阵D3: | Vs V1 V2 V3 V4 Vt --|------------------ Vs| 0 3 1 ∞ ∞ ∞ V1| 3 0 2 4 ∞ 1 V2| ∞ 2 0 3 7 ∞ V3| ∞ 4 3 0 3 6 V4| ∞ ∞ 7 ∞ 0 1 Vt| ∞ ∞ ∞ ∞ ∞ 0 已访问节点集合S:{Vs, V2, V1} ``` - 第四轮迭代,选择距离起点Vs最近的节点V3,将V3标记为已访问,更新距离矩阵中V4的距离。 ``` 距离矩阵D4: | Vs V1 V2 V3 V4 Vt --|------------------ Vs| 0 3 1 ∞ ∞ ∞ V1| 3 0 2 4 ∞ 1 V2| ∞ 2 0 3 7 ∞ V3| ∞ 4 3 0 3 6 V4| ∞ ∞ 7 6 0 1 Vt| ∞ ∞ ∞ ∞ ∞ 0 已访问节点集合S:{Vs, V2, V1, V3} ``` - 第五轮迭代,选择距离起点Vs最近的节点V4,将V4标记为已访问,更新距离矩阵中Vt的距离。 ``` 距离矩阵D5: | Vs V1 V2 V3 V4 Vt --|------------------ Vs| 0 3 1 ∞ ∞ ∞ V1| 3 0 2 4 ∞ 1 V2| ∞ 2 0 3 7 ∞ V3| ∞ 4 3 0 3 6 V4| ∞ ∞ 7 6 0 1 Vt| ∞ ∞ ∞ 10 1 0 已访问节点集合S:{Vs, V2, V1, V3, V4} ``` 3. 根据距离矩阵D5可以得到从起点Vs到终点Vt的最短路径为:Vs → V2 → V3V4 → Vt,总距离为8。 希望这次回答能够帮助您完成课后作业。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值