2016-11-17 5 views
0

Я реализую гистограмму с прокруткой вдоль оси x в D3. Я написал свою функцию масштабирования и мое поведение масштабирования, но всякий раз, когда я пытаюсь скопировать вдоль моей диаграммы, значения на моей оси x просто исчезают. У кого-нибудь есть идеи, почему?D3: Перевод оси x не работает

Вот мой код:

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

function zoomed() { 
     console.log("Entered zoom function!!!"); 
    var t = zoom.translate(), 
    tx = t[0], 
    ty = t[1]; 

    tx = Math.min(tx, 0); 
    tx = Math.max(tx, w - d3.max(data, function(d) { return d.ppm_value; })); 
    zoom.translate([tx, ty]); 
    chart.select(".x.axis") 
     .call(xAxis); 
    bars.attr('transform', 'translate(' + d3.event.translate[0] + ',0) ' 
           + 'scale(' + d3.event.scale + ',1)'); 

} 

Я не могу понять, что мне не хватает. Может ли кто-нибудь мне помочь? Спасибо заранее!

//holds the data 
 
\t \t \t \t \t \t \t \t var data = [ {"yy":12,"mm":01,ppm_value:90000},   {"yy":11,"mm":02,ppm_value:50000}]; 
 

 
\t \t \t \t \t \t \t \t //formats the date 
 
\t \t \t \t \t \t \t \t var format = d3.time.format("%Y-%m-%d"); 
 
\t \t \t \t \t \t \t \t 
 
\t \t \t \t \t \t \t \t //define margins, height and width 
 
\t \t \t \t \t \t \t \t var margin = { 
 
\t \t \t \t \t \t \t \t   top: 20, 
 
\t \t \t \t \t \t \t \t   right: 30, 
 
\t \t \t \t \t \t \t \t   bottom: 30, 
 
\t \t \t \t \t \t \t \t   left: 40 
 
\t \t \t \t \t \t \t \t  }, 
 
\t \t \t \t \t \t \t \t  w = 4000 - margin.left - margin.right, 
 
\t \t \t \t \t \t \t \t  h = 500 - margin.top - margin.bottom; 
 
\t \t \t \t \t \t \t \t 
 
\t \t \t \t \t \t \t \t var x = d3.time.scale() 
 
\t \t \t \t \t \t \t \t \t .range([0, w]); 
 

 
\t \t \t \t \t \t \t \t var y = d3.scale.linear() 
 
\t \t \t \t \t \t \t \t  .range([h, 0]); 
 

 
\t \t \t \t \t \t \t \t var xAxis = d3.svg.axis() 
 
\t \t \t \t \t \t \t \t  .scale(x) 
 
\t \t \t \t \t \t \t \t  .orient("bottom") 
 
\t \t \t \t \t \t \t \t  .ticks(60) 
 
\t \t \t \t \t \t \t \t \t .tickFormat(d3.time.format("%m.%Y")); 
 

 
\t \t \t \t \t \t \t \t var yAxis = d3.svg.axis() 
 
\t \t \t \t \t \t \t \t  .scale(y) 
 
\t \t \t \t \t \t \t \t  .orient("left"); 
 
\t \t \t \t \t \t \t \t 
 
\t \t \t \t \t \t \t \t var zoom = d3.behavior.zoom() 
 
\t \t \t \t \t   \t \t .scaleExtent([1, 1]) 
 
\t \t \t \t \t   \t \t .x(x) 
 
\t \t \t \t \t   \t \t //.xExtent([d3.min(data, function(d) { return new Date(d.date); }), d3.max(data, function(d) { return new Date(d.date); })]) 
 
\t \t \t \t \t   \t \t .on("zoom", zoomed); 
 

 
\t \t \t \t \t \t \t \t //create the svg 
 
\t \t \t \t \t \t \t \t var chart = d3.select("#testChart").append("svg") 
 
\t \t \t \t \t \t \t \t  .attr("width", w + margin.left + margin.right) 
 
\t \t \t \t \t \t \t \t  .attr("height", h + margin.top + margin.bottom) 
 
\t \t \t \t \t \t \t \t  .append("g") 
 
\t \t \t \t \t \t \t \t  .attr("transform", "translate(" + margin.left + "," + margin.top + ")") 
 
\t \t \t \t \t \t \t \t \t .call(zoom); 
 
