D3 (v5) 中的 SVG 路径转换无法正常工作

SVG path transition in D3 (v5) not working properly

使用 D3 v5.

根据 JSON 数据绘制我的签名

我无法在 v5 中为其设置动画,但在 v3 中可以正常工作。

const data = [{"azimuth":2.2814462,"elevation":0.60907805,"pressure":0.010744811,"time":82598635,"x":114.150024,"y":236.93994},{"azimuth":2.2987978,"elevation":0.5964333,"pressure":0.015628817,"time":82598670,"x":102.77983,"y":273.95093},{"azimuth":2.2987978,"elevation":0.5964333,"pressure":0.01855922,"time":82598686,"x":101.0706,"y":288.2202},{"azimuth":2.3361268,"elevation":0.5718097,"pressure":0.08815629,"time":82598703,"x":101.21922,"y":298.5506},{"azimuth":2.3150961,"elevation":0.56043386,"pressure":0.14188035,"time":82598719,"x":105.30655,"y":302.34082},{"azimuth":2.3150961,"elevation":0.56043386,"pressure":0.18046398,"time":82598736,"x":112.81235,"y":300.5572},{"azimuth":2.3150961,"elevation":0.56043386,"pressure":0.20927963,"time":82598752,"x":122.9935,"y":292.15912},{"azimuth":2.3150961,"elevation":0.56043386,"pressure":0.23418805,"time":82598769,"x":134.43799,"y":276.998},{"azimuth":2.3150961,"elevation":0.56043386,"pressure":0.2781441,"time":82598786,"x":146.55132,"y":257.6007},{"azimuth":2.3150961,"elevation":0.56043386,"pressure":0.31697193,"time":82598802,"x":160.15094,"y":238.57495},{"azimuth":2.3150961,"elevation":0.56043386,"pressure":0.34432235,"time":82598819,"x":174.04784,"y":220.73834},{"azimuth":2.3150961,"elevation":0.56043386,"pressure":0.35457876,"time":82598833,"x":184.30328,"y":207.58386},{"azimuth":2.3150961,"elevation":0.56043386,"pressure":0.35018316,"time":82598850,"x":198.05154,"y":188.18652},{"azimuth":2.3150961,"elevation":0.56043386,"pressure":0.30720392,"time":82598866,"x":212.17139,"y":167.52576},{"azimuth":2.3361268,"elevation":0.5718097,"pressure":0.2923077,"time":82598883,"x":224.95355,"y":148.87164},{"azimuth":2.3361268,"elevation":0.5718097,"pressure":0.31770453,"time":82598901,"x":233.79703,"y":133.78485},{"azimuth":2.3361268,"elevation":0.5718097,"pressure":0.34603176,"time":82598916,"x":241.74872,"y":121.076294},{"azimuth":2.3561945,"elevation":0.5598605,"pressure":0.36849818,"time":82598933,"x":250.07199,"y":110.002686},{"azimuth":2.3561945,"elevation":0.5598605,"pressure":0.3753358,"time":82598950,"x":257.50348,"y":99.4494},{"azimuth":2.3762622,"elevation":0.5718097,"pressure":0.3760684,"time":82598966,"x":263.30005,"y":90.82837},{"azimuth":2.3762622,"elevation":0.5718097,"pressure":0.37826622,"time":82598983,"x":268.05618,"y":83.99097},{"azimuth":2.3762622,"elevation":0.5718097,"pressure":0.39902323,"time":82598999,"x":271.47467,"y":79.08594},{"azimuth":2.3762622,"elevation":0.5718097,"pressure":0.41416365,"time":82599016,"x":272.88666,"y":77.45087},{"azimuth":2.3762622,"elevation":0.5718097,"pressure":0.41538465,"time":82599033,"x":273.33255,"y":78.862976},{"azimuth":2.3762622,"elevation":0.5718097,"pressure":0.42442006,"time":82599049,"x":272.36646,"y":86.14624},{"azimuth":2.3762622,"elevation":0.5718097,"pressure":0.42881566,"time":82599066,"x":269.39386,"y":102.42212},{"azimuth":2.3762622,"elevation":0.5718097,"pressure":0.42344326,"time":82599083,"x":263.89456,"y":127.09613},{"azimuth":2.3972929,"elevation":0.56043386,"pressure":0.38290602,"time":82599099,"x":257.2062,"y":157.71564},{"azimuth":2.3972929,"elevation":0.56043386,"pressure":0.33064714,"time":82599116,"x":249.47748,"y":191.38226},{"azimuth":2.3972929,"elevation":0.56043386,"pressure":0.26153848,"time":82599133,"x":240.85693,"y":223.33954},{"azimuth":2.37726,"elevation":0.54817456,"pressure":0.25958487,"time":82599149,"x":233.05386,"y":248.16211},{"azimuth":2.37726,"elevation":0.54817456,"pressure":0.26813188,"time":82599166,"x":228.44635,"y":265.0326},{"azimuth":2.37726,"elevation":0.54817456,"pressure":0.22954825,"time":82599182,"x":227.33163,"y":274.1739},{"azimuth":2.3561945,"elevation":0.53617316,"pressure":0.008791209,"time":82599199,"x":230.45285,"y":275.28864},{"azimuth":2.3561945,"elevation":0.53617316,"pressure":0.008791209,"time":82599201,"x":230.45285,"y":275.28864},{"azimuth":2.419329,"elevation":0.54934233,"pressure":0.00024420026,"time":82599293,"x":307.36877,"y":146.19617},{"azimuth":2.419329,"elevation":0.54934233,"pressure":0.00024420026,"time":82599298,"x":309.89548,"y":140.69653},{"azimuth":2.419329,"elevation":0.54934233,"pressure":0.00024420026,"time":82599301,"x":313.01672,"y":133.71051},{"azimuth":2.419329,"elevation":0.54934233,"pressure":0.00024420026,"time":82599305,"x":313.01672,"y":133.71051},{"azimuth":2.5846002,"elevation":0.56541383,"pressure":0.3758242,"time":82599397,"x":357.38272,"y":17.103668},{"azimuth":2.5846002,"elevation":0.56541383,"pressure":0.5594628,"time":82599414,"x":358.20016,"y":8.928558},{"azimuth":2.5846002,"elevation":0.56541383,"pressure":0.5968254,"time":82599430,"x":358.34882,"y":6.6246643},{"azimuth":2.5989227,"elevation":0.5801088,"pressure":0.6,"time":82599445,"x":357.38272,"y":10.117676},{"azimuth":2.5989227,"elevation":0.5801088,"pressure":0.6,"time":82599447,"x":356.49094,"y":12.49588},{"azimuth":2.5846002,"elevation":0.56541383,"pressure":0.5973138,"time":82599463,"x":353.14676,"y":23.86673},{"azimuth":2.5846002,"elevation":0.56541383,"pressure":0.603663,"time":82599478,"x":345.71527,"y":48.4664},{"azimuth":2.5846002,"elevation":0.56541383,"pressure":0.5821734,"time":82599495,"x":334.64233,"y":80.572266},{"azimuth":2.5846002,"elevation":0.56541383,"pressure":0.5653236,"time":82599511,"x":320.22525,"y":115.94824},{"azimuth":2.5846002,"elevation":0.56541383,"pressure":0.56337,"time":82599528,"x":303.20715,"y":150.72961},{"azimuth":2.5694442,"elevation":0.5508617,"pressure":0.5550672,"time":82599544,"x":286.26334,"y":184.47058},{"azimuth":2.5439591,"elevation":0.5597318,"pressure":0.5648352,"time":82599561,"x":273.55548,"y":213.82666},{"azimuth":2.5439591,"elevation":0.5597318,"pressure":0.5748474,"time":82599578,"x":264.48907,"y":237.46014},{"azimuth":2.5275717,"elevation":0.5456233,"pressure":0.5770452,"time":82599594,"x":258.98978,"y":254.10767},{"azimuth":2.5275717,"elevation":0.5456233,"pressure":0.5538462,"time":82599611,"x":256.98328,"y":263.026},{"azimuth":2.4918826,"elevation":0.51795524,"pressure":0.23418805,"time":82599629,"x":259.1384,"y":263.39758},{"azimuth":2.4918826,"elevation":0.51795524,"pressure":0.052991457,"time":82599630,"x":260.40176,"y":261.9112},{"azimuth":2.4918826,"elevation":0.51795524,"pressure":0.052991457,"time":82599634,"x":260.40176,"y":261.9112},{"azimuth":2.4918826,"elevation":0.51795524,"pressure":0.20757023,"time":82599688,"x":287.0808,"y":183.87604},{"azimuth":2.4918826,"elevation":0.51795524,"pressure":0.2930403,"time":82599695,"x":288.4928,"y":178.82233},{"azimuth":2.4918826,"elevation":0.51795524,"pressure":0.45225888,"time":82599711,"x":296.9647,"y":151.10126},{"azimuth":2.4918826,"elevation":0.51795524,"pressure":0.4708181,"time":82599727,"x":305.28796,"y":125.23816},{"azimuth":2.4918826,"elevation":0.51795524,"pressure":0.44053727,"time":82599744,"x":314.35437,"y":99.67236},{"azimuth":2.5275717,"elevation":0.5456233,"pressure":0.39047623,"time":82599761,"x":324.75845,"y":76.33612},{"azimuth":2.5275717,"elevation":0.5456233,"pressure":0.43003666,"time":82599777,"x":336.72318,"y":60.952026},{"azimuth":2.5275717,"elevation":0.5456233,"pressure":0.50183153,"time":82599794,"x":352.77518,"y":50.547333},{"azimuth":2.5275717,"elevation":0.5456233,"pressure":0.52527475,"time":82599810,"x":370.2392,"y":47.500244},{"azimuth":2.5275717,"elevation":0.5456233,"pressure":0.52234435,"time":82599827,"x":383.7645,"y":55.601044},{"azimuth":2.5275717,"elevation":0.5456233,"pressure":0.50622714,"time":82599843,"x":390.15558,"y":76.03882},{"azimuth":2.5533938,"elevation":0.5364645,"pressure":0.40415144,"time":82599860,"x":387.48026,"y":104.20581},{"azimuth":2.5275717,"elevation":0.5456233,"pressure":0.3770452,"time":82599876,"x":378.56247,"y":127.31909},{"azimuth":2.4918826,"elevation":0.51795524,"pressure":0.44688648,"time":82599893,"x":364.51694,"y":143.74365},{"azimuth":2.4918826,"elevation":0.51795524,"pressure":0.50695974,"time":82599909,"x":346.30978,"y":153.33081},{"azimuth":2.4918826,"elevation":0.51795524,"pressure":0.5470086,"time":82599926,"x":329.14304,"y":154.29694},{"azimuth":2.4918826,"elevation":0.51795524,"pressure":0.5870574,"time":82599943,"x":319.25916,"y":146.49347},{"azimuth":2.4918826,"elevation":0.51795524,"pressure":0.6021978,"time":82599959,"x":321.56293,"y":134.15643},{"azimuth":2.4918826,"elevation":0.51795524,"pressure":0.602442,"time":82599976,"x":335.16257,"y":122.934265},{"azimuth":2.4918826,"elevation":0.51795524,"pressure":0.61514044,"time":82599992,"x":355.15326,"y":116.91437},{"azimuth":2.4918826,"elevation":0.51795524,"pressure":0.61978024,"time":82600009,"x":374.7724,"y":116.76575},{"azimuth":2.4918826,"elevation":0.51795524,"pressure":0.61733824,"time":82600025,"x":388.44635,"y":126.352905},{"azimuth":2.4918826,"elevation":0.51795524,"pressure":0.5763126,"time":82600042,"x":394.16858,"y":147.23663},{"azimuth":2.518345,"elevation":0.5081876,"pressure":0.2808303,"time":82600058,"x":390.67578,"y":174.80908},{"azimuth":2.4992008,"elevation":0.49433747,"pressure":0.06593407,"time":82600073,"x":383.2443,"y":196.65894},{"azimuth":2.4992008,"elevation":0.49433747,"pressure":0.024420027,"time":82600089,"x":368.1584,"y":222.07611},{"azimuth":2.4992008,"elevation":0.49433747,"pressure":0.14945056,"time":82600108,"x":347.57315,"y":240.5816},{"azimuth":2.4518456,"elevation":0.49112195,"pressure":0.37851042,"time":82600123,"x":324.23825,"y":251.65515},{"azimuth":2.4518456,"elevation":0.49112195,"pressure":0.42979246,"time":82600139,"x":299.41708,"y":253.8847},{"azimuth":2.4518456,"elevation":0.49112195,"pressure":0.44200248,"time":82600156,"x":277.71713,"y":243.55432},{"azimuth":2.4518456,"elevation":0.49112195,"pressure":0.4703297,"time":82600173,"x":265.30655,"y":222.67065},{"azimuth":2.4518456,"elevation":0.49112195,"pressure":0.4683761,"time":82600190,"x":266.124,"y":202.23285},{"azimuth":2.4518456,"elevation":0.49112195,"pressure":0.51746035,"time":82600206,"x":275.63632,"y":188.78107},{"azimuth":2.4518456,"elevation":0.49112195,"pressure":0.53235656,"time":82600222,"x":290.425,"y":180.60596},{"azimuth":2.4518456,"elevation":0.49112195,"pressure":0.34017095,"time":82600239,"x":305.065,"y":182.46393},{"azimuth":2.4518456,"elevation":0.49112195,"pressure":0.117460325,"time":82600241,"x":307.29446,"y":185.06512},{"azimuth":2.4518456,"elevation":0.49112195,"pressure":0.117460325,"time":82600245,"x":307.29446,"y":185.06512},{"azimuth":2.2733335,"elevation":0.4301798,"pressure":0.37191698,"time":82600316,"x":323.4208,"y":241.54773},{"azimuth":2.2733335,"elevation":0.4301798,"pressure":0.4664225,"time":82600322,"x":325.57593,"y":242.43958},{"azimuth":2.2733335,"elevation":0.4301798,"pressure":0.50622714,"time":82600339,"x":338.8783,"y":243.25708},{"azimuth":2.2733335,"elevation":0.4301798,"pressure":0.50012213,"time":82600356,"x":356.71387,"y":235.82513},{"azimuth":2.2733335,"elevation":0.4301798,"pressure":0.50183153,"time":82600372,"x":375.96143,"y":218.95471},{"azimuth":2.302525,"elevation":0.44128427,"pressure":0.52332115,"time":82600389,"x":393.94565,"y":194.94958},{"azimuth":2.3285234,"elevation":0.42871678,"pressure":0.5772894,"time":82600405,"x":407.1737,"y":179.56549},{"azimuth":2.3285234,"elevation":0.42871678,"pressure":0.61733824,"time":82600422,"x":412.45004,"y":176.51843},{"azimuth":2.3285234,"elevation":0.42871678,"pressure":0.62661785,"time":82600438,"x":410.2206,"y":182.61261},{"azimuth":2.3561945,"elevation":0.44057047,"pressure":0.5550672,"time":82600455,"x":402.56616,"y":198.81415},{"azimuth":2.3561945,"elevation":0.44057047,"pressure":0.07545788,"time":82600471,"x":395.65488,"y":213.23212},{"azimuth":2.3285234,"elevation":0.42871678,"pressure":0.008547009,"time":82600474,"x":394.68878,"y":215.75897},{"azimuth":2.3285234,"elevation":0.42871678,"pressure":0.008547009,"time":82600478,"x":394.68878,"y":215.75897},{"azimuth":2.2000399,"elevation":0.38531247,"pressure":0.011721613,"time":82600495,"x":394.01996,"y":220.58972},{"azimuth":2.2000399,"elevation":0.38531247,"pressure":0.37142858,"time":82600521,"x":414.01068,"y":208.84729},{"azimuth":2.235008,"elevation":0.3954947,"pressure":0.48864472,"time":82600538,"x":432.21783,"y":191.1593},{"azimuth":2.2620504,"elevation":0.38206026,"pressure":0.54188037,"time":82600554,"x":452.13422,"y":168.56622},{"azimuth":2.2620504,"elevation":0.38206026,"pressure":0.5848596,"time":82600571,"x":469.67255,"y":150.13507},{"azimuth":2.3267417,"elevation":0.40460202,"pressure":0.6056166,"time":82600587,"x":481.4143,"y":138.3183},{"azimuth":2.3267417,"elevation":0.40460202,"pressure":0.62197804,"time":82600604,"x":486.69067,"y":134.3794},{"azimuth":2.3267417,"elevation":0.40460202,"pressure":0.63589746,"time":82600620,"x":485.20435,"y":138.98718},{"azimuth":2.3856473,"elevation":0.40460202,"pressure":0.64468867,"time":82600637,"x":475.9893,"y":158.68182},{"azimuth":2.3856473,"elevation":0.40460202,"pressure":0.64273506,"time":82600653,"x":462.0181,"y":190.49042},{"azimuth":2.3856473,"elevation":0.40460202,"pressure":0.64102566,"time":82600670,"x":446.4863,"y":226.90686},{"azimuth":2.3856473,"elevation":0.40460202,"pressure":0.63638586,"time":82600686,"x":430.80585,"y":260.87073},{"azimuth":2.3856473,"elevation":0.40460202,"pressure":0.63687426,"time":82600703,"x":418.98978,"y":284.20697},{"azimuth":2.3561945,"elevation":0.3923213,"pressure":0.63711846,"time":82600717,"x":401.82303,"y":310.44165},{"azimuth":2.3561945,"elevation":0.3923213,"pressure":0.6537241,"time":82600734,"x":382.94705,"y":329.5417},{"azimuth":2.3267417,"elevation":0.40460202,"pressure":0.6908425,"time":82600751,"x":364.59125,"y":339.57477},{"azimuth":2.3267417,"elevation":0.40460202,"pressure":0.71452993,"time":82600767,"x":348.16766,"y":338.60864},{"azimuth":2.3267417,"elevation":0.40460202,"pressure":0.71575093,"time":82600784,"x":339.54712,"y":327.758},{"azimuth":2.2620504,"elevation":0.38206026,"pressure":0.7030525,"time":82600801,"x":342.4454,"y":308.13776},{"azimuth":2.2620504,"elevation":0.38206026,"pressure":0.7052503,"time":82600817,"x":362.58475,"y":281.15985},{"azimuth":2.2620504,"elevation":0.38206026,"pressure":0.63589746,"time":82600834,"x":404.49835,"y":247.27032},{"azimuth":2.3267417,"elevation":0.40460202,"pressure":0.20708182,"time":82600844,"x":452.5058,"y":215.23871},{"azimuth":2.3267417,"elevation":0.40460202,"pressure":0.20708182,"time":82600849,"x":452.5058,"y":215.23871}];
  
