如何创建交互式d3折线图以显示悬停时的数据图/标签

时间:2015-07-08 15:34:30

标签: javascript d3.js

代码小提琴链接:http://jsfiddle.net/sedhuait/8eep9kpe/9/

 ![function InitChart() {
     var data = \[
         \[
         1413154800000,
         0\],
         \[
         1413158400000,
         0\],
         \[
         1413162000000,
         0\],
         \[
         1413165600000,
         0\],
         \[
         1413169200000,
         0\],
         \[
         1413172800000,
         0\],
         \[
         1413176400000,
         0\],
         \[
         1413180000000,
         27\],
         \[
         1413183600000,
         37\],
         \[
         1413187200000,
         12\],
         \[
         1413190800000,
         13\],
         \[
         1413194400000,
         67\],
         \[
         1413198000000,
         18\],
         \[
         1413201600000,
         1\],
         \[
         1413205200000,
         0\],
         \[
         1413208800000,
         0\],
         \[
         1413212400000,
         0\],
         \[
         1413216000000,
         0\],
         \[
         1413219600000,
         0\],
         \[
         1413223200000,
         0\],
         \[
         1413226800000,
         0\],
         \[
         1413230400000,
         0\],
         \[
         1413234000000,
         0\],
         \[
         1413237600000,
         0\]
     \],
         data1 = \[
             \[
             1413154800000,
             0\],
             \[
             1413158400000,
             0\],
             \[
             1413162000000,
             0\],
             \[
             1413165600000,
             0\],
             \[
             1413169200000,
             0\],
             \[
             1413172800000,
             0\],
             \[
             1413176400000,
             0\],
             \[
             1413180000000,
             1\],
             \[
             1413183600000,
             5\],
             \[
             1413187200000,
             20\],
             \[
             1413190800000,
             16\],
             \[
             1413194400000,
             8\],
             \[
             1413198000000,
             2\],
             \[
             1413201600000,
             3\],
             \[
             1413205200000,
             2\],
             \[
             1413208800000,
             0\],
             \[
             1413212400000,
             0\],
             \[
             1413216000000,
             0\],
             \[
             1413219600000,
             0\],
             \[
             1413223200000,
             0\],
             \[
             1413226800000,
             0\],
             \[
             1413230400000,
             0\],
             \[
             1413234000000,
             0\],
             \[
             1413237600000,
             0\]
         \];





     data.forEach(function (d) {
         d.time = new Date(d\[0\]);
     });

     data1.forEach(function (d) {
         d.time = new Date(d\[0\]);
     });

     var xmax = d3.max(data, function (d) {
         return d.time;
     }),
         xmin = d3.min(data, function (d) {
             return d.time;
         }),
         ymax = d3.max(data, function (d) {
             return d\[1\];
         }),
         ymin = d3.min(data, function (d) {
             return d\[1\];
         });

     var timeFormat = d3.time.format("%I:%M %p ");




     var vis = d3.select("#visualisation"),
         WIDTH = 1000,
         HEIGHT = 500,
         MARGINS = {
             top: 20,
             right: 20,
             bottom: 20,
             left: 50
         },
         xScale = d3.time.scale().range(\[MARGINS.left, WIDTH - MARGINS.right\]).domain(\[xmin, xmax\]),
         yScale = d3.scale.linear().range(\[HEIGHT - MARGINS.top, MARGINS.bottom\]).domain(\[ymin, ymax\]),
         xAxis = d3.svg.axis()
             .scale(xScale)
             .ticks(7)
             .tickPadding(5)
             .tickFormat(timeFormat),
         yAxis = d3.svg.axis()
             .scale(yScale)
             .orient("left");

     vis.append("svg:g")
         .attr("class", "x axis")
         .attr("transform", "translate(0," + (HEIGHT - MARGINS.bottom) + ")")
         .call(xAxis);
     vis.append("svg:g")
         .attr("class", "y axis")
         .attr("transform", "translate(" + (MARGINS.left) + ",0)")
         .call(yAxis);
     var lineGen = d3.svg.line()
         .x(function (d) {
         return xScale(d.time);
     })
         .y(function (d) {
         return yScale(d\[1\]);
     })
         .interpolate("basis");
     vis.append('svg:path')
         .attr('d', lineGen(data))
         .attr('stroke', '#206a82')
         .attr('stroke-width', 5)
         .attr('fill', 'none');

     vis.append('svg:path')
         .attr('d', lineGen(data1))
         .attr('stroke', 'black')
         .attr('stroke-width', 5)
         .attr('fill', 'none');



 }

 InitChart();][1]

输出应该是这样的。 工具提示只应出现在鼠标悬停

actual output

我是d3的新手。我试图从这个啧啧中找到它(http://www.d3noob.org/2013/01/adding-tooltips-to-d3js-graph.html)。

但是由于 .interpolate("基础"); ,它没有正确对齐,如下面的小提琴http://jsfiddle.net/sedhuait/8eep9kpe/10/

请帮助我实现它的步骤。

更新

最后我明白了。但仍面临插值问题('基础')。我希望我的线条边缘光滑。 多行 http://jsfiddle.net/sedhuait/jg4p89c0/

单线 http://jsfiddle.net/sedhuait/772jwy4w/

1 个答案:

答案 0 :(得分:0)

1)对于遵循路径的圆圈,以下代码可能会有所帮助

                var pathEl = path.node();
                var pathLength = pathEl.getTotalLength();
                console.log("Length" + pathLength);
                var BBox = pathEl.getBBox();
                console.log("BBox" + BBox);
                var scale = pathLength/BBox.width;
                console.log("scale" + scale);
                var offsetLeft = document.getElementById("visualisation").offsetLeft;
                console.log("offset" + offsetLeft);



                vis.on("mousemove", function() {
                var x = d3.event.pageX - offsetLeft-90; 
                var beginning = x, end = pathLength, target;
                while (true) {
                target = Math.floor((beginning + end) / 2);
                pos = pathEl.getPointAtLength(target);
                if ((target === end || target === beginning) && pos.x !== x) {
                break;
                }
                if (pos.x > x)      end = target;
                else if (pos.x < x) beginning = target;
                else                break; //position found

}});

如需进一步查询,请参阅http://bl.ocks.org/duopixel/3824661

2)我认为悬停线的工具提示看起来会更好。为此请参考以下链接

http://jsfiddle.net/BvuBV/4/