复制D3.js标尺小部件

时间:2017-03-16 10:23:38

标签: javascript jquery d3.js widget

我在尝试实施加载到以下div中的this widget found in Codepen时遇到了一些麻烦:

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

问题是我想在同一页面上使用其中两个以上,但是当我复制代码时,它会发生what you can see in this snippet实现为两个不同的div:

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

正如您所看到的,第二个小部件无法正常工作,正如我所做的那样,您可能认为这与彼此重叠的变量有关,如果您切换订单它的工作原理!然后它没有意义,如果变量重叠,那么它将始终执行它,无论哪个小部件首先出现。

所以,也许你在想:如果你已经找到解决方案,那么问题是什么?好吧,我需要知道问题出在哪里,因为它们中的每一个都代表从数据库中获取的一些数据,它们可以单独修改和更新,以便将新配置的数据保存回数据库,所以当我刷新其中一个数据时错误的顺序,其中一个小部件永远不会工作,所以现在我必须以正确的顺序刷新它们,直到我发现发生了什么,事实上它们将会超过两个同一页面,所以它们都会低效刷新所有这些以避免崩溃。

试图解决这个问题,我认为这不是关于函数中定义的内部d3.js变量(var t,e,n,r,a,l,s,i,u, o,c,d,g ...),因为它们是本地范围的,所以没有意义。

代码难以阅读导致它被缩小,我使用了一个unminifier来更清楚地阅读它,但无论如何我对D3.js并不太了解......

有什么想法吗?提前谢谢。

1 个答案:

答案 0 :(得分:1)

问题是规范代码在render函数中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>