D3十年时间刻度,数据格式为年

时间:2016-04-21 11:18:49

标签: javascript d3.js

我是D3和JS的新手,我在过去的几天里创建了一个(在我看来)精彩的响应图表和d3tips on.hover。它看起来像this

问题是我已经根据虚拟数据(看起来像this创建了这个图表,每年计算一次),并且我已经对x轴上的刻度进行了硬编码使用

var x = d3.scale.ordinal()
.rangeRoundBands([0, width], 0.1);

var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom")
.tickValues([1910, 1920, 1930, 1940, 1950, 1960, 1970, 1980, 1990, 2000, 2010, 2020]);

这非常合适,但我想根据我将来要导入的数据。我想根据我的数据集中提供的年份范围动态生成x轴上的刻度线(当我没有为刻度线提供任何参数时,轴看起来很糟糕,数字明显重叠并且不可读)。 / p>

这里有关于stackoverflow的一些相关问题,但我还没有能够让任何解决方案起作用。到目前为止,我已经尝试过:

.ticks(10); //To set the amount of ticks to 10, and have d3 determine which ones they should be. This changed nothing compared to not providing any tick properties.
d3.time.scale(); //This completely removed the x axis. I thought this was because my data wasn't in the correct format, but I'm not sure and I haven't found a way to fix this (I tried Date(x_data) but this didn't solve the problem).

我觉得我已经被困在这里了,而且我开始想到一个过于复杂的解决方法,感觉就像一个简单的问题。有没有人有想法?

完整的.js代码作为堆栈代码:



"use strict";
// Hierin worden de marges en grootte van het element vastgesteld.
var margin = {
    top: 120,
    right: 40,
    bottom: 60,
    left: 80
}
  , 
width = 960 - margin.left - margin.right
  , 
height = 500 - margin.top - margin.bottom;

// Het type schaal van de x as.
var x = d3.scale.ordinal()
.rangeRoundBands([0, width], 0.1);

// Het type schaal van de y as.
var y = d3.scale.linear()
.range([height, 0]);

//X as:     .tickValues moeten nog gebaseerd worden op de data ipv hard-coded.
//          Evt lijn tekenen boven de x as.
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom")
//.ticks(10); // Doesn't work.
.tickValues([1910, 1920, 1930, 1940, 1950, 1960, 1970, 1980, 1990, 2000, 2010, 2020]);

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

//on.hover is dit de box die omhoog komt. Tekst (hier d.Jaar & d.Aantal) moet aangepast worden naar de soort chart.
var tip = d3.tip()
.attr('class', 'd3-tip')
.offset([-10, 0])
.html(function(d) {
    return "<strong>Jaar:</strong> <span style='color: #DA6A26'>" + d.Jaar + "</span>" + "<br></br>" + "<strong>Aantal:</strong> <span style='color: #DA6A26'>" + d.Aantal + "</span>";
});

//Responsive svg
var svg = d3.select("body").append("svg")
.attr("width", '50%')
.attr("height", '50%')
.attr('viewBox','0 0 '+Math.max(width,height)+' '+Math.max(width,height))
.attr('preserveAspectRatio','xMinYMin')
.append("g")
.attr("transform", "translate(" + Math.min(width,height) / 10 + "," + Math.min(width,height) / 5 + ")");

// Voer de functie uit die verantwoordelijk is voor het weergeven van de 'tip'.
svg.call(tip);

// d3.tsv functie moet vervangen worden door JSON object uit export van GEOSERVER.
d3.tsv("http://127.0.0.1:8080/sortdate.tsv", type, function(error, data) {
    x.domain(data.map(function(d) {
        return String(d.Jaar);
    }));
    y.domain([0, d3.max(data, function(d) {
        return Number(d.Aantal);
    })]);
    
    svg.append("g")
    .attr("class", "x axis")
    .attr("transform", "translate(0," + height + ")")
    .call(xAxis);
    
    svg.append("g")
    .attr("class", "y axis")
    .call(yAxis)
    .append("text")
    .attr("transform", "rotate(-90)")
    .attr("y", 6)
    .attr("dy", ".71em")
    .style("text-anchor", "end")
    .text("Aantal"); // Tekst bij de y as.
    
    svg.selectAll(".bar")
    .data(data)
    .enter().append("rect")
    .attr("class", "bar")
    .attr("x", function(d) {
        return x(d.Jaar);
    })
    .attr("width", x.rangeBand())
    .attr("y", function(d) {
        return y(d.Aantal);
    })
    .attr("height", function(d) {
        return height - y(d.Aantal);
    })
    .on('mouseover', tip.show)
    .on('mouseout', tip.hide);

});

// Teken de chart.
function type(d) {
    d.N = d.N;
    return d;
}
&#13;
body {
  font: 10px sans-serif;
}

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

.bar {
  fill: #0D4B84;
}

.bar:hover {
  fill: #DA6A26;
}

.x.axis path {
  display: none;
}

.d3-tip {
  line-height: 1;
  font-weight: bold;
  padding: 12px;
  background: #FFFFFF;
  color: #000000;
  border-radius: 2px;
  border-style: solid;
  border-width: 1px;
}

/* Creates a small triangle extender for the tooltip */
.d3-tip:after {
  box-sizing: border-box;
  display: inline;
  font-size: 10px;
  width: 100%;
  line-height: 1;
  color: rgba(0, 0, 0, 0.8);
  content: "\25BC";
  position: absolute;
  text-align: center;
}

/* Style northward tooltips differently */
.d3-tip.n:after {
  margin: -1px 0 0 0;
  top: 100%;
  left: 0;
}
&#13;
<!DOCTYPE html>
<html >
  <head>
    <meta charset="UTF-8">
    <title>D3 Bar Chart</title>
        <link rel="stylesheet" href="css/style.css">
    <script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
    <script src="http://labratrevenge.com/d3-tip/javascripts/d3.tip.v0.6.3.js"></script>
  </head>

  <body>
    <h1>Responsive barchart</h1>
    <div class="chart"></div>

    <script src="js/index.js"></script>
    
  </body>
</html>
&#13;
&#13;
&#13;

2 个答案:

答案 0 :(得分:1)

您遇到问题的原因是您手动设置tickValues()。如果您阅读了axis.tickValues的文档,那么您会看到:

  

如果指定了数值数组,则指定的值用于刻度,而不是使用刻度的自动刻度生成器。

所以你需要做的是删除对tickValues()的调用。类似的东西:

var xAxis = d3.svg.axis().scale(x).orient("bottom");
d3.select("svg").append("g").call(xAxis);

答案 1 :(得分:1)

由于您使用的是序数比例,因此您必须提供刻度值。

但是你可以用你的数据动态地将tickValues限制为10个滴答。

var mod = Math.ceil(x.domain().length/10);
var values = [];//put the ticks in values array
x.domain().forEach(function(d, i){
  if (i%mod ==0){
    values.push(d)
  }
})
xAxis.tickValues(values);//this will have 10 ticks

工作代码here