对D3可重复使用折线图的第二次调用仅绘制轴而不是线

时间:2016-03-09 01:09:40

标签: d3.js charts

我正在尝试制作一个折线图,其中绘制了两条线,一条线显示在今天的日期之前,另一条线显示在今天的日期之后,因为我使用的是D3的剪辑路径,用户可以点击按钮来更新图表。那部分有效,但是当我尝试使代码可重用时,因为我想要第一个下面的第二个图表,当我将第二个容器传递给相同的图表函数时(即图表1的#graph1和图表2的#graph2)它只绘制轴但不绘制第二个图形的线条(第一个图形仍然有效),是否有人指向正确的方向?谢谢。 以下是我的代码:

function chart(selection) {
       selection.each(function(data) {

      var svg = d3.select(this).selectAll("svg").data([data]);

      // Update the outer dimensions.
      svg.attr("width", width)
          .attr("height", height);

      // Update the inner dimensions.
      var g = svg.select("g")
          .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

      if(alreadyClicked==true){

         svg.select("#clip-before rect")
         .transition().duration(400)
         .attr("width", xScale(parsedate(today)))
         .attr("height", height- margin.top - margin.bottom);

         svg.select("#clip-after rect")
         .transition().duration(400)
         .attr("x", xScale(parsedate(today)))
         .attr("width", width-xScale(parsedate(today)))
         .attr("height", height- margin.top - margin.bottom);

         svg.selectAll("path.line-after")
         .data(data).transition()
         .duration(400).attr("d", line_after(data));

         svg.selectAll("path.line-before")
         .data(data).transition()
         .duration(400).attr("d", line_before(data));


      }else{
        g.append("clipPath")
              .attr("id", "clip-before")
              .append("rect")
              .attr("width", xScale(parsedate(today)))
              .attr("height", height- margin.top - margin.bottom);

         g.append("clipPath")
              .attr("id", "clip-after")
              .append("rect")
              .attr("x", xScale(parsedate(today)))
              .attr("width", width-xScale(parsedate(today)))
              .attr("height", height- margin.top - margin.bottom);

        g.selectAll(".line")
              .data(["after"])
              .enter().append("path")
              .attr("class", function(d) { return "line-" + d; })
              .attr("clip-path", function(d) { return "url(#clip-" + d + ")"; })
              .attr("d", line_after(data));

         g.selectAll(".line")
              .data(["before"])
              .enter().append("path")
              .attr("class", function(d) { return "line-" + d; })
              .attr("clip-path", function(d) { return "url(#clip-" + d + ")"; })
              .attr("d", line_before(data));


      }





    // Add the X Axis
      g.append("g")
            .attr("class", "x axis");


      svg.select(".x.axis")
            .attr("transform", "translate(0,300)").transition().duration(400).call(xAxis);

      g.selectAll(".x.axis text")  // select all the text elements for the xaxis
          .attr("transform", function(d) {
             return "translate(" + this.getBBox().height*-2 + "," + this.getBBox().height + ")rotate(-45)";
         });

      // Add the Y Axis
      g.append("g")
            .attr("class", "y axis"); 

      svg.select(".y.axis").transition().duration(400).call(yAxis);


  }); //end selection.each
}//end chart

1 个答案:

答案 0 :(得分:0)

/**
* PredictGraph code start
*/
(function () {
	d3.PredictGraph = function() {
  	  // OPTIONS 
	  // (manipulated with getters and setters below)
	  var margin = {top: 50, right: 20, bottom: 100, left: 60},
		  width = getWidth($(window).width()),
		  height = 450,
		  xValue = function(d) { return d.date; },
		  yValue = function(d) { return d.actualvalue; },
		  yValue2= function(d) { return d.predictedvalue;},  
		  xScale = d3.time.scale().range([0, width]),
		  yScale = d3.scale.linear().range([height, 0]),
		  xAxis = xAxis = d3.svg.axis().scale(xScale)
			.orient("bottom").ticks(10).tickFormat(d3.time.format("%Y-%m-%d")), //this is where the date is formatted for the axis,
		  yAxis = d3.svg.axis().scale(yScale)
			.orient("left").ticks(10),
		  line = d3.svg.line().x(X).y(Y),
		  line_before= d3.svg.line()
				.x(function(d) { return xScale(d.date);})
				.y(function(d) { return yScale(d.actualvalue);
							}),
		  line_after= d3.svg.line()
				.x(function(d) { return xScale(d.date);})
				.y(function(d) { return yScale(d.predictedvalue);})
		  today= moment()._d, //date object
		  formatDate = d3.time.format("%Y-%m-%d"),
		  todayFormatted = formatDate(moment()._d),
		  alreadyClicked=false;
	  function chart(selection) {
		selection.each(function(data) {
		console.log(this);
		var max_actual = d3.max(data, function(d) { return d.actualvalue;} ); //before
		var max_predicted = d3.max(data, function(d) { return d.predictedvalue;} ); //after
		var max = Math.max(max_actual, max_predicted); //overall
		var min_actual = d3.min(data, function(d) { return d.actualvalue;} ); //before
		var min_predicted = d3.min(data, function(d) { return d.predictedvalue;} ); //after
		var min = Math.min(min_actual, min_predicted);			  
		var parsedate = d3.time.format("%Y-%m-%d").parse;		
		// to convert date from a formated string into a date object
			data.forEach(function(d) {d.date = parsedate(d.date);});  			
		  // Update the x-scale.
		  xScale.domain(d3.extent(data, function(d) { return d.date; })).range([0, width- margin.left - margin.right]);
		  // Update the y-scale.
		  yScale.domain([min,max]).range([height- margin.top - margin.bottom,0]);
		  // Select the svg element, if it exists.
		  var svg = d3.select(this).selectAll("svg").data([data]);
		//Otherwise, create the skeletal chart.
		  var gEnter = svg.enter().append("svg").append("g");
		  // Update the outer dimensions.
		  svg.attr("width", width).attr("height", height);
		  // Update the inner dimensions.
		  var g = svg.select("g").attr("transform", "translate(" + margin.left + "," + margin.top + ")");		
		 console.log(svg.select("#clip-before"+this.id));
          var currNode=this;				  
		  if(svg.select("#clip-before"+this.id)[0][0]!=null){		  	
		     svg.select("#clip-before"+this.id+" rect")
		     .transition().duration(400)
		     .attr("width", xScale(parsedate(today)))
			 .attr("height", height- margin.top - margin.bottom);
			 
			 svg.select("#clip-after"+this.id+" rect")
		     .transition().duration(400)
		     .attr("x", xScale(parsedate(today)))
		     .attr("width", width-xScale(parsedate(today)))
			 .attr("height", height- margin.top - margin.bottom);
		  	
		  	 svg.selectAll("path.line-after")
		  	 .data(data).transition()
             .duration(400).attr("d", line_after(data));
             
             svg.selectAll("path.line-before")
		  	 .data(data).transition()
             .duration(400).attr("d", line_before(data));
             
             svg.select("line.today")
		     .transition().duration(400)
		     .attr({'x1': xScale(parsedate(today)),'y1': 0,'x2': xScale(parsedate(today)),'y2': height- margin.top - margin.bottom})
				.style("stroke", "#FF7F66")
				.style("stroke-dasharray", ("3, 3")) 
				.style("fill", "none");	             
		  }else{
		  	g.append("clipPath")
				  .attr("id", "clip-before"+this.id)
				  .append("rect")
				  .attr("width", xScale(parsedate(today)))
				  .attr("height", height- margin.top - margin.bottom);
				  
			 g.append("clipPath")
				  .attr("id", "clip-after"+this.id)
				  .append("rect")
				  .attr("x", xScale(parsedate(today)))
				  .attr("width", width-xScale(parsedate(today)))
				  .attr("height", height- margin.top - margin.bottom);
				  
		  	g.selectAll(".line")
				  .data(["after"])
				  .enter().append("path")
				  .attr("class", function(d) { return "line-" + d; })
				  .attr("clip-path", function(d) { return "url(#clip-"+d+currNode.id+")"; })
				  .attr("d", line_after(data));
				  
			 g.selectAll(".line")
				  .data(["before"])
				  .enter().append("path")
				  .attr("class", function(d) { return "line-" + d; })
				  .attr("clip-path", function(d) { return "url(#clip-"+d+currNode.id+")"; })
				  .attr("d", line_before(data));
				  
			g.append("line")
				.attr("class","today")
				.attr({
					'x1': xScale(parsedate(today)),
					'y1': 0,
					'x2': xScale(parsedate(today)),
					'y2': height- margin.top - margin.bottom
				})
				.style("stroke", "#FF7F66")
				.style("stroke-dasharray", ("3, 3")) 
				.style("fill", "none");			
		  }
		// Add the X Axis
		  g.append("g")
				.attr("class", "x axis");
				//.call(xAxis);
				
		  svg.select(".x.axis")
 				.attr("transform", "translate(0,300)").transition().duration(400).call(xAxis);
 		        
		  g.selectAll(".x.axis text")  // select all the text elements for the xaxis
			  .attr("transform", function(d) {
				 return "translate(" + this.getBBox().height*-2 + "," + this.getBBox().height + ")rotate(-45)";
			 });

		  // Add the Y Axis
		  g.append("g")
 				.attr("class", "y axis"); //.call(yAxis)
			
		  svg.select(".y.axis").transition().duration(400).call(yAxis);		
	       alreadyClicked = true;
		});
	  }

	  // The x-accessor for the path generator; xScale ∘ xValue.
	  function X(d) {
		return xScale(formatDate.parse(d.date));
	  }

	  // The y-accessor for the path generator; yScale ∘ yValue.
	  function Y(d) {
		return yScale(d.actualvalue);
	  }
  
	  function Y2(d){
		return yScale(d.predictedvalue);
	  }

	  chart.margin = function(_) {
		if (!arguments.length) return margin;
		margin = _;
		return chart;
	  };

	  chart.width = function(_) {
		if (!arguments.length) return width;
		width = _;
		return chart;
	  };

	  chart.height = function(_) {
		if (!arguments.length) return height;
		height = _;
		return chart;
	  };

	  chart.x = function(_) {
		if (!arguments.length) return xValue;
		xValue = _;
		return chart;
	  };

	  chart.y = function(_) {
		if (!arguments.length) return yValue;
		yValue = _;
		return chart;
	  };
	  function getWidth(width){
	
			if (width > 1500 || width < 990) {
				return 800;
			}else if ( width > 1300 && width > 990){
				return 700;
			}else{
				return 650;
			}
		}  
	   return chart;
	};
})();

/*PredictGraph code end*/


/*app.js code start*/

		var chart = d3.PredictGraph();	
		//Global Variables
		
		var formatDate = d3.time.format("%Y-%m-%d");
		var today = formatDate(moment()._d) || "2016-01-01";
		var first_day = formatDate(getFirstDay()) || "2015-01-01";
		var numMonths = "three";  //one, three, six, twelve
		var last_day = formatDate(getLastDay(numMonths)) || "2016-04-01";
		var product = "product1";
		var loaded = false;
		// called everytime a user clicks on a month button or select a dropdown menu item
		// input params: the firstDay (today minus 12 months), lastDay (pass value retrieved from numMonths into getLastDay)
		// 				 productSelected (selected product based on dropdown menu value)
		function updateResults(firstDay, lastDay, productSelected){
		
			//get data... will get from Django eventually instead of json file
			//d3.json("data/data.json",function(data){	
          var data=[{"date":"2015-01-01","productname":"product1","actualvalue":512,"predictedvalue":05},{"date":"2015-02-01","productname":"product1","actualvalue":311,"predictedvalue":426},{"date":"2015-03-01","productname":"product1","actualvalue":305,"predictedvalue":725},{"date":"2015-04-01","productname":"product1","actualvalue":396,"predictedvalue":887},{"date":"2015-05-01","productname":"product1","actualvalue":70,"predictedvalue":299},{"date":"2015-06-01","productname":"product1","actualvalue":32,"predictedvalue":40},{"date":"2015-07-01","productname":"product1","actualvalue":157,"predictedvalue":504},{"date":"2015-08-01","productname":"product1","actualvalue":335,"predictedvalue":372},{"date":"2015-09-01","productname":"product1","actualvalue":426,"predictedvalue":899},{"date":"2015-10-01","productname":"product1","actualvalue":983,"predictedvalue":842},{"date":"2015-11-01","productname":"product1","actualvalue":701,"predictedvalue":569},{"date":"2015-12-01","productname":"product1","actualvalue":674,"predictedvalue":387},{"date":"2016-01-01","productname":"product1","actualvalue":986,"predictedvalue":65},{"date":"2016-02-01","productname":"product1","actualvalue":426,"predictedvalue":49},{"date":"2016-03-01","productname":"product1","actualvalue":130,"predictedvalue":63},{"date":"2016-04-01","productname":"product1","actualvalue":674,"predictedvalue":889},{"date":"2016-05-01","productname":"product1","actualvalue":192,"predictedvalue":983},{"date":"2016-06-01","productname":"product1","actualvalue":6,"predictedvalue":186},{"date":"2016-07-01","productname":"product1","actualvalue":476,"predictedvalue":181},{"date":"2016-08-01","productname":"product1","actualvalue":493,"predictedvalue":544},{"date":"2016-09-01","productname":"product1","actualvalue":121,"predictedvalue":792},{"date":"2016-10-01","productname":"product1","actualvalue":745,"predictedvalue":712},{"date":"2016-11-01","productname":"product1","actualvalue":755,"predictedvalue":46},{"date":"2016-12-01","productname":"product1","actualvalue":361,"predictedvalue":810},{"date":"2015-01-01","productname":"product2","actualvalue":675,"predictedvalue":722},{"date":"2015-02-01","productname":"product2","actualvalue":690,"predictedvalue":388},{"date":"2015-03-01","productname":"product2","actualvalue":994,"predictedvalue":871},{"date":"2015-04-01","productname":"product2","actualvalue":678,"predictedvalue":656},{"date":"2015-05-01","productname":"product2","actualvalue":901,"predictedvalue":216},{"date":"2015-06-01","productname":"product2","actualvalue":304,"predictedvalue":491},{"date":"2015-07-01","productname":"product2","actualvalue":223,"predictedvalue":360},{"date":"2015-08-01","productname":"product2","actualvalue":299,"predictedvalue":487},{"date":"2015-09-01","productname":"product2","actualvalue":80,"predictedvalue":267},{"date":"2015-10-01","productname":"product2","actualvalue":760,"predictedvalue":830},{"date":"2015-11-01","productname":"product2","actualvalue":122,"predictedvalue":273},{"date":"2015-12-01","productname":"product2","actualvalue":859,"predictedvalue":258},{"date":"2016-01-01","productname":"product2","actualvalue":807,"predictedvalue":729},{"date":"2016-02-01","productname":"product2","actualvalue":82,"predictedvalue":939},{"date":"2016-03-01","productname":"product2","actualvalue":72,"predictedvalue":348},{"date":"2016-04-01","productname":"product2","actualvalue":544,"predictedvalue":429},{"date":"2016-05-01","productname":"product2","actualvalue":512,"predictedvalue":562},{"date":"2016-06-01","productname":"product2","actualvalue":510,"predictedvalue":800},{"date":"2016-07-01","productname":"product2","actualvalue":283,"predictedvalue":847},{"date":"2016-08-01","productname":"product2","actualvalue":172,"predictedvalue":343},{"date":"2016-09-01","productname":"product2","actualvalue":315,"predictedvalue":633},{"date":"2016-10-01","productname":"product2","actualvalue":863,"predictedvalue":184},{"date":"2016-11-01","productname":"product2","actualvalue":125,"predictedvalue":623},{"date":"2016-12-01","productname":"product2","actualvalue":400,"predictedvalue":920}];
				// get data between first and last day and for the selected product
				// draw a single line as a test
				var test_data = data.filter(function(el){
					return el.date < lastDay && el.date > firstDay && el.productname == productSelected
				});
			d3.select("#graph1").datum(test_data).call(chart);
			//});
		}
		
		function updateResults2(firstDay, lastDay, productSelected){ 
			//get data... will get from Django eventually instead of json file
			//d3.json("data/data.json",function(data){
		var data=[{"date":"2015-01-01","productname":"product1","actualvalue":512,"predictedvalue":805},{"date":"2015-02-01","productname":"product1","actualvalue":311,"predictedvalue":426},{"date":"2015-03-01","productname":"product1","actualvalue":305,"predictedvalue":725},{"date":"2015-04-01","productname":"product1","actualvalue":396,"predictedvalue":887},{"date":"2015-05-01","productname":"product1","actualvalue":70,"predictedvalue":299},{"date":"2015-06-01","productname":"product1","actualvalue":32,"predictedvalue":40},{"date":"2015-07-01","productname":"product1","actualvalue":157,"predictedvalue":504},{"date":"2015-08-01","productname":"product1","actualvalue":335,"predictedvalue":372},{"date":"2015-09-01","productname":"product1","actualvalue":426,"predictedvalue":899},{"date":"2015-10-01","productname":"product1","actualvalue":983,"predictedvalue":842},{"date":"2015-11-01","productname":"product1","actualvalue":701,"predictedvalue":569},{"date":"2015-12-01","productname":"product1","actualvalue":674,"predictedvalue":387},{"date":"2016-01-01","productname":"product1","actualvalue":986,"predictedvalue":65},{"date":"2016-02-01","productname":"product1","actualvalue":426,"predictedvalue":49},{"date":"2016-03-01","productname":"product1","actualvalue":130,"predictedvalue":63},{"date":"2016-04-01","productname":"product1","actualvalue":674,"predictedvalue":889},{"date":"2016-05-01","productname":"product1","actualvalue":192,"predictedvalue":983},{"date":"2016-06-01","productname":"product1","actualvalue":6,"predictedvalue":186},{"date":"2016-07-01","productname":"product1","actualvalue":476,"predictedvalue":181},{"date":"2016-08-01","productname":"product1","actualvalue":493,"predictedvalue":544},{"date":"2016-09-01","productname":"product1","actualvalue":121,"predictedvalue":792},{"date":"2016-10-01","productname":"product1","actualvalue":745,"predictedvalue":712},{"date":"2016-11-01","productname":"product1","actualvalue":755,"predictedvalue":46},{"date":"2016-12-01","productname":"product1","actualvalue":361,"predictedvalue":810},{"date":"2015-01-01","productname":"product2","actualvalue":675,"predictedvalue":722},{"date":"2015-02-01","productname":"product2","actualvalue":690,"predictedvalue":388},{"date":"2015-03-01","productname":"product2","actualvalue":994,"predictedvalue":871},{"date":"2015-04-01","productname":"product2","actualvalue":678,"predictedvalue":656},{"date":"2015-05-01","productname":"product2","actualvalue":901,"predictedvalue":216},{"date":"2015-06-01","productname":"product2","actualvalue":304,"predictedvalue":491},{"date":"2015-07-01","productname":"product2","actualvalue":223,"predictedvalue":360},{"date":"2015-08-01","productname":"product2","actualvalue":299,"predictedvalue":487},{"date":"2015-09-01","productname":"product2","actualvalue":80,"predictedvalue":267},{"date":"2015-10-01","productname":"product2","actualvalue":760,"predictedvalue":830},{"date":"2015-11-01","productname":"product2","actualvalue":122,"predictedvalue":273},{"date":"2015-12-01","productname":"product2","actualvalue":859,"predictedvalue":258},{"date":"2016-01-01","productname":"product2","actualvalue":807,"predictedvalue":729},{"date":"2016-02-01","productname":"product2","actualvalue":82,"predictedvalue":939},{"date":"2016-03-01","productname":"product2","actualvalue":72,"predictedvalue":348},{"date":"2016-04-01","productname":"product2","actualvalue":544,"predictedvalue":429},{"date":"2016-05-01","productname":"product2","actualvalue":512,"predictedvalue":562},{"date":"2016-06-01","productname":"product2","actualvalue":510,"predictedvalue":800},{"date":"2016-07-01","productname":"product2","actualvalue":283,"predictedvalue":847},{"date":"2016-08-01","productname":"product2","actualvalue":172,"predictedvalue":343},{"date":"2016-09-01","productname":"product2","actualvalue":315,"predictedvalue":633},{"date":"2016-10-01","productname":"product2","actualvalue":863,"predictedvalue":184},{"date":"2016-11-01","productname":"product2","actualvalue":125,"predictedvalue":623},{"date":"2016-12-01","productname":"product2","actualvalue":400,"predictedvalue":920}];
				
				// get data between first and last day and for the selected product
				// draw a single line as a test
				var test_data = data.filter(function(el){
					return el.date < lastDay && el.date > firstDay && el.productname == productSelected
				});
				d3.select("#graph2").datum(test_data).call(chart);		
			//});
		}
		$(document).ready(function(){		
			$("#button30").click( function(){
				$(".buttons1").removeClass("selected-button");
				$("#button30").addClass("selected-button");
				numMonths= $("#button30").data('months'); 
				first_day=formatDate(getFirstDay());
				last_day=formatDate(getLastDay(numMonths)); 
				updateResults(first_day,last_day,product);
			});
			
			$("#button90").click( function(){
				$(".buttons1").removeClass("selected-button");
				$("#button90").addClass("selected-button");
				numMonths= $("#button90").data('months');
				first_day=formatDate(getFirstDay());
				last_day=formatDate(getLastDay(numMonths)); 
				updateResults(first_day,last_day,product);
			});
			
			$("#button180").click( function(){
				$(".buttons1").removeClass("selected-button");
				$("#button180").addClass("selected-button");
				numMonths= $("#button180").data('months');
				first_day=formatDate(getFirstDay());
				last_day=formatDate(getLastDay(numMonths)); 
				updateResults(first_day,last_day,product);
			});
			
			$("#button360").click( function(){
				$(".buttons1").removeClass("selected-button");
				$("#button360").addClass("selected-button");
				numMonths= $("#button360").data('months');
				first_day=formatDate(getFirstDay());
				last_day=formatDate(getLastDay(numMonths)); 
				updateResults(first_day,last_day,product);
			});
			
			updateResults(first_day,last_day,product);
			$("#button30-2").click( function(){
				$(".buttons2").removeClass("selected-button");
				$("#button30-2").addClass("selected-button");
				numMonths= $("#button30-2").data('months');
				first_day=formatDate(getFirstDay());
				last_day=formatDate(getLastDay(numMonths)); 
				updateResults2(first_day,last_day,product);
			});
			
			$("#button90-2").click( function(){
				$(".buttons2").removeClass("selected-button");
				$("#button90-2").addClass("selected-button");
				numMonths= $("#button90-2").data('months');
				first_day=formatDate(getFirstDay());
				last_day=formatDate(getLastDay(numMonths));
				updateResults2(first_day,last_day,product);
			});
			
			$("#button180-2").click( function(){
				$(".buttons2").removeClass("selected-button");
				$("#button180-2").addClass("selected-button");
				numMonths= $("#button180-2").data('months'); 
				first_day=formatDate(getFirstDay());
				last_day=formatDate(getLastDay(numMonths));  
				updateResults2(first_day,last_day,product);
			});
			
			$("#button360-2").click( function(){
				$(".buttons2").removeClass("selected-button");
				$("#button360-2").addClass("selected-button");
				numMonths= $("#button360-2").data('months'); //or .data()
				first_day=formatDate(getFirstDay());
				last_day=formatDate(getLastDay(numMonths));  // to set last day
				updateResults2(first_day,last_day,product);
			});
			
			updateResults2(first_day,last_day,product);

   		});
			// function to set last day date... basically today + 1, 3, 6, or 12 months, default is 3
			function getLastDay(months){ 

				switch(months){
					case "one": 
				
						return moment().add(1, 'months')._d; 
					break;
					case"six": 
				
						return moment().add(6, 'months')._d; 
					break;
					case"twelve":  
					
						return moment().add(12, 'months')._d; 
					break; 
					default: 
						return moment().add(3, 'months')._d; 
				};

			}
			
			// function to set first day date... basically today - 12
			function getFirstDay(){
				return moment().subtract(12,'months')._d;
			}
.container{
  margin-top:50px;}
html, body {
  height: 100%; font-family: 'Open Sans', sans-serif;}
.wrap{
  min-heigh:100%;
}
.prediction{
  height:700px;
}
.footer{
  width:100%;
  position:fixed;
  bottom:0px;padding:0px;text-align:center;}
.footer p{margin-left:auto;margin-right:auto;}
    .selected-button{background-color: black;border-color: black;color:white;}
  
	.axis path,
	.axis line {
		fill: none;
		stroke: #000;
		shape-rendering: crispEdges;
	}
	.x.axis path {}	.line {
		fill: none;
		stroke: steelblue;
		stroke-width: 1.5px;
	}

	.line-before {
		stroke:#2185C5;
		fill: none;
	}
	.line-after{
		stroke:#FFB779;
		fill: none;
	}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/jquery-easing/1.3/jquery.easing.min.js"></script>
    <script src="http://jhjanicki.github.io/reusable-line-chart/js/bootstrap.min.js"></script>
<script src="http://jhjanicki.github.io/reusable-line-chart/js/moment.js"></script>
    <!-- D3 --><script src="http://d3js.org/d3.v3.js" charset="utf-8"></script>
   	<!-- underscore --><script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
<div class="container" id="main">
<section class="prediction" id="prediction1">
<div class="row">
<div class="col-lg-12">
<div class="buttons">
<button type="button" class="btn btn-default buttons1" data-months="one" id="button30"> 1 Month</button>
<button type="button" class="btn btn-default selected-button buttons1" data-months="three" id="button90"> 3 Months</button>
<button type="button" class="btn btn-default buttons1" data-months="six" id="button180"> 6 Months</button>
<button type="button" class="btn btn-default buttons1" data-months="twelve" id="button360"> 12 Months</button>
</div>
<div id="graph1">
</div>
</div>
</div> <!-- end row -->
<div class="row">
<div class="col-lg-12">
<div class="buttons">
<button type="button" class="btn btn-default buttons2" data-months="one" id="button30-2"> 1 Month</button>
<button type="button" class="btn btn-default selected-button buttons2" data-months="three" id="button90-2"> 3 Months</button>
<button type="button" class="btn btn-default buttons2" data-months="six" id="button180-2"> 6 Months</button>
<button type="button" class="btn btn-default buttons2" data-months="twelve" id="button360-2"> 12 Months</button>
</div>
<div id="graph2"></div>
</div></div> <!-- end row -->
  </section>	
	</div> <!-- end container -->

我已浏览了您的http://jhjanicki.github.io/reusable-line-chart/并查看了app.js第110行updateResults(first_day,last_day,product);此行将调用第一个图表,并在行号206处将alreadyClicked值设置为true,当您在第151行调用updateResults2(first_day,last_day,product);第二个图表时,“已点击”值将设置为{ {1}}之前现在其他部分将不会被执行,这次它会尝试动画,但实际上没有这样的元素存在。我们必须为每个svg维护单独的clip-path,然后我们才能实现。尝试分析代码并理解。希望这是你正在寻找的。如果没有问我:D