我尝试可视化y轴值,但是在接收鼠标悬停的数据索引时遇到问题。数据的日期格式为:JJJJ-MM-TT \ Thh:mm:ss.ssZ,数据中的对象按日期排序。
d3.json("all.json", function (data) {
var margin = {top: 0, right: 0, bottom: 0, left:0}
var containerWidth = 960 - margin.left - margin.right;
var containerHeight = 500 - margin.top - margin.bottom;
// Only show temperature data
var temp_data = data.filter(
function(el)
{ return el.sensor =="Multisensor:sensormultilevel::temperaturesensor:";
}
);
var data_count = temp_data.length;
var bisectDate = d3.bisector(function(d) { return d.date; }).right;
var formatValue = d3.format(",.2f");
var formatTemperature = function(d) { return formatValue(d) + "°"; };
var minDate = Date.parse(temp_data[0].date);
var maxDate = Date.parse(temp_data[temp_data.length-1].date);
//Create time scale
var x = d3.time.scale()
.domain([minDate, maxDate])
.range([0, containerWidth]);
//Create the xAxis
var xAxis = d3.svg.axis()
.scale(x)
.orient('bottom')
.ticks(d3.time.days, 3)
.tickFormat(d3.time.format('%d.%m'))
.tickSize(3)
.tickPadding(8);
var y_max = calcMax(temp_data);
var y_min = calcMin(temp_data);
//Create temp scale
var y = d3.scale.linear()
.domain([50, y_max + 5])
.range([containerHeight, 0]);
var yAxis = d3.svg.axis()
.scale(y)
.tickSize(3)
.orient('left');
//Add svg Container
var svgContainer = d3.select("body").append("svg").attr("width", containerWidth + margin.left + margin.right).attr("height", containerHeight + margin.top + margin.bottom).append('g')
.attr("transform", "translate(" + margin.left + ", " + margin.top + ")");
//This is the accessor function for the line
var lineFunction = d3.svg.line()
.x(function(d) { return x(Date.parse(d.date)); })
.y(function(d) { return y(d.value); })
.interpolate("linear");
//Add line
var lineGraph = svgContainer.append("path")
.attr("d", lineFunction(temp_data))
.attr("stroke", "white")
.attr("stroke-width", 2)
.attr("fill", "none")
;
//Add xAxis
var xAxisGroup = svgContainer.append("g").attr("class", "xAxis").attr("transform", "translate(0, " + (containerHeight - margin.top - margin.bottom) + ")").call(xAxis);
//Add yAxis
var yAxisGroup = svgContainer.append("g").attr("class", "yAxis").call(yAxis).append("text")
.attr("transform", "rotate(-90)")
.attr("y", 6)
.attr("dy", ".71em")
.style("text-anchor", "end")
.text("Temperature in Fahrenheit");
var focus = svgContainer.append("g")
.attr("class", "focus")
.style("display", "none");
focus.append("circle")
.attr("r", 4.5);
focus.append("text")
.attr("x", 9)
.attr("dy", ".35em");
svgContainer.append("rect")
.attr("class", "overlay")
.attr("width", containerWidth)
.attr("height", containerHeight)
.on("mouseover", function() { focus.style("display", null); })
.on("mouseout", function() { focus.style("display", "none"); })
.on("mousemove", mousemove);
function mousemove() {
var x01 = x.invert(d3.mouse(this)[0]);
x0 = Date.parse(x01);
var bisect = d3.bisector(function(d) { return Date.parse(d.date); }).right;
var item = data[bisect(temp_data, x0, 1)];
console.log("item: " + item);
var i = bisectDate(temp_data, item.date, 1);
var d0 = temp_data[i - 1];
var d1 = temp_data[i];
var d = x0 - d0.date > d1.date - x0 ? d1 : d0;
console.log("x0: " + x0 + " i: " + i + " d0: " + d0 + " d1: " + d1 + "y(" + d.value + "): " + y(d.value));
focus.attr("transform", "translate(" + x(d.value) + ", " + y(d.value) + ")");
focus.select("text").text(formatTemperature(d.value));
}
});
function calcMin(d) {
var min = 0;
for (var i = 0; i < d.length; i++) {
var value = d[i].value;
if ( value <= min ) { min = value; }
}
return min;
}
function calcMax(d) {
var max = 0;
for (var i = 0; i < d.length; i++) {
var value = d[i].value;
if ( value >= max ) { max = value; }
}
return max;
}