\t \t \t \t \t \t \t \t 
 
\t \t \t \t \t \t \t \t var rect = chart.append("rect") 
 
\t \t \t \t \t \t \t \t  .attr("width", w) 
 
\t \t \t \t \t \t \t \t  .attr("height", h) 
 
\t \t \t \t \t \t \t \t  .style("fill", "none") 
 
\t \t \t \t \t \t \t \t  .style("pointer-events", "all"); 
 

 
\t \t \t \t \t \t \t \t //loops through data 
 
\t \t \t \t \t \t \t \t data.forEach(function (d) { 
 
\t \t \t \t \t \t \t \t //coerce to number 
 
\t \t \t \t \t \t \t \t \t d.ppm_value = +d.ppm_value; 
 
\t \t \t \t \t \t \t \t \t d.yy = +d.yy; 
 
\t \t \t \t \t \t \t \t \t d.mm = +d.mm; 
 
\t \t \t \t \t \t \t \t \t d.date = new Date("20" + d.yy + "/" +d.mm); 
 
\t \t \t \t \t \t \t \t \t var dateTick = format(d.date); 
 
\t \t \t \t \t \t \t \t \t d.date = dateTick; 
 
\t \t \t \t \t \t \t \t \t console.log(d.ppm_value); 
 
\t \t \t \t \t \t \t \t }); 
 
\t \t \t \t \t \t \t \t 
 
\t \t \t \t \t \t \t \t //map values onto x axis 
 
\t \t \t \t \t \t \t \t x.domain([d3.min(data, function(d) { return new Date(d.date); }), d3.max(data, function(d) { return new Date(d.date); })]) 
 
\t \t \t \t \t \t \t \t 
 
\t \t \t \t \t \t \t \t //map values onto y axis 
 
\t \t \t \t \t \t \t \t y.domain([0, d3.max(data, function(d) { return d.ppm_value; })]); 
 

 
\t \t \t \t \t \t \t \t chart.append("g") 
 
\t \t \t \t \t \t \t \t  .attr("class", "x axis") 
 
\t \t \t \t \t \t \t \t  .attr("transform", "translate(0," + h + ")") 
 
\t \t \t \t \t \t \t \t  .call(xAxis) 
 

 
\t \t \t \t \t \t \t \t chart.append("g") 
 
\t \t \t \t \t \t \t \t  .attr("class", "y axis") 
 
\t \t \t \t \t \t \t \t  .call(yAxis); 
 

 
\t \t \t \t \t \t \t \t var bars = chart.append("g") 
 
\t \t \t \t \t \t \t \t  .attr("class", "chartobjects"); 
 

 
\t \t \t \t \t \t \t \t bars.selectAll(".rect") 
 
\t \t \t \t \t \t \t \t  .data(data) 
 
\t \t \t \t \t \t \t \t  .enter().append("rect") 
 
\t \t \t \t \t \t \t \t  .attr("class", "rectBar") 
 
\t \t \t \t \t \t \t \t  .on("click",hello) 
 
\t \t \t \t \t \t \t \t  .attr('x', function(d) { 
 
\t \t \t \t \t \t \t \t  \t console.log(d.date); 
 
\t \t \t \t \t \t \t \t   return x(new Date(d.date)); 
 
\t \t \t \t \t \t \t \t  }) 
 
\t \t \t \t \t \t \t \t  .attr("y", function(d) { 
 
\t \t \t \t \t \t \t \t   return y(d.ppm_value); 
 
\t \t \t \t \t \t \t \t   console.log(d.ppm_value); 
 
\t \t \t \t \t \t \t \t  }) 
 
\t \t \t \t \t \t \t \t  .attr("height", function(d) { 
 
\t \t \t \t \t \t \t \t   return h - y(d.ppm_value); 
 
\t \t \t \t \t \t \t \t  }) 
 
\t \t \t \t \t \t \t \t  .attr("width", 15) 
 
