2017-03-16 73 views
2

試圖實現this widget found in Codepen當我遇到一些麻煩加載在以下DIV:複製一個D3.js計部件

<div id="action"></div> 

的事情是我想用兩個以上的人在同一個頁面,但是當我複製的代碼,它發生what you can see in this snippet實施分爲兩個不同的div:

<div id="action"></div> 
<div id="action2"></div> 

正如你所看到的,第二配件將無法正常工作,並且像我一樣,你可能會認爲這是有關的變量彼此重疊,如果您切換它的工作的div的順序!那麼它是沒有意義的,如果變量重疊,那麼它會一直這樣做,不管哪個小部件先行。

所以,也許你在想:如果你已經找到了解決方案,那麼有什麼問題?那麼,我需要知道問題出在哪裏,因爲它們中的每一個都會代表從數據庫中取得的一些數據,並且可以單獨修改和更新它們以將新配置的數據保存回數據庫,所以當我刷新其中一個錯誤的順序,其中一個小部件將無法工作,所以現在我必須以正確的順序刷新它們,直到我找到正在發生的事情,而事實上它們會在同一頁面上超過兩個,所以它將無效刷新所有這些以避免崩潰。

試圖解決這個問題,我認爲這不是關於定義在函數中的內部d3.js變量(var t,e,n,r,a,l,s,i,u,o,c ,d,g ...),因爲它們在本地範圍內是沒有意義的。

的代碼是難以閱讀的原因,而是精縮,我用了一個unminifier讀它更清晰,但無論如何,我對D3.js沒有太多的想法......

任何想法?提前致謝。

回答

1

問題是,在render函數中這個pattern跟在pattern之後,量表代碼做得很好,但在update函數中丟失了它。它開始做全球d3.select,它只更新第一個它選擇的元素的實例。所以修復功能本身就在更新功能中,保留對您正在操作的svg元素的引用,並對其進行進一步選擇。

此外,您只需要定義一次guage函數,並且您應該爲每個量表的實例使用不同的變量。

請參見下面的評論我如何改變guage功能:

var gauge = function() { 
 
    // added "svg" 
 
    var svg, t, e, n, r, a, l, s, i, u, o, c, d, g, p, f, h, m, v, y, x, A, M, _, R, b, I, P, w, T = {}, 
 
     C = 120, 
 
     k = d3.scale.linear().domain([0, C]).range([Math.PI, 2 * Math.PI]), 
 
     z = ["rgb(235,7,27)", "rgb(242,166,0)", "rgb(139,224,91)"], 
 
     W = 0, 
 
     B = 50, 
 
     E = !0, 
 
     G = 100, 
 
     H = 1.57, 
 
     L = 10, 
 
     j = !0, 
 
     q = !0, 
 
     D = 0, 
 
     F = "elastic", 
 
     J = 1e3, 
 
     K = function(t, e) { 
 
      var n = e ? e : 0; 
 
      return g = 0 + (R - n) * Math.cos(t) 
 
     }, 
 
     N = function(t, e) { 
 
      var n = e ? e : 0; 
 
      return p = 0 + (R - n) * Math.sin(t) 
 
     }, 
 
     O = function() { 
 
      return f = 0 + ((A - x)/2 + x) * Math.cos(k(B)) 
 
     }, 
 
     Q = function() { 
 
      return h = 0 + ((A - x)/2 + x) * Math.sin(k(B)) 
 
     }, 
 
     S = function(t, e) { 
 
      e.attr("points", "" + K(P(t), 2 * L) + "," + N(P(t), 2 * L) + " " + K(I(t)) + "," + N(I(t)) + " " + K(w(t), 2 * L) + "," + N(w(t), 2 * L) + " ") 
 
     }; 
 
    return T.render = function(n) { 
 
     var i = d3.scale.linear().domain([0, C]).range([-H, H]); 
 
     r = k(D), a = k(D - L/2), l = k(D + L/2), s = d3.select("#" + _target.id).append("svg").attr("class", "pie").attr("height", e).attr("width", t), m = d3.select("#" + _target.id).append("div").attr("transform", "translate(" + M + "," + _ + ")").attr("class", "gaugeTT"), v = m.append("div").attr("class", "col1"), y = m.append("div").attr("class", "col2"); 
 
     var u = [{ 
 
       startAngle: -H, 
 
       endAngle: H 
 
      }], 
 
      f = [{ 
 
       startAngle: -H, 
 
       endAngle: 0 
 
      }], 
 
      h = [{ 
 
       startAngle: -H, 
 
       endAngle: i(B) 
 
      }]; 
 
     [{ 
 
      startAngle: i(G) - .03, 
 
      endAngle: i(G) 
 
     }]; 
 
     d = A - x; 
 
     var I = d3.svg.arc().outerRadius(A).innerRadius(x); 
 
     d3.svg.arc().outerRadius(A - 1).innerRadius(x + 1); 
 
     o = d3.svg.arc().outerRadius(x + .3 * d).innerRadius(x), c = d3.svg.arc().outerRadius(A).innerRadius(A - .7 * d); 
 
     var P = d3.svg.arc().outerRadius(A + 5).innerRadius(A - .7 * d), 
 
      w = s.append("g"); 
 
      svg = w; 
 
     w.attr("transform", "translate(" + M + "," + _ + ")").selectAll("path.bg").data(u).enter().append("path").attr("class", "bg").attr("fill", "rgb(236,229,240)").attr("d", function(t, e) { 
 
      return I(t, e) 
 
     }), w.attr("transform", "translate(" + M + "," + _ + ")").selectAll("path.average").data(h).enter().append("path").attr("class", "average").attr("fill", "rgb(74,0,98)").attr("d", function(t, e) { 
 
      return o(t, e) 
 
     }), w.attr("transform", "translate(" + M + "," + _ + ")").selectAll("path.actual").data(f).enter().append("path").attr("class", "actual").attr("d", function(t, e) { 
 
      return c(t, e) 
 
     }), w.append("line").attr("class", "needle-line").attr("x1", 0).attr("y1", 0).attr("x2", function() { 
 
      return g = 0 + R * Math.cos(r) 
 
     }).attr("y2", function() { 
 
      return p = 0 + R * Math.sin(r) 
 
     }), q === !0 && w.append("polygon").attr("class", "needleTip").attr("fill", b), j === !0 && (w.append("circle").attr("cx", 0).attr("cy", 0).attr("r", 45), w.select(".needle-line").style("stroke", b).style("stroke-width", 1), w.select("circle").style("fill", b)), w.append("line").attr("class", "goal-post").attr("x1", function() { 
 
      var t = 0 + x * Math.cos(k(G)); 
 
      return t 
 
     }).attr("y1", function() { 
 
      var t = 0 + x * Math.sin(k(G)); 
 
      return t 
 
     }).attr("x2", function() { 
 
      var t = 0 + (A + 10) * Math.cos(k(G)); 
 
      return t 
 
     }).attr("y2", function() { 
 
      var t = 0 + (A + 10) * Math.sin(k(G)); 
 
      return t 
 
     }).style("stroke", "rgb(82,174,201)").style("stroke-width", 5), E === !1 && w.append("circle").attr("class", "average").attr("cx", function() { 
 
      return O(B) 
 
     }).attr("cy", function() { 
 
      return Q(B) 
 
     }).attr("r", 8).style("opacity", .75).style("fill", "rgb(250,250,250)"), w.append("text").attr("class", "centerPercentage").style("fill", "#555").style("font-size", "26").attr("text-anchor", "middle").attr("x", 0).attr("y", 0).attr("dy", ".35em").text("0%"), w.append("text").attr("class", "min-range").style("fill", "#555").style("font-size", "18").attr("text-anchor", "middle").attr("x", -65).attr("y", 75).attr("dy", ".35em").text("0"), w.append("text").attr("class", "max-range").style("fill", "#555").style("font-size", "18").attr("text-anchor", "middle").attr("x", 65).attr("y", 75).attr("dy", ".35em").text(C), w.select(".actual").on("mouseover", function() { 
 
      d3.select(this).transition().duration(400).ease(F).attr("d", function(t) { 
 
       return P(t) 
 
      }), m.transition().style("opacity", "1"), w.on("mousemove", function(t) { 
 
       var e = d3.mouse(this), 
 
        n = e[0] + 200 + "px", 
 
        r = e[1] + 200 + "px"; 
 
       console.log(e), m.style("top", r), m.style("left", n) 
 
      }) 
 
     }), w.select(".actual").on("mouseout", function() { 
 
      d3.select(this).transition().duration(400).ease(F).attr("d", function(t) { 
 
       return c(t) 
 
      }), m.transition().style("opacity", "0"), w.on("mousemove", null) 
 
     }) 
 
    }, T.update = function(t) { 
 
     u = W, W = t, v.html("<p>Acutal " + W + "</p><p>Goal " + G + "</p><p>Average " + B + "</p>"); 
 
     var e = d3.scale.linear().domain([0, 1]).range([u, t]), 
 
      n = d3.scale.linear().domain([0, 60, 120]).range(z), 
 
      s = d3.scale.linear().domain([0, C]).range([-H, H]), 
 
      i = [{ 
 
       startAngle: -H, 
 
       endAngle: s(t) 
 
      }]; 
 
     d3.svg.arc().outerRadius(A).innerRadius(x); 
 
     // selection on svg 
 
     svg.selectAll("path.actual").data(i).transition().ease(F).duration(J).attrTween("d", function(t) { 
 
      var r = this.__current__; 
 
      r || (r = { 
 
       startAngle: -H, 
 
       endAngle: -H 
 
      }); 
 
      var a = d3.interpolate(r, t); 
 
      return this.__current__ = a(1), 
 
       function(t) { 
 
        return svg.attr("fill", function(r) { 
 
         return n(e(t)) 
 
        }), c(a(t)) 
 
       } 
 
     }); 
 
     var o = r, 
 
      d = a, 
 
      g = l; 
 
     r = k(t), _angleC = k(B), a = k(t - L/2), l = k(t + L/2), I = d3.interpolate(o, r), _interpolateC = d3.interpolate(o, _angleC), P = d3.interpolate(d, a), w = d3.interpolate(g, l); 
 
     // selections based on svg 
 
     var p = svg.select(".centerPercentage"), 
 
      f = svg.select("polygon"); 
 
     svg.select(".needle-line").transition().ease(F).duration(J).attrTween("x2", function() { 
 
      return function(t) { 
 
       return q === !0 && (S(t, f), p.text(parseInt(e(t)) + "%")), K(I(t)) 
 
      } 
 
     }).attrTween("y2", function() { 
 
      return function(t) { 
 
       return N(I(t)) 
 
      } 
 
     }) 
 
    }, T.width = function(e) { 
 
     return arguments.length ? (t = e, T) : t 
 
    }, T.height = function(t) { 
 
     return arguments.length ? (e = t, T) : e 
 
    }, T.needleWidth = function(t) { 
 
     return arguments.length ? (L = t/2, T) : L 
 
    }, T.spread = function(t) { 
 
     return arguments.length ? (t < Math.PI/2 && (t = Math.PI/2), n = t - Math.PI/2, H = t, k = d3.scale.linear().domain([0, C]).range([Math.PI - n, 2 * Math.PI + n]), T) : H 
 
    }, T.colors = function(t) { 
 
     return arguments.length ? (i = t, T) : i 
 
    }, T.needleColor = function(t) { 
 
     return arguments.length ? (b = t, T) : b 
 
    }, T.needleTip = function(t) { 
 
     return arguments.length ? (q = t, T) : q 
 
    }, T.target = function(n) { 
 
     return arguments.length ? (_target = document.getElementById(n), t = _target.offsetWidth, e = _target.offsetHeight, M = t/2, _ = e/1.5, T) : _target 
 
    }, T.innerRadius = function(t) { 
 
     return arguments.length ? (x = t, T) : x 
 
    }, T.outerRadius = function(t) { 
 
     return arguments.length ? (A = t, R = t, T) : A 
 
    }, T.radius = function(t) { 
 
     return arguments.length ? (R = t, T) : R 
 
    }, T.renderLine = function(t) { 
 
     return arguments.length ? (j = t, T) : j 
 
    }, T.easing = function(t) { 
 
     return arguments.length ? (F = t, T) : F 
 
    }, T.goal = function(t) { 
 
     return arguments.length ? (G = t, T) : G 
 
    }, T.average = function(t) { 
 
     return arguments.length ? (B = t, T) : B 
 
    }, T.duration = function(t) { 
 
     return arguments.length ? (J = t, T) : J 
 
    }, T 
 
}; 
 

 
custom=gauge().target("action").outerRadius(120).innerRadius(78).radius(65).spread(2.2).goal(80).average(75).easing("linear").duration(2e3).needleWidth(23).needleColor("rgb(230,222,236)"); 
 

 
custom.render(); 
 
custom.update(110); 
 

 
window.setTimeout(function() { 
 
    custom.update(120); 
 
}, 4000); 
 

 
custom2=gauge().target("action2").outerRadius(120).innerRadius(78).radius(65).spread(2.2).goal(80).average(75).easing("linear").duration(2e3).needleWidth(23).needleColor("rgb(230,222,236)"); 
 

 
custom2.render(); 
 
custom2.update(70); 
 

 
window.setTimeout(function() { 
 
    custom2.update(68); 
 
}, 4000);
*{ 
 
    box-sizing: border-box; 
 
} 
 

 
#action{ 
 
    width: 600px; 
 
    height: 400px; 
 
    margin-left: 100px; 
 
    color: #ffffff; 
 
    font-family: sans-serif; 
 
    font-weight: 400; 
 
    text-align: center; 
 
    font-size: 18px; 
 
    border: solid 1px #eee; 
 
    position: absolute; 
 
} 
 

 
#action2{ 
 
    top: 400px; 
 
    width: 600px; 
 
    height: 400px; 
 
    margin-left: 100px; 
 
    color: #ffffff; 
 
    font-family: sans-serif; 
 
    font-weight: 400; 
 
    text-align: center; 
 
    font-size: 18px; 
 
    border: solid 1px #eee; 
 
    position: absolute; 
 
} 
 

 
.gaugeTT{ 
 
    width: 125px; 
 
    background-color: rgb(253,253,253); 
 
    font-size: 0.7em; 
 
    text-align: left; 
 
    color: #777; 
 
    opacity: 0; 
 
    position: absolute; 
 
    top: 0; 
 
    left: 15px; 
 
    border: solid 1px #ccc; 
 
} 
 
.gaugeTT p{ 
 
    margin: 0; 
 
    padding: 0; 
 
    display: block; 
 
} 
 
.gaugeTT .col1{ 
 
    width: 100%; 
 
    text-align: left; 
 
}
<script src="http://d3js.org/d3.v3.js"></script> 
 
<div id="action"></div> 
 
<div id="action2"></div>

+0

真棒,是解決它肯定!非常感謝 –