D3 折线图剪裁 y 轴
D3 line chart clipped y axis
我正在尝试在 d3 中构建图表,它在 fiddle 中很容易工作。但是,当我将代码放入我的实际实现中时,生成的 svg 元素在顶部和左侧被切掉了。我试过大小和边距,但不知何故,什么都没有改变。
这里是 fiddle,其中包含工作代码和粘贴的 svg,正如我的实际实现所提供的:http://jsfiddle.net/16jjdyt1/5/
这是我得到的输出图片:
这是我实际实现的代码。
function updateGraph(data) {
var selector = "#" + id + " .chart svg";
// NOTE this is a hack, sometimes chart is null!
if (!_.isEmpty(data.primary)) {
d3.selectAll(selector + " > *").remove();
var width = 400,
height = 140;
var margin = {top: 30, right: 60, bottom: 30, left: 50}
var parseDate = d3.time.format('%d.%m.%y %H:%M').parse;
var x = d3.time.scale().range([0, width]);
var y0 = d3.scale.linear().range([height, 0]);
var y1 = d3.scale.linear().range([height, 0]);
// ticks
var xAxis = d3.svg.axis().scale(x)
.orient("bottom").tickFormat(function(d) {
return d3.time.format('%d.%m.%y %H:%M')(new Date(d))
})
.ticks(5); // TODO change this
var yAxisLeft = d3.svg.axis().scale(y0)
.orient("left").tickFormat(d3.format(',.2f'));
var yAxisRight = d3.svg.axis().scale(y1)
.orient("right").tickFormat(d3.format(',.2f'));
// function for left aligned lines
var valueline = d3.svg.line()
.x(function(d) { return x(d.x); })
.y(function(d) { return y0(d.y); })
.interpolate("cardinal").tension(0.8);
// function for right aligned lines
var valueline2 = d3.svg.line()
.x(function(d) { return x(d.x); })
.y(function(d) { return y1(d.y); })
.interpolate("cardinal").tension(0.8);
d3.select(selector)
.attr("width", width + margin.left + margin.right + 20)
.attr("height", height + margin.top + margin.bottom +20)
.append("g")
.attr("transform","translate(" + margin.left + "," + margin.top + ")");
// TODO refactor this
var x_values = [];
var y0_values = [];
var y1_values = [];
_.each(data.primary, function(d){
_.each(d.values, function(f){
x_values.push(f.x);
y0_values.push(f.y);
});
}); // TODO refactor this!
_.each(data.secondary, function(d){
_.each(d.values, function(f){
x_values.push(f.x);
y1_values.push(f.y);
});
}); // TODO refactor this!
x.domain(d3.extent(x_values)); // scale x axis
y0.domain(d3.extent(y0_values)); // scale y axis 1
y1.domain(d3.extent(y1_values)); // scale y axis 2
// Add left aligned graphs
data.primary.forEach(function(d){
d3.select(selector).append("path")
.style("stroke", d.color)
.attr("d",valueline(d.values));
});
// Add right aligned graphs
data.secondary.forEach(function(d){
d3.select(selector).append("path")
.style("stroke", d.color)
.attr("d",valueline2(d.values));
});
d3.select(selector).append("g") // Add the X Axis
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
d3.select(selector).append("g") // Add first y axis
.attr("class", "y axis")
.call(yAxisLeft);
d3.select(selector).append("g") // Add second y axis
.attr("class", "y axis")
.attr("transform", "translate(" + width + " ,0)")
.call(yAxisRight);
}
}
return timechart;
};
我不知道这个错误可能出在哪里,所以我很高兴得到任何提示。
提前致谢!
你的路径、轴等应该位于 g
元素内,像这样::
<g transform="translate(50,30)">
// in 'test', chart goes here
</g>
但是,在您的 'output' 版本中,图表元素都在 g
:
之后
<g transform="translate(50,30)"></g>
// in 'output', chart goes here
在实际实现的代码中,首先将 g
附加到 selector
(即 svg 元素)...
d3.select(selector)
.attr("width", width + margin.left + margin.right + 20)
.attr("height", height + margin.top + margin.bottom +20)
.append("g")
.attr("transform","translate(" + margin.left + "," + margin.top + ")");
然后添加其他位,这些位将在 之后,而不是 嵌套在 内,翻译后的 g
,像这样:
d3.select(selector).append("g") // Add the X Axis
.attr("class", "x axis")
为了避免这种情况,您可以做的一件事是为 g
定义一个 id
,并定义一个 select 用于添加您的轴和路径,例如:
d3.select(selector)
.attr("width", width + margin.left + margin.right + 20)
.attr("height", height + margin.top + margin.bottom +20)
.append("g")
.attr("transform","translate(" + margin.left + "," + margin.top + ")")
.attr("id", "selector_g";
然后
d3.select("#selector_g").append("g") // Add the X Axis
.attr("class", "x axis")
我正在尝试在 d3 中构建图表,它在 fiddle 中很容易工作。但是,当我将代码放入我的实际实现中时,生成的 svg 元素在顶部和左侧被切掉了。我试过大小和边距,但不知何故,什么都没有改变。
这里是 fiddle,其中包含工作代码和粘贴的 svg,正如我的实际实现所提供的:http://jsfiddle.net/16jjdyt1/5/
这是我得到的输出图片:
function updateGraph(data) {
var selector = "#" + id + " .chart svg";
// NOTE this is a hack, sometimes chart is null!
if (!_.isEmpty(data.primary)) {
d3.selectAll(selector + " > *").remove();
var width = 400,
height = 140;
var margin = {top: 30, right: 60, bottom: 30, left: 50}
var parseDate = d3.time.format('%d.%m.%y %H:%M').parse;
var x = d3.time.scale().range([0, width]);
var y0 = d3.scale.linear().range([height, 0]);
var y1 = d3.scale.linear().range([height, 0]);
// ticks
var xAxis = d3.svg.axis().scale(x)
.orient("bottom").tickFormat(function(d) {
return d3.time.format('%d.%m.%y %H:%M')(new Date(d))
})
.ticks(5); // TODO change this
var yAxisLeft = d3.svg.axis().scale(y0)
.orient("left").tickFormat(d3.format(',.2f'));
var yAxisRight = d3.svg.axis().scale(y1)
.orient("right").tickFormat(d3.format(',.2f'));
// function for left aligned lines
var valueline = d3.svg.line()
.x(function(d) { return x(d.x); })
.y(function(d) { return y0(d.y); })
.interpolate("cardinal").tension(0.8);
// function for right aligned lines
var valueline2 = d3.svg.line()
.x(function(d) { return x(d.x); })
.y(function(d) { return y1(d.y); })
.interpolate("cardinal").tension(0.8);
d3.select(selector)
.attr("width", width + margin.left + margin.right + 20)
.attr("height", height + margin.top + margin.bottom +20)
.append("g")
.attr("transform","translate(" + margin.left + "," + margin.top + ")");
// TODO refactor this
var x_values = [];
var y0_values = [];
var y1_values = [];
_.each(data.primary, function(d){
_.each(d.values, function(f){
x_values.push(f.x);
y0_values.push(f.y);
});
}); // TODO refactor this!
_.each(data.secondary, function(d){
_.each(d.values, function(f){
x_values.push(f.x);
y1_values.push(f.y);
});
}); // TODO refactor this!
x.domain(d3.extent(x_values)); // scale x axis
y0.domain(d3.extent(y0_values)); // scale y axis 1
y1.domain(d3.extent(y1_values)); // scale y axis 2
// Add left aligned graphs
data.primary.forEach(function(d){
d3.select(selector).append("path")
.style("stroke", d.color)
.attr("d",valueline(d.values));
});
// Add right aligned graphs
data.secondary.forEach(function(d){
d3.select(selector).append("path")
.style("stroke", d.color)
.attr("d",valueline2(d.values));
});
d3.select(selector).append("g") // Add the X Axis
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
d3.select(selector).append("g") // Add first y axis
.attr("class", "y axis")
.call(yAxisLeft);
d3.select(selector).append("g") // Add second y axis
.attr("class", "y axis")
.attr("transform", "translate(" + width + " ,0)")
.call(yAxisRight);
}
}
return timechart;
};
我不知道这个错误可能出在哪里,所以我很高兴得到任何提示。 提前致谢!
你的路径、轴等应该位于 g
元素内,像这样::
<g transform="translate(50,30)">
// in 'test', chart goes here
</g>
但是,在您的 'output' 版本中,图表元素都在 g
:
<g transform="translate(50,30)"></g>
// in 'output', chart goes here
在实际实现的代码中,首先将 g
附加到 selector
(即 svg 元素)...
d3.select(selector)
.attr("width", width + margin.left + margin.right + 20)
.attr("height", height + margin.top + margin.bottom +20)
.append("g")
.attr("transform","translate(" + margin.left + "," + margin.top + ")");
然后添加其他位,这些位将在 之后,而不是 嵌套在 内,翻译后的 g
,像这样:
d3.select(selector).append("g") // Add the X Axis
.attr("class", "x axis")
为了避免这种情况,您可以做的一件事是为 g
定义一个 id
,并定义一个 select 用于添加您的轴和路径,例如:
d3.select(selector)
.attr("width", width + margin.left + margin.right + 20)
.attr("height", height + margin.top + margin.bottom +20)
.append("g")
.attr("transform","translate(" + margin.left + "," + margin.top + ")")
.attr("id", "selector_g";
然后
d3.select("#selector_g").append("g") // Add the X Axis
.attr("class", "x axis")