我正在用多条线填充图表并尝试访问最高值,然后每隔几秒递增一次。我不确定使用什么语法来分别访问每一行......
索引.html:
function generateVisualization(data){
//className for first timeline
var className = "ch1Class";
data.forEach(function(d) {
d.date = parseDate(d.date);
d.price = +d.price; // + ensures its an integer
});
maxY = d3.max(data.map(function(d) { return d.price; }));
obj[className] = maxY;
maxX = d3.max(data.map(function(d) { return d.date; }));
objD[className] = maxX;
x.domain(d3.extent(data.map(function(d) { return Math.max(d.date); })));
y.domain([0, d3.max(data.map(function(d) { return Math.max(d.price); }))]);
x2.domain(x.domain());
y2.domain(y.domain());
focus.append("path")
.datum(data)
.attr("clip-path", "url(#clip)")
.attr("d", area)
.attr("class", className);
//make sure the first textbox is selected in the channel selection
$("#demo_box_1").attr("checked","checked");
focus.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
focus.append("g")
.attr("class", "y axis")
.call(yAxis);
context.append("path")
.datum(data)
.attr("class", className)
.attr("d", area2);
context.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height2 + ")")
.call(xAxis2);
context.append("g")
.attr("class", "x brush")
.call(brush)
.selectAll("rect")
.attr("y", -6)
.attr("height", height2 + 7);
}
<!-- time series start -->
var margin = {top: 10, right: 10, bottom: 100, left: 40},
margin2 = {top: 430, right: 10, bottom: 20, left: 40},
width = 960 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom,
height2 = 500 - margin2.top - margin2.bottom;
var parseDate = d3.time.format("%b %Y").parse;
//var parseDate = d3.time.format("%x %X.%L").parse;
var x = d3.time.scale().range([0, width]),
x2 = d3.time.scale().range([0, width]),
y = d3.scale.linear().range([height, 0]),
y2 = d3.scale.linear().range([height2, 0]);
var xAxis = d3.svg.axis().scale(x).orient("bottom"),
xAxis2 = d3.svg.axis().scale(x2).orient("bottom"),
yAxis = d3.svg.axis().scale(y).orient("left");
var brush = d3.svg.brush()
.x(x2)
.on("brush", brushed);
var area = d3.svg.area()
.interpolate("monotone")//smooths path corners
.x(function(d) { return x(d.date); })
.y0(height)
.y1(function(d) { return y(d.price); });
var area2 = d3.svg.area()
.interpolate("monotone")//smooths path corners
.x(function(d) { return x2(d.date); })
.y0(height2)
.y1(function(d) { return y2(d.price); });
var svg = d3.select("#maincontent1").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.attr("class", "timeLine");
svg.append("defs").append("clipPath")
.attr("id", "clip")
.append("rect")
.attr("width", width)
.attr("height", height);
var focus = svg.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
var context = svg.append("g")
.attr("transform", "translate(" + margin2.left + "," + margin2.top + ")");
var dataset; //global variable
d3.csv("ch1.csv", function(error, data) {
dataset = data;
generateVisualization(data);
});
<!-- time series end -->
</script>
</div><!-- end #maincontent -->
包含的js文件:
//create an object to track max y values
var obj = {};
var objD = {};
// if adding/removing paths check max values and rescale if necessary
function maxValue(maxY,maxX,addRemove,className){
//if adding and its not in the array yet, then add to array, then check to see if its got the highest yvalue, if so updateaxis
if(addRemove=="add"){
if((className in obj )!=true){
// add new class/max value to an object
obj[className] = maxY;
objD[className] = maxY;
//check to see if its the highest yvalue in the object and if so, rescale
var max = 0;
for(var i in obj){
if(obj[i] > max) {
max = obj[i];
}
}
if (max==obj[className]){
updateAxis("y");
//reScaleEverything();
}
// important, reset the y domain to the new max, if you don't do this then the brushing will use the last added paths y max
y.domain([0, max]);
}
} else if (addRemove=="remove"){
//if its being remove then it should already have a matching obj, remove it from the obj array and then test for the new max yVal, rescale to new max
if((className in obj )==true){
var max = 0;
for(var i in obj){
if(obj[i] > max) {
max = obj[i];
}
}
if (max==obj[className]){
delete obj[className];
delete objD[className];
var max = 0;
for(var i in obj){
if(obj[i] > max) {
max = obj[i];
}
}
//set the new y domain
y.domain([0, max]);
//y2.domain([0, max]);
//rescale y using the new max value
updateAxis("y");
}
}
}
}
// found in maxValue(), this is called after setting domains
function updateAxis(axisXY){
if (axisXY == 'x'){//Update x-axis
svg.select(".x.axis")
.transition()
.duration(1000)
.call(xAxis);
} else if (axisXY == 'y'){
//Update y-axis
svg.select(".y.axis")
.transition()
.duration(1000)
.call(yAxis);
}
// very important, rescales all existing paths to new y values
focus.selectAll("path").attr("d", area);
//focus.selectAll("path").attr("d", area2);
//focus.select(".x.axis").call(xAxis);
}
function rescaleEverything(){
}
function checkSetY(maxY){
var max = 0;
for(var i in obj){
if(obj[i] > max) {
max = obj[i];
}
}
if(maxY>max){
//if the new maxY is bigger then any other Y then set a new domain
return y.domain([0, maxY]);
}
}
function checkSetX(maxX){
console.log(maxX);
var max = 0;
for(var i in objD){
if(objD[i] > max) {
max = objD[i];
}
}
if(maxX>max){
//if the new maxX is bigger then any other Y then set a new domain
return x.domain([0, maxX]);
}
}
function addCSV(csvFileName, className){
d3.csv(csvFileName, function(error, data) {
data.forEach(function(d) {
d.date = parseDate(d.date);
d.price = +d.price;
});
maxY = d3.max(data.map(function(d) { return d.price; }));
checkSetY(maxY);
maxX = d3.max(data.map(function(d) { return d.date; }));
checkSetX(maxX);
//x.domain(d3.extent(data.map(function(d) { return d.date; })));
//y.domain([0, d3.max(data.map(function(d) { return d.price; }))]);
x2.domain(x.domain());
y2.domain(y.domain());
focus.append("path")
.datum(data)
.attr("clip-path", "url(#clip)")
.attr("d", area)
.attr("class", className);
context.append("path")
.datum(data)
.attr("class", className)
.attr("d", area2);
// important, this fixes brushing issues, avoids multiple context brush areas
context.selectAll("g.x.brush").remove();
context.append("g")
.attr("class", "x brush")
.call(brush)
.selectAll("rect")
.attr("y", -6)
.attr("height", height2 + 7);
maxValue(maxY,maxX,"add",className);
//maxX = d3.max(data.map(function(d) { return Date.max(d.date); }));
//console.log(maxX);
});
}
function removeCSV(className){
var classRemoval = "." + className;
d3.selectAll(classRemoval).transition().remove();
maxValue(maxY,maxX,"remove",className);
}
function brushed() {
x.domain(brush.empty() ? x2.domain() : brush.extent());
//console.log(x2);
focus.selectAll("path").attr("d", area);
focus.select(".x.axis").call(xAxis);
}
function incrementDate(){
//pass in last date
}
$(document).ready(function() {
//addCSV("sp501.csv", "timeLine2");
//toggle the side panel sliding
$(".togglePanel").click(function(){
//$("#channels").animate({left:'-130px'},350);
var $lefty = $("#channels");
$lefty.animate({
left: parseInt($lefty.css('left'),10) == 0 ?
-$lefty.outerWidth() :
0
});
});
$("#maincontent2, #maincontent3").hide();
$(".gauge").hover(
function(){
var idName = $(this).attr('id');
var newName = "." + idName.substring(0,3) + "Class";
//alert(newName);
$(newName).css("fill","#c2c2c2");
$(newName).css("fill-opacity",".7");
//$(newName).css("stroke-width","3");
},
function(){
var idName = $(this).attr('id');
var newName = "." + idName.substring(0,3) + "Class";
$(newName).css("fill","none");
$(newName).css("stroke-width","1");
}
);
//hide all gauges
$(".gauge").hide();
//this one starts already open
$("#ch1GaugeContainer").slideDown();
$("#tabs li").click(function() {
$("#tabs li").removeClass("selected");
$(this).addClass("selected");
});
$('#channelSelect :checkbox').click(function() {
var $this = $(this);
var channelName = $this.attr("value") + ".csv";
var className = $this.attr("value") + "Class";
var guageName = "#" + $this.attr("value") + "GaugeContainer";
// $this will contain a reference to the checkbox
if ($this.is(':checked')) {
addCSV(channelName,className);
$(guageName).slideDown();
} else {
removeCSV(className);
$(guageName).slideUp();
}
});
});