2013-05-05 2 views
3

CSV 파일에서 데이터를 읽고 마우스 오버 이벤트에 반응하는 여러 줄을 표시하는 d3 선 그래프를 구현했습니다. 그것은 (너무 길고 약간 어수선한 그러나 나는 그것이 최선의 전체 코드를 표시하는 생각입니다 죄송) 다음 코드를 사용하여 팬 및 줌 잘 작동 :제한된 줌을 사용하는 d3 그래프

d3.csv("ijisb.csv", function(error, data) { 

    var margin = {top: 50, right: 120, bottom: 50, left: 70}, 
    width = 1200 - margin.left - margin.right, 
    height = 800 - margin.top - margin.bottom; 

    var parseDate = d3.time.format("%m%d").parse; 

    var color = d3.scale.category20(); 

    color.domain(d3.keys(data[0]).filter(function(key) { return key !== "date"; })); 

    data.forEach(function(d) { 
     d.date = parseDate(d.date); 
    }); 

    var sources = color.domain().map(function(name) { 
     return { 
      name: name, 
      values: data.map(function(d) { 
       return {date: d.date, temperature: +d[name]}; 
      }) 
     }; 
    }); 

    var x = d3.time.scale() 
     .range([0, width]) 
     .domain([ 
     d3.min(data, function(d) { return d.date; }), 
     d3.max(data, function(d) { return d.date; }) 
    ]); 

    var y = d3.scale.linear() 
     .range([height, 0]) 
     .domain([ 
     0, 
     d3.max(sources, function(c) { return d3.max(c.values, function(v) { return v.temperature; }); }) 
    ]); 

    var xAxis = d3.svg.axis() 
     .scale(x) 
     .orient("bottom") 
     .ticks(12) 
     .tickFormat(d3.time.format("%b %d")); 

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

    var line = d3.svg.line() 
     .defined(function(d) { return d.temperature >= 0; }) 
     .x(function(d) { return x(d.date); }) 
     .y(function(d) { return y(d.temperature); }); 

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

    var svg = d3.select("body").append("svg") 
    .attr("width", "100%") 
    .attr("height", "100%") 
    .attr("viewBox", "0 0 1200 800") 
    .append("g") 
    .attr("transform", "translate(" + margin.left + "," + margin.top + ")") 
    .call(zoom); 

    var rect = svg.append("svg:rect") 
    .attr("width", width) 
    .attr("height", height) 
    .attr("class", "plot"); 

    var make_x_axis = function() { 
     return d3.svg.axis() 
      .scale(x) 
      .orient("bottom") 
      .ticks(12) 
      .tickFormat(d3.time.format("%b %d")); 
    }; 

    var make_y_axis = function() { 
     return d3.svg.axis() 
      .scale(y) 
      .orient("left") 
      .ticks(5); 
    }; 

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

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

    svg.append("g") 
     .attr("class", "x grid") 
     .attr("transform", "translate(0," + height + ")") 
     .call(make_x_axis() 
     .tickSize(-height, 0, 0) 
     .tickFormat("")); 

    svg.append("g") 
     .attr("class", "y grid") 
     .call(make_y_axis() 
     .tickSize(-width, 0, 0) 
     .tickFormat("")); 

    var source = svg.selectAll(".source") 
    .data(sources) 
    .enter().append("g") 
    .attr("class", "source"); 

    var clip = svg.append("clipPath") 
    .attr("id", "clip") 
    .append("rect") 
    .attr("x", 0) 
    .attr("y", 0) 
    .attr("width", width) 
    .attr("height", height) 
    .append("text"); 

    source.append("path") 
     .data(sources) 
     .attr("class", "line") 
     .attr("clip-path", "url(#clip)") 
     .attr("d", function(d) { return line(d.values); }) 
     .style("stroke", function(d) {return color(d.name);}) 
     .style("opacity", 0.8) 
     .on("mouseover", function(d){ 
      d3.select(this) 
       .style("stroke",function(d) {return color(d.name);}) 
       .style("opacity", 1.0) 
       .style("stroke-width", 2.5); 
       this.parentNode.parentNode.appendChild(this.parentNode); 
      d3.select('#text-' + d.name) 
       .style("fill",function(d) {return color(d.name);}) 
       .style("font-weight", 700); 
     }) 
     .on("mouseout", function(d) { 
      d3.select(this) 
       .transition() 
       .duration(250) 
       .style("stroke", function(d) {return color(d.name);}) 
       .style("stroke-width", 1.5) 
       .style("opacity", 0.8); 
      d3.select('#text-' + d.name) 
       .transition() 
       .duration(250) 
       .style("fill", function(d) {return color(d.name);}) 
       .style("font-weight", 400); 
     }) 
     .attr("id", function(d, i) { return "path-" + d.name; }); 

    source.append("text") 
     .datum(function(d) { return {name: d.name}; }) 
     .attr("x", function(d, i) { return width+10; }) 
     .attr("y", function(d, i) { return (i*(height/16)); }) 
     .style("fill", function(d) {return color(d.name);}) 
     .on("mouseover", function(d){ 
      d3.select('#path-' + d.name) 
       .style("stroke",function(d) {return color(d.name);}) 
       .style("opacity", 1.0) 
       .style("stroke-width", 2.5); 
       this.parentNode.parentNode.appendChild(this.parentNode); 
      d3.select(this) 
       .style("fill",function(d) {return color(d.name);}) 
       .style("font-weight", 700); 
     }) 
     .on("mouseout", function(d) { 
      d3.select('#path-' + d.name) 
       .transition() 
       .duration(250) 
       .style("stroke", function(d) {return color(d.name);}) 
       .style("stroke-width", 1.5) 
       .style("opacity", 0.8); 
      d3.select(this) 
       .transition() 
       .duration(250) 
       .style("fill", function(d) {return color(d.name);}) 
       .style("font-weight", 400); 
     }) 
     .text(function(d) { return d.name; }) 
     .attr("font-family","sans-serif") 
     .attr("font-size","14px") 
     .attr("id", function(d, i) { return "text-" + d.name; } 
     ); 

    var minT = new Date('01/01/1900'), maxT = new Date('01/01/2002'), w = $(window).width(); 

function zoomed() { 
     d3.event.translate; 
     d3.event.scale; 

    svg.select(".x.axis") 
     .call(xAxis); 
    svg.select(".y.axis").call(yAxis); 
    svg.select(".x.grid") 
     .call(make_x_axis() 
     .tickSize(-height, 0, 0) 
     .tickFormat("")); 
    svg.select(".y.grid") 
     .call(make_y_axis() 
     .tickSize(-width, 0, 0) 
     .tickFormat("")); 
    source.select(".line") 
     .attr("d", function(d) { return line(d.values); }) 
     .style("stroke", function(d) {return color(d.name);}); 
    } 

    }); 
