简体   繁体   English

D3十年时间刻度滴答作响,数据格式设置为年

[英]D3 decennial time scale ticks with data formatted as years

I'm new to D3 and JS, and I've created a (in my eyes) wonderful responsive chart with d3tips on.hover in the past couple of days. 我是D3和JS的新手,并且在过去几天中,我创建了一个(很有趣的)响应式图表,其中d3tips.hover悬停了。 It looks like this . 看起来像这样

The problem is that I've created this chart based on dummy data (which looks like this ,a count per year), and I've hard-coded the ticks on the x axis using 问题是我已经基于虚拟数据(看起来像这样 ,每年计数)创建了此图表,并且使用以下代码对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]);

This works perfectly fine, but I'd like to base my ticks on the data that I'll be importing in the future. 这可以很好地工作,但是我想在将来要导入的数据上打勾。 I'd like to dynamically generate the ticks on the x axis based on the range of years provided in my dataset (when I provide no arguments for ticks the axis looks horrible jumbled up, the numbers clearly overlap and are unreadable). 我想根据数据集中提供的年份范围在x轴上动态生成刻度线(当我没有为刻度线提供任何参数时,该轴看起来像是乱七八糟,数字显然重叠且不可读)。

There are a number of related questions here on stackoverflow, but I haven't been able to get any of the solutions to work. 关于stackoverflow,这里有许多相关的问题,但是我还无法获得任何可行的解决方案。 So far I've tried: 到目前为止,我已经尝试过:

.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).

I feel like I'm stuck here, and I'm starting to think of way too complicated workarounds for what feels like a simple problem. 我觉得自己被困在这里,并且我开始考虑对于一个简单的问题来说过于复杂的解决方法。 Does anyone have an idea? 有人有主意吗?

The complete .js code as a stack snippet: 完整的.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) { dN = dN; return d; } 
 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; } 
 <!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> 

The reason that you're having issues is because you're setting the tickValues() manually. 您遇到问题的原因是因为您正在手动设置tickValues() If you read the documentation for axis.tickValues then you'll see that: 如果您阅读axis.tickValues的文档,则会看到:

If a values array is specified, the specified values are used for ticks, rather than using the scale's automatic tick generator. 如果指定了值数组,则将指定的值用于刻度,而不是使用刻度的自动刻度生成器。

So what you need to do is remove that call to tickValues() . 因此,您需要做的是删除对tickValues()调用。 Something like: 就像是:

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

Since you are using ordinal scale you will have to to give tick values. 由于您正在使用序数标度,因此您必须提供刻度值。

But you can restrict the tickValues to 10 ticks like this dynamically with your data. 但是您可以通过数据动态地将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

working code here 这里的工作代码

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM