2015-12-16 18 views
5

Tôi đang tạo hình ảnh hóa dòng thời gian với d3 nơi tên miền có thể thay đổi từ vài ngày đến vài thập kỷ. Tôi đang sử dụng một quy mô thời gian d3 và trục như thế này:d3.js: nhận định dạng đánh dấu từ thang thời gian

var timeScale = d3.time.scale() 
    .domain([firstEvent, lastEvent]) 
    .range([leftPadding, w - rightPadding]); 
var timeAxis = d3.svg.axis() 
    .scale(timeScale) 
    .orient("bottom"); 
timeAxis.ticks(5); 

Kể từ miền như vậy là biến, nó là thuận tiện để sử dụng ticks(x) mà sẽ tự động chọn định dạng đánh dấu. Vấn đề của tôi là trong một số trường hợp, năm không được hiển thị, điều đó là rất quan trọng. Ý tưởng của tôi là kiểm tra định dạng đánh dấu sau khi trục được tạo và nếu nó không chứa năm, hãy hiển thị nó theo cách thủ công bên cạnh trục. Tuy nhiên, tôi đã không thể có được định dạng đánh dấu của quy mô; sử dụng timeScale.tickFormat() chỉ trả về một hàm. Làm thế nào tôi có thể giải quyết vấn đề này?

+0

Bạn có thể gọi '.ticks()' mà không có bất kỳ đối số nào để có được vị trí đánh dấu. –

+0

@LarsKotthoff Có, nhưng '.ticks()' trả về các vị trí chưa được định dạng, vì vậy người ta không thể biết liệu năm đó sẽ được hiển thị trong bất kỳ nhãn nào của họ theo như tôi có thể thấy. – speedymcs

Trả lời

3

Thử nghiệm regex đơn giản như thế nào?

var hasYear = false; 
var re = /^\d{4}$/; 
// get the ticks text  
d3.selectAll('.x>.tick>text').each(function(d){ 
    // does the text look like a year? 
    var txt = this.textContent; 
    if (re.test(txt)){ 
    hasYear = true; 
    } 
}); 
console.log(hasYear); 

qua sử dụng mẫu mã này và chơi xung quanh với phạm vi khác nhau:

<!DOCTYPE html> 
 
<meta charset="utf-8"> 
 
<style> 
 

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

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

 
</style> 
 
<body> 
 
<script src="//d3js.org/d3.v3.min.js"></script> 
 
<script> 
 

 
var margin = {top: 250, right: 40, bottom: 250, left: 40}, 
 
    width = 960 - margin.left - margin.right, 
 
    height = 500 - margin.top - margin.bottom; 
 

 
var x = d3.time.scale() 
 
    .domain([new Date(2013, 12, 2), new Date(2013, 12, 6)]) 
 
    .range([0, width]); 
 

 
var xAxis = d3.svg.axis() 
 
    .scale(x) 
 
    .ticks(5); 
 

 
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 + ")"); 
 

 
svg.append("g") 
 
    .attr("class", "x axis") 
 
    .attr("transform", "translate(0," + height + ")") 
 
    .call(xAxis); 
 
    
 
xAxis.ticks().some(function(d){ 
 
    return /^\d{4}$/.exec("3434") 
 
}) 
 

 
var hasYear = false; 
 
var re = /^\d{4}$/; 
 
d3.selectAll('.x>.tick>text').each(function(d){ 
 
    var txt = this.textContent; 
 
    if (re.test(txt)){ 
 
    hasYear = true; 
 
    } 
 
}); 
 
console.log(hasYear); 
 

 

 
</script>

+0

Dường như hoạt động tốt - cảm ơn rất nhiều! Cần tìm hiểu thêm về các lựa chọn ... – speedymcs

1

trục thời gian D3 của định dạng kiểm tra xem bất kỳ ngày hiển thị trên ve trên nửa đêm, đầu tiên của tháng 1 chỉ hiển thị trong năm. Bạn có thể kiểm tra xem một năm đầy đủ sẽ được hiển thị bằng cách nhận các bọ ve và sau đó kiểm tra điều kiện này:

function isYear(t) { 
    return +t == +(new Date(t.getFullYear(), 0, 1, 0, 0, 0, 0)); 
} 
var ticks = timeScale.ticks(); 
var willDisplayYear = ticks.some(isYear); 

Hoàn thành bản demo cho cả hai trường hợp here.

+0

Cảm ơn câu trả lời của bạn, Lars. Bạn có một nguồn cho cách trục thời gian quyết định có hay không một năm được hiển thị? Nghe có vẻ rất khó với tôi, tôi nghĩ nó chỉ phụ thuộc vào phạm vi của trục. Mã cho tôi một lỗi - 't.getFullYear' không phải là một hàm. Rõ ràng nó cần phải được gọi từ một đối tượng Date. Tôi đã tạo một tài khoản đầu tiên: var date = new Date (t); ngày mới (+ t) == ngày mới (date.getFullYear(), 0, 0, 0, 0, 0, 0); Mã trả về 'sai' mặc dù một năm hiện diện trong các dấu tích. Tôi đã đánh dấu câu trả lời của Mark là chính xác vì nó có vẻ như là một giải pháp mạnh mẽ hơn. – speedymcs

+0

Ah bạn nói đúng - bạn cần sử dụng tỷ lệ cho việc này. Tôi sẽ sửa câu trả lời. –

+0

Nó vẫn trả về 'sai' mặc dù ngay cả khi có đủ năm trong các nhãn đánh dấu. Có thể phải làm với các múi giờ. – speedymcs

Các vấn đề liên quan