2015-11-27 2 views
1

Я сделал сюжет с d3js и потому, что функция графика выходит за пределы участка, который я хотел закрепить. В то же время я также подумал о масштабировании. Поэтому я начал применять следующий код в своем коде; http://bl.ocks.org/mbostock/3892919d3js увеличить в сюжет

К сожалению, похоже, что моя реализация неверна. Мои метки оси x и y, похоже, исчезают + фон становится черным + фактический график отсутствует, пока вы не попытаетесь увеличить масштаб: S.

Решение, как исправить, т. Е. Правильно выполнить это задание. Далее я также открыт для улучшения моего кода.

Jsfiddle версии с зумом: http://jsfiddle.net/n3Lndkum/12/ Jsfiddle из последней рабочей версии: http://jsfiddle.net/n3Lndkum/9/

Embedded версии:

var margin = {top: 20, right: 20, bottom: 50, left: 50}, 
 
    width = 250 - margin.left - margin.right, 
 
    height = 250 - margin.top - margin.bottom, 
 
    padding = 50; 
 

 
var x = d3.scale.linear() 
 
    .range([0, width]) 
 
    .domain([0, 10]); 
 

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

 
var xAxis = d3.svg.axis() 
 
    .scale(x) 
 
    .orient("bottom") 
 
    .ticks(5) 
 
\t .innerTickSize(-6) 
 
\t .outerTickSize(0) 
 
\t .tickPadding(7); 
 

 
var yAxis = d3.svg.axis() 
 
    .scale(y) 
 
    .orient("left") 
 
    .ticks(5) 
 
\t .innerTickSize(-6) 
 
\t .outerTickSize(0) 
 
\t .tickPadding(7); 
 

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

 
var data = []; 
 

 
for (var k = -100; k < 101; k++) { 
 
    data.push({x: k/10, y: 0.5*k*k/100}); 
 
} 
 

 
var line = d3.svg.line() 
 
    .x(function(d) { return x(d.x); }) 
 
    .y(function(d) { return y(d.y); }) 
 
    .interpolate("linear"); 
 

 
var svg = d3.select("body").append("svg") 
 
    .attr("width", width + margin.left + margin.right) 
 
    .attr("height", height + margin.top + margin.bottom) 
 
    .append("g") 
 
    .attr("transform", "translate(" + margin.left + "," + margin.top + ")") 
 
    .call(zoom); 
 

 
svg.append("rect") 
 
    .attr("width", width) 
 
    .attr("height", height); 
 

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

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

 
/* append additional X axis */ 
 
svg.append("g") 
 
\t .attr("class", "axis") 
 
\t .attr("transform", "translate(" + [0, 0] + ")") 
 
\t .call(xAxis.innerTickSize(6).tickPadding(-20).tickFormat("")); 
 

 
/* append additional y axis */ 
 
svg.append("g") 
 
\t .attr("class","y axis") 
 
\t .attr("transform", "translate(" + [width, 0] + ")") 
 
\t .call(yAxis.innerTickSize(6).tickPadding(-20).tickFormat("")); 
 

 
// Add x axis label 
 
svg.append("text") 
 
\t .attr("transform", "translate(" + (width/2) + "," + (height + margin.bottom) + ")") 
 
\t .style("font-size","15") 
 
\t .style("text-anchor", "middle") 
 
\t .text("x axis"); 
 

 
// Add y axis label 
 
svg.append("text") 
 
\t .attr("transform", "rotate(-90)") 
 
\t .attr("y",0 - margin.left) 
 
\t .attr("x",0 - (height/2)) 
 
\t .attr("dy", "1em") 
 
\t .style("font-size","15") 
 
\t .style("text-anchor", "middle") 
 
\t .text("y axis"); 
 

 
// Add x grid 
 
svg.append("g")   
 
\t .attr("class","grid") 
 
\t .attr("transform","translate(0," + height + ")") 
 
\t .call(xAxis 
 
     .tickSize(-height,-height,0) 
 
\t \t .tickFormat("") 
 
     ); 
 

 
// Add y grid 
 
svg.append("g")   
 
\t .attr("class","grid") 
 
\t .call(yAxis 
 
\t \t .tickSize(-width,-width,0) 
 
\t \t .tickFormat("") 
 
\t); 
 

 
function zoomed() { 
 
\t svg.select(".x.axis").call(xAxis); 
 
    \t svg.select(".y.axis").call(yAxis); 
 
    
 
    // Add data 
 
    svg.append("path") 
 
     .attr("class","line") 
 
     .attr("d",line(data)); 
 
    
 
}
body { 
 
    font: 10px sans-serif; 
 
} 
 

 
.axis path, 
 
.axis line { 
 
    fill: none; 
 
    stroke: #000; 
 
    shape-rendering: crispEdges; 
 
} 
 

 
.line { 
 
    fill: none; 
 
    stroke: steelblue; 
 
    stroke-width: 1.5px; 
 
} 
 

 
.grid .tick { 
 
    stroke: lightgrey; 
 
    opacity: 0.7; 
 
} 
 

 
.grid path { 
 
    stroke-width: 0; 
 
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>

+0

ждать, вы хотите, чтобы перемещаться, изменяя диапазон ху, или делать вы хотите уменьшить масштаб, как приращения того, что будет 2 be 4 then 6 и т. д.? Также преднамеренно, чтобы случайный путь появлялся на мыши? – Pete

+0

Как панорамирование, так и масштабирование, и даже с шагом. Я рассмотрел эту часть, используя «.scaleExtent ([0.1, 32])», если я прав. Кроме того, если это возможно, я хочу только панорамировать, пока график не окажется на границе графика, поэтому вы не можете панорамировать дальше, чем данные. «Случайным» путем является график x^2. Моя логика сказала мне, что, поскольку вы увеличиваете масштаб изображения, нужно перерисовывать каждый раз, поэтому я помещаю эту часть в увеличенную функцию. –

+0

Я как бы понимаю, о чем вы говорите. Но без сомнения, если панорамировать или масштабировать график нужно перерисовать, поэтому при каждом перерисовании вы также перерисовываете путь. – Pete

ответ

2

Немногие вещи здесь:

1 .) Вы не применяете клип-путь к линия. Вот почему он переполняет сетку.

2.) Ваша сетка черная, потому что вы добавили к ней rect (чтобы он мог получать события мыши панорамирования/масштабирования), но вы не устанавливаете его заливку на что-то (по умолчанию это черный). Обратите внимание, что вы не можете установить его заполнить до тех пор, пока он не получит события мыши.

3.) Вы не должны разделять определение оси, как вы делаете:

.call(xAxis.innerTickSize(6).tickPadding(-20).tickFormat("")); 

Сковороду и функциональность масштабирования будет необходимо перерисовать ось (ов) и сетки (ы), сохранить ссылку на каждый созданный вами.

4.) В вашем событии масштабирования не добавляйте новую строку повторно. Выберите существующий и обновить свои данные:

d3.select(".line") 
    .attr("d", line(data)); 

Сведя все это вместе:

<!DOCTYPE html> 
 
<meta charset="utf-8"> 
 
<title>Zoom + Pan</title> 
 
