2015-07-17 3 views
4

Я работаю над вводным проектом в d3. Из списка, разделенного запятыми, я читаю данные формы. Я могу получить данные, чтобы показать изначально без проблем. Однако, когда я увеличиваю или уменьшаю масштаб с помощью колеса мыши, происходят две вещи:d3.js: Отвечает на увеличение колесиков мыши Соответственно

  • Этикетки оси х, которые должны быть временами, превращаются в числа, основу которых я не совсем понимаю.
  • Ярлыки оси Y, которые должны быть от 0 до 25 000 для набора данных, с которыми я работаю, превращаются в числа, похожие на те, которые отображаются на оси х.
  • Бары, которые изначально вычерчены, исчезают.

Я включил весь исходный код в нижней части этого сообщения, но я выделил элементы, которые, как я думаю, важны. Имейте в виду, что я не совсем уверен, что важно, поскольку я полный новичок для d3.

Когда событие MouseWheel получена эта функция называется

function redraw() { 
    drawAxes(); 
    redrawBars(); 
} 

drawAxes() выглядит следующим образом:

function drawAxes() { 
    chart.select(".x.axis").call(xAxis); 
    chart.select(".y.axis").call(yAxis); 
} 

redrawBars() выглядит следующим образом:

function redrawBars() { 
    chart.selectAll("g.data_bar") 
    .attr("height", function(d) { return yAxisScale(maxPval - d.pval); }) 
    .attr("transform", function(d) { return "translate(0," + yAxisScale(d.pval) + ")"; }); 
} 

Данные следующего вида: метку времени, power_val

2015-04-14 18:49:17, 14388 
2015-04-14 18:49:18, 14388 
2015-04-14 18:49:19, 14456 
2015-04-14 18:49:20, 14456 
2015-04-14 18:49:21, 14289 
2015-04-14 18:49:22, 14289 
2015-04-14 18:49:36, 16106 
2015-04-14 18:53:36, 6463 
2015-04-14 18:53:37, 6463 
2015-04-14 18:53:38, 6425 
2015-04-14 18:53:39, 6425 
2015-04-14 18:53:40, 6498 
2015-04-14 18:53:41, 3848 
2015-04-14 18:53:42, 3848 
2015-04-14 18:53:43, 3848 
2015-04-14 18:53:44, 3713 
2015-04-14 18:53:45, 3713 
2015-04-14 18:53:46, 3677 
2015-04-14 18:53:47, 3677 

Позвольте мне знать, если есть что-нибудь еще мне нужно, чтобы включить или описать. Я понимаю, что на данный момент мой код довольно уродлив.

/* 
 
* Variables with no dependence on data. 
 
*/ 
 
var barWidth = 1, 
 
    dateFormatter = d3.time.format("%Y-%m-%d %H:%M:%S"), 
 
    margin = {top: 20, right: 30, bottom: 30, left: 40}, 
 
    width = 960 - margin.left - margin.right, 
 
    height = 500 - margin.top - margin.bottom; 
 

 
/* 
 
* Variables that do depend on data. 
 
*/ 
 
var maxPval = -1; 
 

 
/* 
 
* Create scales for axes, and axes themselves 
 
*/ 
 
var xAxisScale = d3.time.scale().range([0, width]), 
 
    yAxisScale = d3.scale.linear().range([height, 0]), 
 
    xAxis = d3.svg.axis() 
 
     .scale(xAxisScale) 
 
     .orient("bottom"), 
 
    yAxis = d3.svg.axis() 
 
     .scale(yAxisScale) 
 
     .orient("left"); 
 

 
// Zoom behavior 
 
var zoom = d3.behavior.zoom() 
 
     .x(xAxisScale) 
 
     .y(yAxisScale) 
 
     .scaleExtent([0.1,1000]) 
 
     .on("zoom", zoomed); 
 

 
/* 
 
* Function called by mousewheel event listener. 
 
*/ 
 
function zoomed() { 
 
    console.log("mousewheel event received."); 
 
    redraw(); 
 
} 
 

 
// Compute space for chart. 
 
var chart = d3.select(".chart") 
 
    .attr("width", (width + margin.left + margin.right)) 
 
    .attr("height", (height + margin.top + margin.bottom)) 
 
    .attr("transform", "translate(" + margin.left + "," + margin.top + ")") 
 
    .call(zoom); 
 

 
// Add axes to page 
 
chart.append("g") 
 
    .attr("class", "x axis") 
 
    .attr("transform", "translate(" + margin.left + ", " + height + ")") 
 
    .call(xAxis); 
 
chart.append("g") 
 
    .attr("class", "y axis") 
 
    .attr("transform", "translate(" + margin.left + ", " + 0 + ")") 
 
    .call(yAxis); 
 

 
/* 
 
* Initialize axes based on times and power values passed to graph. 
 
*/ 
 
function initAxes(data) { 
 
    var xAxisExtent = d3.extent(data, function(d) { return +d.date; }); 
 
    xAxisScale.domain([new Date(xAxisExtent[0]), new Date(xAxisExtent[1])]); 
 
    yAxisScale.domain([0, d3.max(data, function(d) { return d.pval; })]); 
 
    drawAxes(); 
 
} 
 

 
/* 
 
* Re-draw the bar graph to adjust for zoom event. 
 
*/ 
 
function drawAxes() { 
 
    chart.select(".x.axis").call(xAxis); 
 
    chart.select(".y.axis").call(yAxis); 
 
} 
 

 
/* 
 
* Intialize bar graph. 
 
*/ 
 
function initBars(data) { 
 
    chart.selectAll("g.data_bar") 
 
    .data(data) 
 
    .enter() 
 
    .append("g") 
 
     .attr("transform", 
 
      function(d) { 
 
       console.log(d.date); 
 
       return "translate(" + (xAxisScale(d.date) + margin.left) + ",0)"; 
 
      }) 
 
     .attr("class", "data_bar") 
 
     .append("rect") 
 
     .attr("width", barWidth - 0.1) 
 
     .attr("height", function(d) { return yAxisScale(maxPval - d.pval); }) 
 
     .attr("transform", function(d) { return "translate(0," + yAxisScale(d.pval) + ")"; }); 
 
} 
 

 
/* 
 
* Redraw all elements on the page in response to a mousewheel event. 
 
*/ 
 
function redraw() { 
 
    drawAxes(); 
 
    redrawBars(); 
 
} 
 

 
/* 
 
* Redraw bars after scale changed by mousewheel event. 
 
*/ 
 
function redrawBars() { 
 
    chart.selectAll("g.data_bar") 
 
    .attr("height", function(d) { return yAxisScale(maxPval - d.pval); }) 
 
    .attr("transform", function(d) { return "translate(0," + yAxisScale(d.pval) + ")"; }); 
 
} 
 

 
/* 
 
* Called when reading in data file in function immediately after this. 
 
* Ensure power values are numbers not strings. 
 
* Ensure timestamps are javascript Date objects. 
 
*/ 
 
function selector(d) { 
 
    d.pval = +d["power_val"]; 
 
    d.date = dateFormatter.parse(d["timestamp"]); 
 
    return d; 
 
} 
 

 

 
// Read in data file. 
 
d3.csv("out_file", selector, function(error, data) { 
 

 
    // Check for errors. 
 
    if (error) { 
 
     console.log("error reading csv file."); 
 
     return; 
 
    } 
 

 
    // Set maxPval 
 
    maxPval = d3.max(data, function(d) { return d.pval; }); 
 
    console.log(maxPval); 
 

 
    initAxes(data); 
 
    initBars(data); 
 
});
body { 
 
    background-color: darkseagreen; 
 
} 
 

 
.chart rect { 
 
    fill: black; 
 
} 
 

 
.chart text { 
 
    fill: black; 
 
    font: 3px sans-serif; 
 
    text-anchor: start; 
 
} 
 

 
.axis text { 
 
    font: 6px sans-serif; 
 
} 
 

 
.axis path, 
 
.axis line { 
 
    fill: none; 
 
    stroke: white; 
 
    shape-rendering: crispEdges; 
 
}
<!doctype html> 
 

 
<html lang="en"> 
 
<head> 
 
    <meta charset="utf-8"> 
 
    <title>D3 Bar Chart</title> 
 
    <link rel="stylesheet" type="text/css" href="zoom_bar_chart.css"> 
 
    <script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script> 
 
</head> 
 

 
<body> 
 
    <svg class="chart"></svg> 
 
    <script src="zoom_bar_chart.js" charset="utf-8"></script> 
 
</body> 
 
</html>

ответ

2

пару вещей:

  • Вы назначаете вашу ось зума перед установкой домена. Это корень ваших проблем.
  • Вы рисуете бары странно. Переверните каждый прямоугольник в g в положение в направлении x, а затем используйте rect для установки y. Это не ломает ничего, но проще расположить прямоугольник.
  • Нельзя установить новое положение x при масштабировании.

Соответствующие изменения:

var zoom = d3.behavior.zoom() 
    .on("zoom", zoomed); 

... 

function initAxes(data) { 
    var xAxisExtent = d3.extent(data, function(d) { 
    return +d.date; 
    }); 
    xAxisScale.domain([new Date(xAxisExtent[0]), new Date(xAxisExtent[1])]); 
    yAxisScale.domain([0, d3.max(data, function(d) { 
    return d.pval; 
    })]); 
    zoom.x(xAxisScale); 
    zoom.y(yAxisScale); 
    drawAxes(); 
} 

... 

function redrawBars() { 
    chart.selectAll(".data_bar") 
    .attr("transform", function(d) { 
     return "translate("+(xAxisScale(d.date) + margin.left)+"," + yAxisScale(d.pval) + ")"; 
    }) 
    .attr("height", function(d) { 
     return (height - yAxisScale(d.pval)); 
    }); 
} 

Все вместе here.

Смежные вопросы