내가 가진 문제는 내가 제한 할 수 있다는 것입니다

패닝 및 확대/축소 기능을 사용하여 그래프를 화면 밖으로 확대 또는 축소 할 수 없습니다. I는 (전술 한 예에서 구현 된) 줌에 scaleExtent을 설정하고, 상기 줌 기능을 변화시킴으로써이를 수행 할 수

function zoomed() { 

    var t = zoom.translate(), 

    tx = t[0]; 
    ty = t[1]; 

    tx = Math.min(tx, 0); 
    zoom.translate([tx, ty]); 

    d3.event.translate; 
    d3.event.scale; 

    svg.select(".x.axis") 
     .call(xAxis); 
    svg.select(".y.axis").call(yAxis); 
    svg.select(".x.grid") 
     .call(make_x_axis() 
     .tickSize(-height, 0, 0) 
     .tickFormat("")); 
    svg.select(".y.grid") 
     .call(make_y_axis() 
     .tickSize(-width, 0, 0) 
     .tickFormat("")); 
    source.select(".line") 
     .attr("d", function(d) { return line(d.values); }) 
     .style("stroke", function(d) {return color(d.name);}); 
} 

이 0으로 X 축 최소값을 제한한다. 그러나 열심히 노력하지만 X 축의 최대 값을 제한 할 수는 없으므로 그래프가 여전히 오른쪽으로 너무 멀리 이동할 수 있습니다.

어떤 도움이 필요합니까? 나는 이것이 의미가 있기를 바란다! 너무 높은 경우 당신은 단순히 그것을 수동으로 값을 확인하고 재설정 할 수 있습니다

답변

3

아이디 : 또한

if(tx > threshold) { tx = threshold; } 

, 문장 코드에서

d3.event.translate; 
d3.event.scale; 

는 영향을주지 않습니다.

4

덕분에 도움을, 나는 결국 다음 코드를했다 :

var t = zoom.translate(), 
s = zoom.scale(); 

tx = Math.min(0, Math.max(width * (1 - s), t[0])); 
ty = Math.min(0, Math.max(height * (1 - s), t[1])); 

zoom.translate([tx, ty]); 

어려움이 지금 해결 다양한 줌 레벨에서 그래프를 경계했다. d3.event.translate 및 d3.event.scale 문도 필요하지 않으므로 제거해야합니다.