D3.js鼠标悬停在页面上的多个多线图表

时间:2017-12-29 04:15:51

标签: d3.js

我在页面上使用鼠标悬停代码绘制了多个图表,如下所示 chart with mousever

问题是鼠标线上显示的数据属于chart2。此外,鼠标悬停在chart2上会在chart1中创建一行。构建这些代码的代码是一个大循环。

                var dataset = objects[object].dates;
            dataset.forEach(function (d) {
                if(interval === 'hourly') {
                    var date_parts = d.date.split(/[-|\s|:]/)
                    d.date = new Date(+date_parts[2], (+date_parts[0] - 1), +date_parts[1], +date_parts[3], +date_parts[4]);
                }
                else {
                   var date_parts = d.date.split(/-/);
                   d.date = new Date(+date_parts[2], +date_parts[0] - 1, +date_parts[1]);
                }
                d.total = d.total / 1000000000000;
                d.available = d.available / 1000000000000;
                d.used = d.used / 1000000000000;
                return d;
            });

            var margin = {top: 20, right: 50, bottom: 50, left: 100},
                width = card.offsetWidth - 300 - margin.left - margin.right,
                height = 200 + margin.top + margin.bottom;

            var xScale = d3.scaleTime()
                .domain([
                    d3.min(dataset, function (d) {
                        return d.date;
                    }),
                    d3.max(dataset, function (d) {
                        return d.date;
                    })
                ])
                .range([0, width]);


            var yScale = d3.scaleLinear()
                .domain([0, d3.max(dataset, function (d) {
                    return d.total
                })])
                .range([height, 0]);

          var xAxis;
            if ( interval === "hourly") {
                xAxis = d3.axisBottom()
                    .scale(xScale)
                    .ticks(dataset.length - 1)
                    .tickFormat(formatTime)

            } else if (interval === 'weekly') {
                xAxis = d3.axisBottom()
                    .scale(xScale)
                    .ticks((dataset.length - 1) / 7 )
                    .tickFormat(formatTime);
            }

            //Define Y axis
            var yAxis = d3.axisLeft()
                .scale(yScale)
                .ticks(10);

            var availLine = d3.line()
                .x(function (d) {
                    return xScale(d.date);
                })
                .y(function (d) {
                    return yScale(d.available);
                });

            var totalLine = d3.line()
                .x(function (d) {
                    return xScale(d.date);
                })
                .y(function (d) {
                    return yScale(d.total);
                });

            var usedLine = d3.line()
                .x(function (d) {
                    return xScale(d.date);
                })
                .y(function (d) {
                    return yScale(d.used);
                });

            var svg = d3.select("#" + name)
                .append("svg")
                .attr("perserveApsectRatio", "xMinYMin meet")
                //.attr("width", width + margin.left + margin.right)
                //.attr("height", height + margin.top + margin.bottom)
                .attr("viewBox", "0, 0, " + (width + margin.left + margin.right) + "," + (height + margin.top + margin.bottom) + "")
                //.classed("svg-content", true)
                .append("g")
                .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

           svg.append("path")
                .data([dataset])
                .attr("class", name + "-line")
                .style("stroke", "green")
                .attr("d", availLine);

            svg.append("path")
                .data([dataset])
                .attr("class", name + "-line")
                .style("stroke", "red")
                .attr("d", totalLine);

            svg.append("path")
                .data([dataset])
                .attr("class", name + "-line")
                .style("stroke", "blue")
                .attr("d", usedLine);

            var color = ["red", "green", "blue"];
            var values = ["total", "available", "used"]

            var legend = svg.selectAll('g')
                  .data(values)
                  .enter()
                  .append('g')
                  .attr('class', 'legend');

            legend.append('rect')
                .attr('x', width - 20)
                .attr('y', function(d, i){
                    return i * 20;
                })
                .attr('width', 10)
                .attr('height', 10)
                .style('fill', function(d, i) {
                    return color[i];
                });

            legend.append('text')
                .attr('x', width - 8)
                .attr('y', function(d, i) {
                    return (i * 20) + 9;
                })
                .text(function(d, i) {
                    return d;
                });

            svg.append("g")
                .attr("class", "axis")
                .attr("transform", "translate(0," + height + ")")
                .call(xAxis)
                .style("font-size", ".51em")
                .selectAll("text")
                        .style("text-anchor", "end")
                        .attr("dx", "-.8em")
                        .attr("dy", ".15em")
                        .attr("transform", function(d) {
                            return "rotate(-65)"
                        });


            //svg.append("text")
            //    .attr("transform",
            //        "translate(" + (width / 2) + " ," +
            //        (height + margin.top + 40) + ")")
            //    .style("text-anchor", "middle")
            //    .text("Date/Time");

            svg.append("g")
                .attr("class", "axis")
                .attr("transform", "translate(0 ,0)")
                .call(yAxis)
                .append("text")
                .attr("class", "axis-title")
                .attr("transform", "rotate(-90)")
                .attr("y", 6)
                .attr("dy", ".71em")
                .attr("text-anchor", "end")
                .attr("fill", "#5D6971")
                .text("Terabytes");

            var mouseG = svg.append("g")
                .attr("class", "focus")
                .attr("class", "mouse-over-effects");

            mouseG.append("path")
                .attr("class", "mouse-line")
                .style("stroke", "black")
                .style("stroke-width", "1px")
                .style("opacity", "0");

            var lines = document.getElementsByClassName(name + "-line");

            var mousePerLine = mouseG.selectAll('.mouse-per-line')
                .data([dataset])
                .enter()
                .append("g")
                .attr("class", "mouse-per-line");

            mousePerLine.append("circle")
                .attr("r", 7)
                .style("stroke", function (d) {
                    return d
                })
                .style("fill", "none")
                .style("stroke-width", "1px")
                .style("opacity", "0");

            mousePerLine.append("text")
                .attr("transform", "translate(10,3)");

            mouseG.append("svg:rect")
                .attr('width', width)
                .attr('height', height)
                .attr('fill', 'none')
                .attr('pointer-events', 'all')
                .on("mouseout", function (){
                    d3.select(".mouse-line")
                        .style("opacity", "0");
                    d3.selectAll(".mouse-per-line circle")
                        .style("opacity", "0");
                    d3.selectAll(".mouse-per-line text")
                        .style("opacity", "0");
                })
                .on("mouseover", function() {
                    d3.select(".mouse-line")
                        .style("opacity", "1");
                    d3.selectAll(".mouse-per-line circle")
                        .style("opacity", "1");
                    d3.selectAll(".mouse-per-line text")
                        .style("opacity", "1");
                })
                .on("mousemove", function() {
                  var mouse = d3.mouse(this);
                  d3.select(".mouse-line")
                      .attr("d", function () {
                          var d = "M" + mouse[0] + "," + height;
                          d += " " + mouse[0] + "," + 0;
                          return d;
                       });
                  d3.selectAll(".mouse-per-line")
                      .attr("transform", function(d, i) {
                          console.log(width / mouse[0]);
                          var xDate = xScale.invert(mouse[0]),
                              bisect = d3.bisector(function (d) {
                                  return d.date;
                              }).right;


                          var beginning = 0,
                              end = lines[i].getTotalLength(),
                              target = null;

                          while (true) {
                              target = Math.floor((beginning + end) / 2);
                              var pos = lines[i].getPointAtLength(target);
                              if ((target === end || target === beginning) && pos.x !== mouse[0]) {
                                  break;
                              }
                              else if (pos.x > mouse[0]) beginning = target;
                              else break;
                          }

                          var displayFormat;
                          if(interval === 'weekly' || interval === 'monthly') {
                              displayFormat = d3.timeFormat("%m/%d");
                          }
                          else {
                              displayFormat = d3.timeFormat("%H:%M:%S");
                          }
                          d3.select(this).select('text')
                              .text(displayFormat(xDate) + "\n" + yScale.invert(pos.y).toFixed(2))
                              .attr("font-size", ".7em");

                          return "translate(" + mouse[0] + "," + pos.y + ")";
                      });
                    });

看来,就数据而言,每个数据集都需要与正确的图表相关联。我只是在图表1中激活了鼠标线。

0 个答案:

没有答案