我有一个函数,我调用它来呈现d3js
图表:
var tooltip = tooltipd3();
var svg = d3.select("svg#svg-day"),
margin = {
top: 20,
right: 30,
bottom: 30,
left: 25,
padding: 15
},
width = 700 - margin.left - margin.right,
height = 300 - margin.top - margin.bottom;
// parse the periodo / time
var parseTime = d3.timeParse("%Y-%m-%d");
// set the ranges
var x = d3.scaleTime().range([0, width - margin.padding]);
var y = d3.scaleLinear().range([height, 0]);
// define the area
var area = d3.area()
.x(function(d) {
return x(d.periodo) + (margin.left + margin.padding);
})
.y0(height)
.y1(function(d) {
return y(d.guadagno);
});
// define the line
var valueline = d3.line()
.x(function(d) {
return x(d.periodo) + (margin.left + margin.padding);
})
.y(function(d) {
return y(d.guadagno);
});
var div = d3.select("svg#svg-day")
.append("div") // declare the tooltip div
.attr("class", "tooltip") // apply the 'tooltip' class
.style("opacity", 0);
// get the data
d3.csv(base_url() + 'graph/getStatementsDaily/', function(error, data) {
if (error) throw error;
$('.graph-loading').hide();
// format the data
data.forEach(function(d) {
d.periodo = parseTime(d.periodo)
d.guadagno = +d.guadagno;
});
// scale the range of the data
x.domain(d3.extent(data, function(d) {
return d.periodo;
}));
y.domain([0, d3.max(data, function(d) {
return d.guadagno + ((d.guadagno / 100) * 10); // 10% in più sulla scala numerica
})]);
// add the area
svg.append("path")
.data([data])
.attr("class", "area")
.attr("d", area);
// add the valueline path.
svg.append("path")
.data([data])
.attr("class", "line")
.attr("d", valueline);
// Add the scatterplot
svg.selectAll("dot")
.data(data)
.enter().append("circle")
.attr("class", "dot")
.attr("r", 3)
.attr("cx", function(d) {
return x(d.periodo) + (margin.left + margin.padding);
})
.attr("cy", function(d) {
return y(d.guadagno);
})
.on('mouseover', function(d) {
var html = '<h5>' + d.guadagno + ' €</h5>';
tooltip.mouseover(html); // pass html content
})
.on('mousemove', tooltip.mousemove)
.on('mouseout', tooltip.mouseout);
// add the X Axis
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(" + (margin.left + margin.padding) + "," + (height) + ")")
.call(d3.axisBottom(x).tickFormat(d3.timeFormat("%d/%m")))
// add the Y Axis
svg.append("g")
.attr("class", "y axis")
.attr("transform", "translate (" + (margin.left + margin.padding) + " 0)")
.call(d3.axisLeft(y));
});
您看到的侧边按钮是要更改csv网址,以便图表在点击时更新,我这样做:
$('.input-number__increase, .input-number__decrease').on('click', function() {
var where_at = $('#scroll-statement-day').val();
$('.graph-loading').show();
$('#svg').css({ 'opacity': 0.4 });
var display_where_at = (where_at - 7) + '-' + where_at;
if (parseInt(where_at) === 7) {
display_where_at = where_at;
}
$('#data-days').html(display_where_at);
var tooltip = tooltipd3();
var svg = d3.select("svg#svg-day"),
margin = {
top: 20,
right: 30,
bottom: 30,
left: 25,
padding: 15
},
width = 700 - margin.left - margin.right,
height = 300 - margin.top - margin.bottom;
// parse the periodo / time
var parseTime = d3.timeParse("%Y-%m-%d");
// set the ranges
var x = d3.scaleTime().range([0, width - margin.padding]);
var y = d3.scaleLinear().range([height, 0]);
// define the area
var area = d3.area()
.x(function(d) {
return x(d.periodo) + (margin.left + margin.padding);
})
.y0(height)
.y1(function(d) {
return y(d.guadagno);
});
// define the line
var valueline = d3.line()
.x(function(d) {
return x(d.periodo) + (margin.left + margin.padding);
})
.y(function(d) {
return y(d.guadagno);
});
var div = d3.select("svg#svg-day")
.append("div") // declare the tooltip div
.attr("class", "tooltip") // apply the 'tooltip' class
.style("opacity", 0);
var speed = 750;
d3.csv(base_url() + 'graph/getStatementsDaily/' + where_at, function(error, data) {
if (error) throw error;
$('.graph-loading').hide();
$('#svg').css({ 'opacity': 1 });
// format the data
data.forEach(function(d) {
d.periodo = parseTime(d.periodo)
d.guadagno = +d.guadagno;
});
// Scale the range of the data again
x.domain(d3.extent(data, function(d) {
return d.periodo;
}));
y.domain([0, d3.max(data, function(d) {
return d.guadagno + ((d.guadagno / 100) * 10); // 10% in più sulla scala numerica
})]);
// Select the section we want to apply our changes to
var svg = d3.select("body").transition();
// Make the changes
svg.select(".line") // change the line
.duration(speed)
.attr("d", valueline(data));
svg.selectAll("g.x.axis") // change the x axis
.duration(speed)
.call(d3.axisBottom(x).tickFormat(d3.timeFormat("%d/%m")));
svg.selectAll("g.y.axis") // change the y axis
.duration(speed)
.call(d3.axisLeft(y));
svg.select("path")
.duration(speed)
.attr("d", area);
svg.select("circle")
.duration(speed)
.attr("r", 3)
.attr("cx", function(d) {
return x(d.periodo) + (margin.left + margin.padding);
})
.attr("cy", function(d) {
return y(d.guadagno);
})
});
});
我试图找出原因,但我无法得到它......任何想法?
答案 0 :(得分:2)
执行此操作时:
svg.select("circle")
您只选择页面中的第一个圆圈(如果有)。根据API,select
...
选择与指定选择器字符串匹配的第一个元素。 (强调我的)
话虽如此,你需要selectAll
。但仅凭这一点无法解决问题:您必须重新绑定数据。由于我不知道您的数据结构,因此默认方法按索引绑定。
总之,它应该是:
svg.selectAll("circle")
.data(data)
//etc...
由于这些圈子有一个名为dot
的班级,您可以避免使用以下选择其他圈子
svg.selectAll(".dot")
.data(data)
//etc...
关于行和区域,请执行相同的操作:首先绑定数据,然后更改其d
属性:
svg.select(".area")
.data([data])
.attr("d", area);
svg.select(".line")
.data([data])
.attr("d", valueline);
此外,由于您要重新绑定数据,因此您必须更改此内容:
var svg = d3.select("body").transition();
因为svg.selectAll
将是一个转换选择。也就是说,在重新绑定数据之后设置转换到每个单独的选择,将其从svg
选择中删除。