const padding = 10;

const maxX = d3.max(data, (d) => d.x);
const maxY = d3.max(data, (d) => d.y);

const x = d3.scaleLinear().domain([0, maxX]).range([padding, (600 - padding)]);
const y = d3.scaleLinear().domain([0, maxY]).range([padding, (600 - padding)]);

// Line generator
const line = d3
    .line()
    .x(function(d) {
        return x(d.x);
    })
    .y(function(d) {
        return y(d.y);
    })
    .curve(d3.curveCardinal);

// SVG container
const svg = d3.select('svg');

// Find the length of the line at each given point. (Draw hidden line with portion of the points and then remove.)
const lengthAt = [];

for (let i = 1; i < data.length - 1; i++) {
    let path = svg
        .append('path')
        .attr('d', line(data.slice(i)))
        .attr('class', 'temp')
        .attr('visibility', 'hidden');
      
    lengthAt.push(path.node().getTotalLength());
}

svg.selectAll('.temp').remove();

// Add the path
let path = svg
    .append('path')
    .attr('d', () => line(data))
    .attr('stroke', 'steelblue')
    .attr('stroke-width', 2)
    .attr('fill', 'none');

const totalLength = path.node().getTotalLength();

path.attr({ 'stroke-dasharray': totalLength + ' ' + totalLength, 'stroke-dashoffset': totalLength });

// Transition will be chained from either the original path or the last transition.
let transitionFrom = path;
  
// Start at 1 since no transition needed to first point.
for (let i = 1; i < data.length; i++) {
    transitionFrom = transitionFrom
        .transition()
        .duration(data[i].time - data[i - 1].time)
        .ease(d3.easeLinear)
        .attr('stroke-dashoffset', lengthAt[i - 1] || 0);
}
<script src="https://d3js.org/d3.v5.min.js"></script>

<div id="signature">
    <svg width="600" height="600"></svg>
</div>

如果你想要fiddle:

v3(工作):https://jsfiddle.net/m9xhgt5a/

v5(不工作):https://jsfiddle.net/x0orptsh/


相同的数据,相同的代码,相同的形状。

无法弄清楚确切的问题是什么。

您只是忘记拆分笔画属性设置器。

只需更换

path.attr({ 'stroke-dasharray': totalLength + ' ' + totalLength, 'stroke-dashoffset': totalLength });

   path
     .attr('stroke-dasharray', totalLength + ' ' + totalLength)
     .attr('stroke-dashoffset', totalLength);

编辑:运行 fiddle