在D3.js中,如果图表被缩放,工具提示无法正确显示

时间:2015-05-20 10:28:40

标签: html d3.js graph tooltip zoom

我正在使用带有缩放功能的D3.js区域图。工具提示功能。我正在长按(触摸或鼠标按下)&在鼠标上工具提示停止。

如果图表未缩放,则工具提示会正确显示,但如果图表缩放,则工具提示未正确更新

任何帮助将不胜感激。请检查创建的小提琴:

http://jsfiddle.net/nZD3E/15/

var date_format = d3.time.format("%b'%y"),
    commaFormat = d3.format(',');
var margin = {
    top: 0,
    right: 10,
    bottom: 45,
    left: 75
};

var stopMove = false,pressTimer, startZoom = true, touchTime = 0, showTooltip = false, ct = 0, savedScale, saveTrans;
var width = 900 - margin.left - margin.right;
var height = 400 - margin.top - margin.bottom;

var bisectDate = d3.bisector(function (d) {
    return new Date(d.date);
}).left,formatDate = d3.time.format("%d-%b");;

var x = d3.time.scale()
    .domain([new Date(data[0].date), d3.time.day.offset(new Date(data[data.length - 1].date), 1)])
    .range([0, width]);

var y = d3.scale.linear()
    .domain(d3.extent(data, function (d) {
    return d.balance;
}))
    .range([height, 0]);

area = d3.svg.area()
    .x(function (d) {
    return x(new Date(d.date));
})
    .y0(height)
    .y1(function (d) {
    return y(d.balance);
});

var zoom = d3.behavior.zoom()
    .x(x)
    .scaleExtent([1, 10])
    .on("zoom", zoomed);

svg = d3.select("body").append("svg")
    .append("svg:svg")
    .attr('width', width + margin.left + margin.right)
    .attr('height', height + margin.top + margin.bottom)
    .append("svg:g")
    .attr("transform", "translate(" + margin.left + "," + margin.top + ")")
    .call(zoom);

svg.append("svg:rect")
    .attr("width", width)
    .attr("height", height)
    .attr("class", "plot");

xAxis = d3.svg.axis()
    .scale(x)
    .orient("bottom")
    .tickSize(-height)
    .tickFormat(date_format);

var yAxis = d3.svg.axis()
    .scale(y)
    .orient("left")
    .ticks(5)
    .tickSize(-width)
    .tickFormat(function (d) {
    return d;
});

svg.append("text")
    .attr("transform", "rotate(-90)")
    .attr("y", (0 - margin.left))
    .attr("x", 0 - ((height) / 2))
    .attr("dy", "1em")
    .style("display", 'none')
    .style("text-anchor", "middle")
    .style("font-size", "11px")
    .style("font-weight", "bold")
    .text("Daily Balance");

svg.append("svg:rect")
    .attr("width", width)
    .attr("height", height)
    .attr("class", "plot");

svg.append("g")
    .attr("class", "x axis")
    .attr("transform", "translate(0," + height + ")")
    .call(xAxis)
    .selectAll("text")
    .style("text-anchor", "end")
    .style("color", "#333")
    .attr("dx", "-1.1em")
    .attr("dy", "-.55em")
    .attr("transform", "rotate(-45)");

svg.append("g")
    .attr("class", "y axis")
    .call(yAxis);

var clip = svg.append("svg:clipPath")
    .attr("id", "clip")
    .append("svg:rect")
    .attr("x", 0)
    .attr("y", 0)
    .attr("width", width)
    .attr("height", height);

var chartBody = svg.append("g")
    .attr("clip-path", "url(#clip)");

chartBody.append("svg:path")
    .datum(data)
    .attr("class", "area")
    .attr("d", area);

var focus = svg.append("g")
    .style("display", "none");

focus.append("line")
    .attr("class", "x")
    .style("stroke", "darkblue")
    .style("stroke-dasharray", "3,3")
    .style("opacity", 0.5)
    .attr("y1", 0)
    .attr("y2", height);

focus.append("line")
    .attr("class", "y")
    .style("stroke", "darkblue")
    .style("stroke-dasharray", "3,3")
    .style("opacity", 0.5)
    .attr("x1", width)
    .attr("x2", width);

focus.append("circle")
    .attr("class", "y")
    .style("fill", "none")
    .style("stroke", "darkblue")
    .attr("r", 4);

focus.append("text")
    .attr("class", "y1")
    .style("stroke", "white")
    .style("stroke-width", "3.5px")
    .style("opacity", 0.8)
    .attr("dx", 8)
    .attr("dy", "-.3em");