\t \t \t \t \t \t \t \t  .attr("fill", function(d) { 
 
\t \t \t \t \t \t \t \t   return d.ppm_value > 35000 ? "blue" : "red" 
 
\t \t \t \t \t \t \t \t  }); 
 

 
\t \t \t \t \t \t \t \t function hello() { 
 
\t \t \t \t \t \t \t \t  alert("Hello world!!"); 
 
\t \t \t \t \t \t \t \t } 
 

 
\t \t \t \t \t \t \t \t function zoomed() { 
 
\t \t \t \t \t \t \t \t \t console.log("Entered zoom function!!!"); 
 
\t \t \t \t \t \t \t \t \t var t = zoom.translate(), 
 
\t \t \t \t \t \t \t \t  tx = t[0], 
 
\t \t \t \t \t \t \t \t  ty = t[1]; 
 

 
\t \t \t \t \t \t \t \t tx = Math.min(tx, 0); 
 
\t \t \t \t \t \t \t \t tx = Math.max(tx, w - d3.max(data, function(d) { return d.ppm_value; })); 
 
\t \t \t \t \t \t \t \t zoom.translate([tx, ty]); 
 
\t \t \t \t \t \t \t \t chart.select(".x.axis") 
 
\t \t \t \t \t \t \t \t \t \t .call(xAxis); 
 
\t \t \t \t \t \t \t \t 
 
\t \t \t \t \t \t \t \t bars.attr('transform', 'translate(' + d3.event.translate[0] + ',0) ' 
 
\t \t \t \t \t \t \t \t \t \t + 'scale(' + d3.event.scale + ',1)'); 
 
\t \t \t \t \t \t \t \t 
 
\t \t \t \t \t \t \t \t }
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.1.0/d3.min.js"></script> 
 
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.10/angular.min.js"></script> 
 

 
<!-- Panel --> 
 
<div class="row"> 
 
    <div class="col-lg-12 col-xs-12 col-sm-12 col-md-12"> 
 
     <div class="panel panel-primary"> 
 
      <div class="panel-heading"> 
 
       Test chart done in D3 
 
      </div> 
 
\t \t \t \t <div class="panel-body"> 
 
\t \t \t \t \t <!-- <div style="overflow: scroll;"> --> 
 
\t \t \t \t \t <div id="testChart"> 
 
\t \t \t \t <!-- </div> --> 
 
\t \t \t \t </div> 
 
\t \t \t </div> 
 
\t \t </div> 
 
</div> 
 
</div>

+0

Пожалуйста, воздержитесь от открытия повторяющихся вопросов. Если ваш вопрос остается без ответа, скорее всего, он недостаточно подробен для ответа. Например, с этим вопросом вы не указали достаточно кода, чтобы кто-нибудь мог воспроизвести проблему. Фрагмент стоп-кода, plunker или jsfiddle действительно поможет. – Mark

+0

Я добавил плавный фрагмент – blaa

ответ

0

Вы должны установить .x вашей функции масштабирования после установки начального .domain. Я также рекомендую вам не прыгать назад и вперед между обработкой ваших значений x как string и date. Сделайте их дату и пойти с ним:

//map values onto x axis 
x.domain(d3.extent(data, function(d) { 
    return d.date; 
})); 
zoom.x(x); 

<!DOCTYPE html> 
 
<html> 
 

 
<head> 
 
    <link rel="stylesheet" href="style.css"> 
 
    <script src="script.js"></script> 
 