<style> 
 
    svg { 
 
    font: 10px sans-serif; 
 
    shape-rendering: crispEdges; 
 
    } 
 
    
 
    rect { 
 
    fill: transparent; 
 
    } 
 
    
 
    .axis path, 
 
    .axis line { 
 
    fill: none; 
 
    stroke: #000; 
 
    shape-rendering: crispEdges; 
 
    } 
 
    
 
    .line { 
 
    fill: none; 
 
    stroke: steelblue; 
 
    stroke-width: 1.5px; 
 
    clip-path: url(#clip); 
 
    } 
 
    
 
    .grid .tick { 
 
    stroke: lightgrey; 
 
    opacity: 0.7; 
 
    } 
 
    
 
    .grid path { 
 
    stroke-width: 0; 
 
    } 
 
</style> 
 

 
<body> 
 
    <script src="//d3js.org/d3.v3.min.js"></script> 
 
    <script> 
 
    var margin = { 
 
     top: 20, 
 
     right: 20, 
 
     bottom: 30, 
 
     left: 40 
 
     }, 
 
     width = 600 - margin.left - margin.right, 
 
     height = 500 - margin.top - margin.bottom; 
 

 
    var x = d3.scale.linear() 
 
     .domain([0, 10]) 
 
     .range([0, width]); 
 

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

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

 
    var svg = d3.select("body").append("svg") 
 
     .attr("width", width + margin.left + margin.right) 
 
     .attr("height", height + margin.top + margin.bottom) 
 
     .append("g") 
 
     .attr("transform", "translate(" + margin.left + "," + margin.top + ")") 
 
     .call(zoom); 
 

 
    var xAxis1 = d3.svg.axis() 
 
     .scale(x) 
 
     .orient("bottom") 
 
     .ticks(5) 
 
     .innerTickSize(-6) 
 
     .outerTickSize(0) 
 
     .tickPadding(7); 
 

 
    var yAxis1 = d3.svg.axis() 
 
     .scale(y) 
 
     .orient("left") 
 
     .ticks(5) 
 
     .innerTickSize(-6) 
 
     .outerTickSize(0) 
 
     .tickPadding(7); 
 

 
    var xAxis2 = d3.svg.axis() 
 
     .scale(x) 
 
     .orient("top") 
 
     .ticks(5) 
 
     .innerTickSize(6) 
 
     .tickPadding(-20) 
 
     .tickFormat(""); 
 

 
    var yAxis2 = d3.svg.axis() 
 
     .scale(y) 
 
     .orient("left") 
 
     .ticks(5) 
 
     .innerTickSize(6) 
 
     .tickPadding(-20) 
 
     .tickFormat(""); 
 

 
    var xGrid = d3.svg.axis() 
 
     .scale(x) 
 
     .orient("bottom") 
 
     .tickSize(-height, -height, 0) 
 
     .tickFormat(""); 
 

 
    var yGrid = d3.svg.axis() 
 
     .scale(y) 
 
     .orient("left") 
 
     .ticks(5) 
 
     .tickSize(-width, -width, 0) 
 
     .tickFormat(""); 
 
     
 
    // Add x grid 
 
    svg.append("g") 
 
     .attr("class", "x grid") 
 
     .attr("transform", "translate(0," + height + ")") 
 
     .call(xGrid); 
 

 
    // Add y grid 
 
    svg.append("g") 
 
     .attr("class", "y grid") 
 
     .call(yGrid); 
 

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

 
    svg.append("g") 
 
     .attr("class", "y1 axis") 
 
     .call(yAxis1); 
 

 
    /* append additional X axis */ 
 
    svg.append("g") 
 
     .attr("class", "x2 axis") 
 
     .attr("transform", "translate(" + [0, 0] + ")") 
 
     .call(xAxis2); 
 

 
    /* append additional y axis */ 
 
    svg.append("g") 
 
     .attr("class", "y2 axis") 
 
     .attr("transform", "translate(" + [width, 0] + ")") 
 
     .call(yAxis2); 
 

 
    svg.append("defs").append("clipPath") 
 
     .attr("id", "clip") 
 
     .append("rect") 
 
     .attr("width", width) 
 
     .attr("height", height); 
 
     
 
    svg.append("rect") 
 
     .attr("width", width) 
 
     .attr("height", height); 
 

 
    var data = []; 
 

 
    for (var k = -100; k < 101; k++) { 
 
     data.push({ 
 
     x: k/10, 
 
     y: 0.5 * k * k/100 
 
     }); 
 
    } 
 

 
    var line = d3.svg.line() 
 
     .x(function(d) { 
 
     return x(d.x); 
 
     }) 
 
     .y(function(d) { 
 
     return y(d.y); 
 
     }) 
 
     .interpolate("linear"); 
 

 
    svg.append("path") 
 
     .attr("class", "line") 
 
     .attr("d", line(data)) 
 

 
    function zoomed() { 
 
     svg.select(".x1.axis").call(xAxis1); 
 
     svg.select(".y1.axis").call(yAxis1); 
 
     svg.select(".x2.axis").call(xAxis2); 
 
     svg.select(".y2.axis").call(yAxis2); 
 
     svg.select(".x.grid").call(xGrid); 
 
     svg.select(".y.grid").call(yGrid); 
 

 
     d3.select(".line") 
 
     .attr("d", line(data)); 
 
    } 
 
    </script>