2016-01-01 4 views
0

У меня есть некоторые проблемы с моей визуализацией d3. Я пытаюсь сделать линейную диаграмму, которая показывает разработку более 15 лет.Линия линейной диаграммы zoom

Первая проблема заключается в том, что ось x не масштабируется в зависимости от масштабирования. Я использовал это для начала: http://bl.ocks.org/mbostock/4dc8736fb1ce9799c6d6 Но я не знаю, почему моя ось не масштабируется.

Во-вторых, маркировка оси не так, она должна быть неделя и год (eg01-2016)

И последнее: Какие у меня есть, если есть какие-то данные отсутствуют, например, в данные за 2013 год? Могу ли я переломить диаграмму, так что в этом году есть просто пробел?

Вот HTML

<!doctype html> 
<html> 
    <head> 
    <link rel="stylesheet" href="main.css"> 
    <script src="//d3js.org/d3.v3.min.js"></script> 
    <title>Test Tool</title> 
    </head> 

    <body> 
    <!--MAIN--> 
    <main> 

    <!--LINE CHART --> 
    <script> 
    // Set the dimensions of the canvas/graph 
    var margin = {top: 10, right: 20, bottom: 30, left: 50}, 
     width = 1000 - margin.left - margin.right, 
     height = 570 - margin.top - margin.bottom; 

    // Set the ranges 
    var x = d3.time.scale().domain([-width/2, width/2]) 
     .range([0, width]); 
    var y = d3.scale.linear().domain([-height/2, height/2]) 
     .range([height, 0]); 


    // Define the axes 
    var xAxis = d3.svg.axis().scale(x) 
     .orient("bottom").ticks(10); 

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

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

    var drag = d3.behavior.drag() 
     .origin(function(d) { return d; }) 
     .on("dragstart", dragstarted) 
     .on("drag", dragged) 
     .on("dragend", dragended); 

    var area = d3.svg.area() 
     .x(function(d) { return x(d.meldewoche); }) 
     .y0(height) 
     .y1(function(d) { return y(d.faelle); }) 
     .interpolate("basis"); 

    var areaflip = d3.svg.area() 
     .x(function(d) { return x(d.meldewoche); }) 
     .y0(height) 
     .y1(function(d) { return y(-d.faelle); }) 
     .interpolate("basis"); 

    // Define the line 
    var valueline = d3.svg.line() 
     .x(function(d) { return x(d.meldewoche); }) 
     .y(function(d) { return y(d.faelle); }) 
     .interpolate("basis"); 

    var valuelineflip = d3.svg.line() 
     .x(function(d) { return x(d.meldewoche); }) 
     .y(function(d) { return y(-d.faelle); }) 
     .interpolate("basis"); 

    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 container = svg.append("g"); 

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

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

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

    // Get the data 
    d3.csv("data-hanta-gesamt.csv", function(error, data) { 
     data.forEach(function(d) { 
      // Parse the date/time 
      var parseDate = d3.time.format("%W-%Y").parse; 
      d.meldewoche = parseDate(d.meldewoche); 
      d.faelle = +d.faelle; 
     }); 

    // Scale the range of the data 
    x.domain(d3.extent(data, function(d) { return d.meldewoche; })); 
    y.domain([0, d3.max(data, function(d) { return d.faelle+550; })]); 

    // Add the valueline path. 
    container.append("path") 
      .attr("class", "line") 
      .attr("d", valueline(data)) 
      .attr("transform", "translate(0,-265)"); 
    container.append("path") 
      .attr("class", "lineflip") 
      .attr("d", valuelineflip(data)) 
      .attr("transform", "translate(0,-265)"); 

    container.append("path") 
      .datum(data) 
      .attr("class", "area") 
      .attr("d", area) 
      .attr("transform", "translate(0,-265)"); 
    container.append("path") 
      .datum(data) 
      .attr("class", "areaflip") 
      .attr("d", areaflip) 
      .attr("transform", "translate(0,-265)"); 

    }); 


    //ZOOM 
    function zoomed() { 
     container.select(".x axis").call(xAxis); 
     container.select(".y axis").call(yAxis); 
     //svg.selectAll('.line').attr('d', line) 
     container.attr("transform", "translate(" + d3.event.translate[0] + ",0)scale(" + d3.event.scale + ",1)"); 

    } 

    function dragstarted(d) { 
     d3.event.sourceEvent.stopPropagation(); 
     d3.select(this).classed("dragging", true); 
    } 

    function dragged(d) { 
     d3.select(this) 
      .attr("cx", d.x = d3.event.x) 
      .attr("cy", d.y = d3.event.y); 
    } 

    function dragended(d) { 
     d3.select(this).classed("dragging", false); 
    } 


    </script> 
    </main>  
    </body> 
</html> 

И CSS:

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

meldewoche,faelle 
01-2001,2 
03-2001,1 
04-2001,2 
05-2001,2 
07-2001,1 
08-2001,6 
09-2001,1 
... 

ответ

0

Вам просто нужно небольшими изменениями для решения проблем, связанных упоминается.

  1. Выпуск 1: ось х не масштабируется в ответ на увеличение. Проблема, с которой вы сталкиваетесь, связана с тем, как вы обновляете оси x и y в zoomed. В частности, ваш текущий код пытается выбрать ось из container:

    container.select(".x axis").call(xAxis); 
    container.select(".y axis").call(yAxis); 
    

    Однако оси детей не container. Кроме того, вы заменили ., необходимые для выбора осей по оси «оси» с пробелом. Если вместо этого вы выбрали ось как дети svg и установив селектор класса правильно, то ваше поведение зума будет работать:

    svg.select(".x.axis").call(xAxis); 
    svg.select(".y.axis").call(yAxis); 
    
  2. Выпуск 2: Разметка оси х неправильно. Эта проблема связана с тем фактом, что вы добавляете по оси x до, загружая ваши данные. Таким образом, область оси x не была задана с использованием дат ваших данных.

    Решение этой проблемы заключается в перемещении всего кода, который опирается на ось x в ваш d3.csv. Таким образом, при добавлении оси или даже при масштабировании область шкалы x для оси x уже настроена правильно. Вот обновленный Javascript, который работает на меня.

// Установить размеры холста/график края вара = { сверху: 10, справа: 20, снизу: 30, слева: 50 }, ширины = 1000 - рентабельность .left - margin.right, height = 570 - margin.top - margin.bottom;

// Set the ranges 
var x = d3.time.scale().domain([-width/2, width/2]) 
    .range([0, width]); 
var y = d3.scale.linear().domain([-height/2, height/2]) 
    .range([height, 0]); 

// Define the axes 
var xAxis = d3.svg.axis().scale(x) 
    .orient("bottom").ticks(10); 

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

// Get the data 
d3.csv("data-hanta-gesamt.csv", function(error, data) { 
    data.forEach(function(d) { 
    // Parse the date/time 
    var parseDate = d3.time.format("%W-%Y").parse; 
    d.meldewoche = parseDate(d.meldewoche); 
    d.faelle = +d.faelle; 
    }); 


    var drag = d3.behavior.drag() 
    .origin(function(d) { 
     return d; 
    }) 
    .on("dragstart", dragstarted) 
    .on("drag", dragged) 
    .on("dragend", dragended); 

    var area = d3.svg.area() 
    .x(function(d) { 
     return x(d.meldewoche); 
    }) 
    .y0(height) 
    .y1(function(d) { 
     return y(d.faelle); 
    }) 
    .interpolate("basis"); 

    var areaflip = d3.svg.area() 
    .x(function(d) { 
     return x(d.meldewoche); 
    }) 
    .y0(height) 
    .y1(function(d) { 
     return y(-d.faelle); 
    }) 
    .interpolate("basis"); 

    // Define the line 
    var valueline = d3.svg.line() 
    .x(function(d) { 
     return x(d.meldewoche); 
    }) 
    .y(function(d) { 
     return y(d.faelle); 
    }) 
    .interpolate("basis"); 

    var valuelineflip = d3.svg.line() 
    .x(function(d) { 
     return x(d.meldewoche); 
    }) 
    .y(function(d) { 
     return y(-d.faelle); 
    }) 
    .interpolate("basis"); 

    // Scale the range of the data 
    x.domain(d3.extent(data, function(d) { 
    return d.meldewoche; 
    })); 
    y.domain([0, d3.max(data, function(d) { 
    return d.faelle + 550; 
    })]); 

    var zoom = d3.behavior.zoom() 
    .x(x) 
    .y(y) 
    .scaleExtent([1, 10]) 
    .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 container = svg.append("g"); 

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

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

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

    // Add the valueline path. 
    container.append("path") 
    .attr("class", "line") 
    .attr("d", valueline(data)) 
    .attr("transform", "translate(0,-265)"); 
    container.append("path") 
    .attr("class", "lineflip") 
    .attr("d", valuelineflip(data)) 
    .attr("transform", "translate(0,-265)"); 

    container.append("path") 
    .datum(data) 
    .attr("class", "area") 
    .attr("d", area) 
    .attr("transform", "translate(0,-265)"); 
    container.append("path") 
    .datum(data) 
    .attr("class", "areaflip") 
    .attr("d", areaflip) 
    .attr("transform", "translate(0,-265)"); 


    //ZOOM 
    function zoomed() { 
    svg.select(".x.axis").call(xAxis); 
    svg.select(".y.axis").call(yAxis); 
    //svg.selectAll('.line').attr('d', line) 
    container.attr("transform", "translate(" + d3.event.translate[0] + ",0)scale(" + d3.event.scale + ",1)"); 

    } 

    function dragstarted(d) { 
    d3.event.sourceEvent.stopPropagation(); 
    d3.select(this).classed("dragging", true); 
    } 

    function dragged(d) { 
    d3.select(this) 
     .attr("cx", d.x = d3.event.x) 
     .attr("cy", d.y = d3.event.y); 
    } 

    function dragended(d) { 
    d3.select(this).classed("dragging", false); 
    } 
}); 
+0

Большое спасибо за помощь.Но я думаю, что есть еще одна проблема с масштабированием. Он работает, но метки оси просто становятся больше (размер шрифта становится больше). Это не работает, как в примере, когда метки оси меняются. Аналогичная проблема с самой линией, ширина штриха увеличивается, но я хочу иметь более подробный график с одним и тем же штрихом. Надеюсь, это объяснит проблему достаточно хорошо. – Valentina

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