focus.append("text")
    .attr("class", "y2")
    .attr("dx", 8)
    .attr("dy", "-.3em");

                svg.append("rect")
                .attr("width", width)
                .attr("height", height)
                .style("fill", "none")
                .style("pointer-events", "all")
                .on("mousedown", function () { touchTime = touchTime + 1; console.log("mouseStart touchTime" + touchTime);
                    if (touchTime == 1) {
                        ct = 1;
                        pressTimer = window.setTimeout(function () {
                            svg.call(zoom)
                            .on("zoom", null)
                            .on("mouseout.zoom", null)
                            .on("mouseover.zoom", null)
                            .on("mousemove.zoom", null)
                            .on("touchstart.zoom",
                            function () {
                                stopMove = true;
                                console.log("mouseDtart in zoomdisabled");
                            })
                            .on("touchmove.zoom", null)
                            .on("touchend.zoom", null);
                            startZoom = false;
                            console.log("show tooltip"); showTooltip = true; focus.style("display", null);//}
                        }, 1000)
                    }
                }
                )
                .on("mouseup", function () {  focus.style("display", "none");
                    touchTime = 0;
                    if (showTooltip) { startZoom = true; }
                    showTooltip = false;
                    console.log("touchend touchTime" + touchTime + " cleartimeout=" + ct);
                    if (ct == 1) {
                        window.clearTimeout(pressTimer);
                        startZoom = true;
                        ct = 0;                       
                    }
                })
                .on("touchend", function () {
                    focus.style("display", "none");
                    touchTime = 0;
                    if (showTooltip) { startZoom = true; }
                    showTooltip = false;
                    console.log("touchend touchTime" + touchTime + " cleartimeout=" + ct);
                    if (ct == 1) {
                        window.clearTimeout(pressTimer);
                        startZoom = true;
                        ct = 0;
                    }
                })
                .on("touchstart", function () {
                    touchTime = touchTime + 1; console.log("touchstart touchTime" + touchTime);
                    if (touchTime == 1) {
                        ct = 1;
                        pressTimer = window.setTimeout(function () {
                            svg.call(zoom)
                            .on("zoom", null)
                            .on("mouseout.zoom", null)
                            .on("mouseover.zoom", null)
                            .on("mousemove.zoom", null)
                            .on("touchstart.zoom",
                            function () {
                                stopMove = true;
                                console.log("touchstart in zoomdisabled");
                            })
                            .on("touchmove.zoom", null)
                            .on("touchend.zoom", null);
                            startZoom = false;
                            console.log("show tooltip"); showTooltip = true; focus.style("display", null);//}
                        }, 1000)
                    }
                }
                )
                .on("mousemove", mousemove)
                .on("touchmove", mousemove);


            function mousemove() {
                if (ct == 1) {
                    console.log("clear timeout");
                    window.clearTimeout(pressTimer);
                    ct = 0;
                }
                if (showTooltip) {
                    console.log("this1=" + x(d3.mouse(this)[0]));
                    var x0 = x.invert(d3.mouse(this)[0]),
                    i = bisectDate(data, x0, 1);
                    console.log("x0=" + x0);
                    if (i < data.length) {
                        var d0 = data[i - 1],
                        d1 = data[i],
                        d = x0 - d0.date > d1.date - x0 ? d1 : d0;

                        focus.select("circle.y")
                        .attr("transform", "translate(" + x(new Date(d.date)) + "," + y(d.balance) + ")");

                        focus.select("text.y1")
                        .attr("transform", "translate(" + x(new Date(d.date)) + "," + y(d.balance) + ")")
                        .text(commaFormat(d.balance));

                        focus.select("text.y2")
                        .attr("transform", "translate(" + x(new Date(d.date)) + "," + y(d.balance) + ")")
                        .text(commaFormat(d.balance));

                        focus.select(".x")
                        .attr("transform", "translate(" + x(new Date(d.date)) + "," + y(d.balance) + ")")
                        .attr("y2", height - y(d.balance));

                        focus.select(".y")
                        .attr("transform", "translate(" + width * -1 + "," + y(d.balance) + ")")
                        .attr("x2", width + width);
                    }
                }
            }
                function zoomed() {

                    var translate = zoom.translate(),
                    scale = zoom.scale();
                    console.log("translate="+translate+" scale="+scale);
                        tx = Math.min(0, Math.max(width * (1 - scale), translate[0]));
                        ty = Math.min(0, Math.max(height * (1 - scale), translate[1]));

                        zoom.translate([tx, ty]);
                        if (startZoom) {                       
                        svg.select(".y.axis").call(yAxis);

                        svg.select(".x.axis").call(xAxis)
                        .selectAll("text")
                        .style("text-anchor", "end")
                        .style("color", "#333")
                        .attr("dx", "-1.1em")
                        .attr("dy", "-.55em")
                        .attr("transform", "rotate(-45)");

                        svg.select(".area")
                        .attr("class", "area")
                        .attr("d", area);
                    }
                }

0 个答案:

没有答案