Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/463.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 工具提示D3折线图出现问题_Javascript_D3.js - Fatal编程技术网

Javascript 工具提示D3折线图出现问题

Javascript 工具提示D3折线图出现问题,javascript,d3.js,Javascript,D3.js,编辑:这里有一个小问题 我在实现简单的D3工具提示时遇到了问题 我有一个多行图表,它适用于其中一行,但仅适用于第二行的第一点。所有线的X值都相等,只是y值不同 小费?相关代码的部分: var div = d3.select("body").append("div") .attr("class", "tooltip") .style("opacity", 0); points.selectAll('.point') .data(fun

编辑:这里有一个小问题

我在实现简单的D3工具提示时遇到了问题

我有一个多行图表,它适用于其中一行,但仅适用于第二行的第一点。所有线的X值都相等,只是y值不同

小费?相关代码的部分:

var div = d3.select("body").append("div") 
    .attr("class", "tooltip")       
    .style("opacity", 0);      

points.selectAll('.point')
        .data(function(d) {
          console.log('.point d is: ', d);
          d.values.forEach(function(kv) {
            console.log('kv is:', kv);
            return kv.name = d.name;
          })
          return d.values;
        })
        .enter()
        .append('circle')
        .attr('circleId', function(d, i) { 
          return 'circleId-'+(i+1);
        })
        .attr('cx', function(d) {
          return x(d.Period);
        })
        .attr('cy', function(d) {
          return y(d.Value);
        })
        .attr('r', function(d) { 
          return dotRadius()
        })
        .on("mouseover", function(d) { 
          console.log('mouseover d is :', d);   
          div.transition()    
            .duration(200)    
            .style("opacity", .9);    
          div.html(d.name + ': ' + d.Value)  
            .style("left", (d3.event.pageX - 24) + "px")   
            .style("top", (d3.event.pageY - 56) + "px");  
        })          
        .on("mouseout", function(d) {   
          div.transition()    
            .duration(500)    
            .style("opacity", 0); 
        });
整个代码减去CSS:

jQuery(document).ready(function ($) {

  var margin = {top: 20, right: 30, bottom: 60, left: 45},
  width = 375 - margin.left - margin.right,
  height = 225 - margin.top - margin.bottom,
  dotRadius = function() { return 3 };  
  // dispatch = d3.dispatch("pointMouseover", "pointMouseout");

  var x = d3.time.scale()
    .range([0, width]);

  var y = d3.scale.linear()
    .range([height, 0]);

  var xAxis = d3.svg.axis()
    .scale(x)
    .orient('bottom')
    .tickFormat(d3.time.format('%b'));

  var yAxis = d3.svg.axis()
    .scale(y)
    .orient('left');

  var div = d3.select("body").append("div") 
    .attr("class", "tooltip")       
    .style("opacity", 0);

  // This is a function that determines the colours of the lines drawn, up to 10.
  var color = d3.scale.category10();

  // This is used to format the time for our data.
  var formatTime = d3.time.format("%Y-%m-%d");

  var line = d3.svg.line()
    .x(function(d) { return x(d.Period); })
    .y(function(d) { return y(d.Value); });


  var svg = d3.select("#pipeline-chart-render")
    .attr('width', width + margin.left + margin.right)
    .attr('height', height + margin.top + margin.bottom)
    .append('g')
    .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

  svg.append("g")
    .attr("class", "x axis")
    .attr("transform", "translate(0," + height + ")")

  // This separates the data into the lines we want, although the data is stored
  // In the same original object.
  color.domain(d3.keys(data[0].values[0]).filter(function(key) { 
    if (key === 'Amount'
     || key === 'Quantity') {
        return key
    }
  }));


  // This returns the data into two separate objects which can be graphed.
  // In this case, Amount and Quantity.
  var datasets = color.domain().map(function(name) {
    return {
      name: name,
      values: data.map(function(d) {
        return {
          Period: formatTime.parse(d.values[0].Time),
          Value: +d.values[0][name]};
      })
    };
  });

  console.log('datasets is: ', datasets);

  // set the minYDomainValue to zero instead of letting it be a lingering magic number.
  var minDomainValue = 0

  var minDate = d3.min(datasets, function(d0){
    return d3.min(d0.values, function(d1){
      return d1.Period;
    })
  }),
  maxDate = d3.max(datasets, function(d0){
    return d3.max(d0.values, function(d1){
      return d1.Period;
    })
  });

  x.domain([minDate, maxDate]);
  y.domain([
    minDomainValue,
    d3.max(datasets, function(c) { return d3.max(c.values, function(v) { return v.Value; }); })
  ])

  // Append the x-axis class and move axis around.
  svg.append("g")
    .attr("class", "x axis")
    .attr("transform", "translate(0," + height + ")")
    .call(xAxis)
    .append('text')
    .attr('x', 150)
    .attr('y', 36)
    .style('text-anchor', 'middle')
    .text('2015');

  // Append the y-axis class.
  svg.append("g")
    .attr("class", "y axis")
    .call(yAxis)
    .append("text")
    .attr("transform", "rotate(-90)")
    .attr("y", -30)
    .attr('x', -30)
    .style("text-anchor", "end")
    .text("Quantity/Amount");

  // The following is for defining the area BETWEEN graphs.  
  var areaAboveQuantity = d3.svg.area()
    .x(line.x())
    .y0(line.y())
    .y1(0);

  var areaBelowQuantity = d3.svg.area()
    .x(line.x())
    .y0(line.y())
    .y1(height);

  var areaAboveAmount = d3.svg.area()
    .x(line.x())
    .y0(line.y())
    .y1(0);
  var areaBelowAmount = d3.svg.area()
    .x(line.x())
    .y0(line.y())
    .y1(height);

  var pipeline = svg.selectAll('.pipeline')
    .data(datasets);

  pipeline.enter()
    .append('g')
    .attr('class', 'pipeline');


  pipeline.append('path')
    .attr('class', 'line')
    .attr('id', function(d, i) {
      return 'pipeline-'+(i+1);
    })
    .attr('d', function(d) { console.log('line d is: ', d); return line(d.values); })
    .attr("data-legend",function(d) { return d.name})
    .style("stroke", function(d) { return color(d.name); })

  pipeline.exit().remove()

  // Rendering the points on the graph.
  var points = svg.selectAll('.pipelinePoint')
    .data(datasets);

  points
    .enter()
    .append('g')
    .attr('class', 'pipelinePoint');

  points.selectAll('.point')
    .data(function(d) {
      console.log('.point d is: ', d);
      d.values.forEach(function(kv) {
        console.log('kv is:', kv);
        return kv.name = d.name;
      })
      return d.values;
    })
    .enter()
    .append('circle')
    .attr('circleId', function(d, i) { 
      return 'circleId-'+(i+1);
    })
    .attr('cx', function(d) {
      return x(d.Period);
    })
    .attr('cy', function(d) {
      return y(d.Value);
    })
    .attr('r', function(d) { 
      return dotRadius()
    })
    .on("mouseover", function(d) { 
      console.log('mouseover d is :', d);   
      div.transition()    
        .duration(200)    
        .style("opacity", .9);    
      div.html(d.name + ': ' + d.Value)  
        .style("left", (d3.event.pageX - 24) + "px")   
        .style("top", (d3.event.pageY - 56) + "px");  
    })          
    .on("mouseout", function(d) {   
      div.transition()    
        .duration(500)    
        .style("opacity", 0); 
    });



  var defs = svg.append('defs');

  defs.append('clipPath')
    .attr('id', 'clip-quantity')
    .append('path')
    .datum(datasets)
    .attr('d', function(d) {
       return areaAboveQuantity(d[1].values);
    });

  defs.append('clipPath')
    .attr('id', 'clip-amount')
    .append('path')
    .datum(datasets)
    .attr('d', function(d) {
      return areaAboveAmount(d[0].values);
    });


  svg.append('path')
    .datum(datasets)
    .attr('class', 'area')
    .attr('d', function(d) {
      return areaBelowQuantity(d[1].values)
    });

  // Quantity IS ABOVE Amount
  svg.append('path')
    .datum(datasets)
    .attr('d', function(d) {
      areaBelowQuantity(d[1].values);
    })
    .attr('clip-path', 'url(#clip-amount)')
    .style('fill', 'steelblue')
    .style('opacity', '0.2');


  // Amount IS ABOVE Quanity
  svg.append('path')
    .datum(datasets)
    .attr('d', function(d) {
      return areaBelowAmount(d[0].values);
    })
    .attr('clip-path', 'url(#clip-quantity)')
    .style('fill', 'steelblue')
    .style('opacity', '0.2')
    // .on("mouseover", function(d) { 
    //   console.log('mouseover d is :', d);   
    //   div.transition()    
    //     .duration(200)    
    //     .style("opacity", .9);    
    //   div.html('Hello')  
    //     .style("left", (d3.event.pageX) + "px")   
    //     .style("top", (d3.event.pageY - 28) + "px");  
    // })          
    // .on("mouseout", function(d) {   
    //   div.transition()    
    //     .duration(500)    
    //     .style("opacity", 0); 
    // });


  legend1 = svg.append("g")
    .attr("class","legend")
    .attr("transform","translate(-20,180)")
    .style("font-size","12px")
    .call(d3Legend)

})

var d3Legend = function(g) {
  g.each(function() {
    var g= d3.select(this),
        items = {},
        svg = d3.select(g.property("nearestViewportElement")),
        legendPadding = g.attr("data-style-padding") || 5,
        lb = g.selectAll(".legend-box").data([true]),
        li = g.selectAll(".legend-items").data([true])

    lb.enter().append("rect").classed("legend-box",true)
    li.enter().append("g").classed("legend-items",true)

    svg.selectAll("[data-legend]").each(function() {
      var self = d3.select(this)
      items[self.attr("data-legend")] = {
        pos : self.attr("data-legend-pos") || this.getBBox().y,
        color : self.attr("data-legend-color") != undefined ? self.attr("data-legend-color") : self.style("fill") != 'none' ? self.style("fill") : self.style("stroke") 
      }
    })

    items = d3.entries(items).sort(function(a,b) { return a.value.pos-b.value.pos})

    li.selectAll("text")
        .data(items,function(d) { return d.key})
        .call(function(d) { d.enter().append("text")})
        .call(function(d) { d.exit().remove()})
        .attr("y",function(d,i) { return i+"em"})
        .attr("x","1em")
        .text(function(d) { ;return d.key})

    li.selectAll("circle")
        .data(items,function(d) { return d.key})
        .call(function(d) { d.enter().append("circle")})
        .call(function(d) { d.exit().remove()})
        .attr("cy",function(d,i) { return i-0.25+"em"})
        .attr("cx",0)
        .attr("r","0.4em")
        .style("fill",function(d) { return d.value.color})  

    // Reposition and resize the box
    var lbbox = li[0][0].getBBox()  
    lb.attr("x",(lbbox.x-legendPadding))
        .attr("y",(lbbox.y-legendPadding))
        .attr("height",(lbbox.height+2*legendPadding))
        .attr("width",(lbbox.width+2*legendPadding))
  })
  return g
};

var data = [
  {
    key: 1,
    values: [
      {
        Amount: 33,
        Quantity: 22,
        Time: '2015-01-01'
      }
    ]
  },
  {
    key: 2,
    values: [
      {
        Amount: 52,
        Quantity: 20,
        Time: '2015-02-01'
      }
    ]
  },
  {
    key: 3,
    values: [
      {
        Amount: 63,
        Quantity: 30,
        Time: '2015-03-01'
      }
    ]
  },
  {
    key: 4,
    values: [
      {
        Amount: 92,
        Quantity: 60,
        Time: '2015-04-01'
      }
    ]
  },
  {
    key: 5,
    values: [
      {
        Amount: 50,
        Quantity: 29,
        Time: '2015-05-01'
      }
    ]
  },
  {
    key: 6,
    values: [
      {
        Amount: 53,
        Quantity: 25,
        Time: '2015-06-01'
      }
    ]
  },
  {
    key: 7,
    values: [
      {
        Amount: 46,
        Quantity: 12,
        Time: '2015-07-01'
      }
    ]
  },
  {
    key: 8,
    values: [
      {
        Amount: 52,
        Quantity: 15,
        Time: '2015-08-01'
      }
    ]
  },
  {
    key: 9,
    values: [
      {
        Amount: 55,
        Quantity: 20,
        Time: '2015-09-01'
      }
    ]
  },
  {
    key: 10,
    values: [
      {
        Amount: 35,
        Quantity: 17,
        Time: '2015-10-01'
      }
    ]
  },
  {
    key: 11,
    values: [
      {
        Amount: 80,
        Quantity: 45,
        Time: '2015-11-01'
      }
    ]
  },
  {
    key: 12,
    values: [
      {
        Amount: 64,
        Quantity: 24,
        Time: '2015-12-01'
      }
    ]
  }
]

这是因为您的路径妨碍了您在节点上悬停。您需要将
指针事件设置为
none
,如下所示:

我创建了一个类-noPointers:

.noPointers{
  pointer-events:none;
}
并将其应用于挡道的路径(第369行):


更新的fiddle:

设置JSFIDLE。当你能看到发生了什么时,代码更容易阅读:)是的,工作得很好。这仅仅是一个CSS解决方案,真让人伤心。哈哈,通常答案都很简单:)只要知道去哪里找:)
 // Amount IS ABOVE Quanity
    svg.append('path')
      .datum(datasets).attr('class', 'noPointers')//added class here