Setting d3.curveBundle.beta seems to have no effect

隐身守侯 提交于 2020-01-02 08:12:43

问题


The d3 documentation on d3.curveBundle() provides an example of how to set beta:

var line = d3.line().curve(d3.curveBundle.beta(0.5));

However, the value of beta supplied seems to have no effect on the curve produced. Here is a minimal example, using beta = 0.0 which should produce a straight line between the two end points:

// create a 300x300 svg element
var w = 300;
var h = 300;
var svg = d3.select("body")
  .append("svg")
  .attr("width", w)
  .attr("height", h);

// create a line generator
var rl = d3.line()
  .x(function(d) {
    return d.x;
  })
  .y(function(d) {
    return d.y;
  })
  .curve(d3.curveBundle.beta(0.0));

// three points used to generate the path
var line_data = [{
  x: 0,
  y: -100
}, {
  x: 100,
  y: 0
}, {
  x: 0,
  y: 100
}];

// path generated from line_data
svg.append("path")
  .attr("d", rl(line_data))
  .style("fill", "none")
  .style("stroke", "red")
  .style("stroke-width", "2px")
  .attr("transform", "translate(" + (w / 2) + "," + (h / 2) + ")");

// three circles corresponding to the points in line_data
svg.selectAll("circle")
  .data(line_data)
  .enter()
  .append("circle")
  .attr("cx", function(d) {
    return d.x;
  })
  .attr("cy", function(d) {
    return d.y;
  })
  .attr("r", 2)
  .style("fill", "black")
  .attr("transform", "translate(" + (w / 2) + "," + (h / 2) + ")");
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.7.1/d3.min.js"></script>

This code produces the same result regardless of the value of beta supplied. What am I missing?


回答1:


Problem

It appears that d3.min.js is broken in relation to this functionality. This problem is not present in regular un-minified d3.js (both v4.7.1 - the version in the question). So, you were doing it right, weren't missing anything, just seems to have been an error introduced through the minification process.

Update And Resolution

This was confirmed by Altocumulus and Gerardo Furtado (see comments below). Altocumulus dug into it and found the actual discrepancy between the minified and non-minified d3.js, flagging the issue on github. Mike Bostock quickly sourced the error to the version of uglify-js used:

This is an excessively aggressive optimization by UglifyJS that was introduced in a recent release and seems like a bad default. I will see about disabling it or downgrading UglifyJS.

Mike has since tediously updated all modules and put out a new release today (release notes). For the record, that was only 7 hours from Altocumulus's flagging the issue to a new release.

Demonstration:

The following three snippets should have identical code (based on the above code) and only differ in relation to the d3 script source. The first one is 4.7.1 un-minified, the second 4.7.1 minified, and the third 4.7.2 minified.

D3.js non-minified v4.7.1:

// create a 300x300 svg element
            var w = 300;
            var h = 300;
            var svg = d3.select("body")
                .append("svg")
                .attr("width", w)
                .attr("height", h);

            // create a line generator
            var rl = d3.line()
                .x(function(d) {return d.x;})
                .y(function(d) {return d.y;})
                .curve(d3.curveBundle.beta(0.0));

            // three points used to generate the path
            var line_data = [{x:0,y:-100},{x:100,y:0},{x:0,y:100}];

            // path generated from line_data
            svg.append("path")
                .attr("d",rl(line_data))
                .style("fill", "none")
                .style("stroke", "red")
                .style("stroke-width", "2px")
                .attr("transform", "translate(" + (w/2) + "," + (h/2) + ")");

            // three circles corresponding to the points in line_data
            svg.selectAll("circle")
                .data(line_data)
                .enter()
                .append("circle")
                .attr("cx", function(d) {return d.x;})
                .attr("cy", function(d) {return d.y;})
                .attr("r",2)
                .style("fill","black")
                .attr("transform", "translate(" + (w/2) + "," + (h/2) + ")");
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.7.1/d3.js"></script>

And d3.js minified v4.7.1:

// create a 300x300 svg element
            var w = 300;
            var h = 300;
            var svg = d3.select("body")
                .append("svg")
                .attr("width", w)
                .attr("height", h);

            // create a line generator
            var rl = d3.line()
                .x(function(d) {return d.x;})
                .y(function(d) {return d.y;})
                .curve(d3.curveBundle.beta(0.0));

            // three points used to generate the path
            var line_data = [{x:0,y:-100},{x:100,y:0},{x:0,y:100}];

            // path generated from line_data
            svg.append("path")
                .attr("d",rl(line_data))
                .style("fill", "none")
                .style("stroke", "red")
                .style("stroke-width", "2px")
                .attr("transform", "translate(" + (w/2) + "," + (h/2) + ")");

            // three circles corresponding to the points in line_data
            svg.selectAll("circle")
                .data(line_data)
                .enter()
                .append("circle")
                .attr("cx", function(d) {return d.x;})
                .attr("cy", function(d) {return d.y;})
                .attr("r",2)
                .style("fill","black")
                .attr("transform", "translate(" + (w/2) + "," + (h/2) + ")");
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.7.1/d3.min.js"></script>

Updated (minified) 4.7.2:

// create a 300x300 svg element
            var w = 300;
            var h = 300;
            var svg = d3.select("body")
                .append("svg")
                .attr("width", w)
                .attr("height", h);

            // create a line generator
            var rl = d3.line()
                .x(function(d) {return d.x;})
                .y(function(d) {return d.y;})
                .curve(d3.curveBundle.beta(0.0));

            // three points used to generate the path
            var line_data = [{x:0,y:-100},{x:100,y:0},{x:0,y:100}];

            // path generated from line_data
            svg.append("path")
                .attr("d",rl(line_data))
                .style("fill", "none")
                .style("stroke", "red")
                .style("stroke-width", "2px")
                .attr("transform", "translate(" + (w/2) + "," + (h/2) + ")");

            // three circles corresponding to the points in line_data
            svg.selectAll("circle")
                .data(line_data)
                .enter()
                .append("circle")
                .attr("cx", function(d) {return d.x;})
                .attr("cy", function(d) {return d.y;})
                .attr("r",2)
                .style("fill","black")
                .attr("transform", "translate(" + (w/2) + "," + (h/2) + ")");
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.7.2/d3.min.js"></script>


来源:https://stackoverflow.com/questions/42651448/setting-d3-curvebundle-beta-seems-to-have-no-effect

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!