</head> 
 

 
<body> 
 
    <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.1.0/d3.min.js"></script> 
 
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.10/angular.min.js"></script> 
 

 
    <!-- Panel --> 
 
    <div class="row"> 
 
    <div class="col-lg-12 col-xs-12 col-sm-12 col-md-12"> 
 
     <div class="panel panel-primary"> 
 
     <div class="panel-heading"> 
 
      Test chart done in D3 
 
     </div> 
 
     <div class="panel-body"> 
 
      <!-- <div style="overflow: scroll;"> --> 
 
      <div id="testChart"> 
 
      <!-- </div> --> 
 
      </div> 
 
     </div> 
 
     </div> 
 
    </div> 
 
    </div> 
 

 
    <script> 
 
    //holds the data 
 
    var data = [{ 
 
     "yy": 12, 
 
     "mm": 01, 
 
     ppm_value: 90000 
 
    }, { 
 
     "yy": 11, 
 
     "mm": 02, 
 
     ppm_value: 50000 
 
    }]; 
 

 
    //formats the date 
 
    var format = d3.time.format("%Y-%m-%d"); 
 

 
    //define margins, height and width 
 
    var margin = { 
 
     top: 20, 
 
     right: 30, 
 
     bottom: 30, 
 
     left: 40 
 
     }, 
 
     w = 4000 - margin.left - margin.right, 
 
     h = 500 - margin.top - margin.bottom; 
 

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

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

 
    var xAxis = d3.svg.axis() 
 
     .scale(x) 
 
     .orient("bottom") 
 
     .ticks(60) 
 
     .tickFormat(d3.time.format("%m.%Y")); 
 

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

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

 
    //create the svg 
 
    var chart = d3.select("#testChart").append("svg") 
 
     .attr("width", w + margin.left + margin.right) 
 
     .attr("height", h + margin.top + margin.bottom) 
 
     .append("g") 
 
     .attr("transform", "translate(" + margin.left + "," + margin.top + ")") 
 
     .call(zoom); 
 

 
    var rect = chart.append("rect") 
 
     .attr("width", w) 
 
     .attr("height", h) 
 
     .style("fill", "none") 
 
     .style("pointer-events", "all"); 
 

 
    //loops through data 
 
    data.forEach(function(d) { 
 
     //coerce to number 
 
     d.ppm_value = +d.ppm_value; 
 
     d.yy = +d.yy; 
 
     d.mm = +d.mm; 
 
     d.date = new Date("20" + d.yy + "/" + d.mm); 
 
     //var dateTick = format(d.date); 
 
     //d.date = dateTick; 
 
     //console.log(d.ppm_value); 
 
    }); 
 

 
    //map values onto x axis 
 
    x.domain(d3.extent(data, function(d) { 
 
     return d.date; 
 
    })); 
 
    zoom.x(x); 
 

 
    //map values onto y axis 
 
    y.domain([0, d3.max(data, function(d) { 
 
     return d.ppm_value; 
 
    })]); 
 

 
    chart.append("g") 
 
     .attr("class", "x axis") 
 
     .attr("transform", "translate(0," + h + ")") 
 
     .call(xAxis) 
 

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

 
    var bars = chart.append("g") 
 
     .attr("class", "chartobjects"); 
 

 
    bars.selectAll(".rect") 
 
     .data(data) 
 
     .enter().append("rect") 
 
     .attr("class", "rectBar") 
 
     .on("click", hello) 
 
     .attr('x', function(d) { 
 
     console.log(d.date); 
 
     return x(new Date(d.date)); 
 
     }) 
 
     .attr("y", function(d) { 
 
     return y(d.ppm_value); 
 
     console.log(d.ppm_value); 
 
     }) 
 
     .attr("height", function(d) { 
 
     return h - y(d.ppm_value); 
 
     }) 
 
     .attr("width", 15) 
 
     .attr("fill", function(d) { 
 
     return d.ppm_value > 35000 ? "blue" : "red" 
 
     }); 
 

 
    function hello() { 
 
     alert("Hello world!!"); 
 
    } 
 

 
    function zoomed() { 
 
     console.log("Entered zoom function!!!"); 
 
     var t = zoom.translate(), 
 
     tx = t[0], 
 
     ty = t[1]; 
 

 
     tx = Math.min(tx, 0); 
 
     tx = Math.max(tx, w - d3.max(data, function(d) { 
 
     return d.ppm_value; 
 
     })); 
 
     zoom.translate([tx, ty]); 
 
     
 
     console.log(x.domain()) 
 
     
 
     chart.select(".x.axis") 
 
     .call(xAxis); 
 

 
     bars.attr('transform', 'translate(' + d3.event.translate[0] + ',0) ' + 'scale(' + d3.event.scale + ',1)'); 
 

 
    } 
 
    </script> 
 

 
</body> 
 

 
</html>

+0

Как установить пределы для оси x для панорамирования? Когда я прокручиваю направо, мои ценности идут, и они никогда не останавливаются. А также, когда я прокручиваю влево, я не хочу, чтобы по гистограмме двигались и перерисовывались. – blaa

+0

@blaa, вам нужно ввести [ограничения панорамирования] (http://bl.ocks.org/garrilla/11280861). BTW, d3 версия 4 значительно изменяет масштаб. Возможно, вам захочется подумать о переходе, поскольку эти вещи становятся намного проще. – Mark

+0

tx = Math.max (tx, d3.max (данные, функция (d) { return d.date; })); , Эта строка кода не должна указывать верхний предел на панорамирование? – blaa