D3.js遇到问题。最初,此代码x轴为0、1、2、3、4、5、6、7。我正在尝试将x轴设置为x:[“星期六”,“星期日”,“星期一”,“星期二”,“星期三”,“星期四”,“星期五”,“星期六”]。请帮忙!不确定如何解决。
<!DOCTYPE html>
<meta charset="utf-8">
<style>
body {
font: 10px sans-serif;
}
.axis path,
.axis line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
.grid path,
.grid line {
fill: none;
stroke: rgba(0, 0, 0, 0.25);
shape-rendering: crispEdges;
}
.x.axis path {
display: none;
}
.line {
fill: none;
stroke-width: 2.5px;
}
</style>
<body>
<script src="https://d3js.org/d3.v3.js"></script>
<script>
var data = [ { label: "High",
x: ["Saturday", "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"],
y: [82, 81, 81, 70, 77, 78, 79, 80] },
{ label: "Low",
x: ["Saturday", "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"],
y: [67, 59, 50, 47, 51, 60, 66, 66] } ] ;
var xy_chart = d3_xy_chart()
.width(960)
.height(500)
.xlabel("Days")
.ylabel("Temperature F*") ;
var svg = d3.select("body").append("svg")
.datum(data)
.call(xy_chart) ;
function d3_xy_chart() {
var width = 640,
height = 480,
xlabel = "X Axis Label",
ylabel = "Y Axis Label" ;
function chart(selection) {
selection.each(function(datasets) {
//
// Create the plot.
//
var margin = {top: 20, right: 80, bottom: 30, left: 50},
innerwidth = width - margin.left - margin.right,
innerheight = height - margin.top - margin.bottom ;
var x_scale = d3.scale.linear()
.range([0, innerwidth])
.domain([ d3.min(datasets, function(d) { return d3.min(d.x); }),
d3.max(datasets, function(d) { return d3.max(d.x); }) ]) ;
var y_scale = d3.scale.linear()
.range([innerheight, 0])
.domain([ d3.min(datasets, function(d) { return d3.min(d.y); }),
d3.max(datasets, function(d) { return d3.max(d.y); }) ]) ;
var color_scale = d3.scale.category10()
.domain(d3.range(datasets.length)) ;
var x_axis = d3.svg.axis()
.scale(x_scale)
.orient("bottom") ;
var y_axis = d3.svg.axis()
.scale(y_scale)
.orient("left") ;
var x_grid = d3.svg.axis()
.scale(x_scale)
.orient("bottom")
.tickSize(-innerheight)
.tickFormat("") ;
var y_grid = d3.svg.axis()
.scale(y_scale)
.orient("left")
.tickSize(-innerwidth)
.tickFormat("") ;
var draw_line = d3.svg.line()
.interpolate("basis")
.x(function(d) { return x_scale(d[0]); })
.y(function(d) { return y_scale(d[1]); }) ;
var svg = d3.select(this)
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")") ;
svg.append("g")
.attr("class", "x grid")
.attr("transform", "translate(0," + innerheight + ")")
.call(x_grid) ;
svg.append("g")
.attr("class", "y grid")
.call(y_grid) ;
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + innerheight + ")")
.call(x_axis)
.append("text")
.attr("dy", "-.71em")
.attr("x", innerwidth)
.style("text-anchor", "end")
.text(xlabel) ;
svg.append("g")
.attr("class", "y axis")
.call(y_axis)
.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 6)
.attr("dy", "0.71em")
.style("text-anchor", "end")
.text(ylabel) ;
var data_lines = svg.selectAll(".d3_xy_chart_line")
.data(datasets.map(function(d) {return d3.zip(d.x, d.y);}))
.enter().append("g")
.attr("class", "d3_xy_chart_line") ;
data_lines.append("path")
.attr("class", "line")
.attr("d", function(d) {return draw_line(d); })
.attr("stroke", function(_, i) {return color_scale(i);}) ;
data_lines.append("text")
.datum(function(d, i) { return {name: datasets[i].label, final: d[d.length-1]}; })
.attr("transform", function(d) {
return ( "translate(" + x_scale(d.final[0]) + "," +
y_scale(d.final[1]) + ")" ) ; })
.attr("x", 3)
.attr("dy", ".35em")
.attr("fill", function(_, i) { return color_scale(i); })
.text(function(d) { return d.name; }) ;
}) ;
}
chart.width = function(value) {
if (!arguments.length) return width;
width = value;
return chart;
};
chart.height = function(value) {
if (!arguments.length) return height;
height = value;
return chart;
};
chart.xlabel = function(value) {
if(!arguments.length) return xlabel ;
xlabel = value ;
return chart ;
} ;
chart.ylabel = function(value) {
if(!arguments.length) return ylabel ;
ylabel = value ;
return chart ;
} ;
return chart;
}
</script>
答案 0 :(得分:0)
这是扩展问题。您正在以线性比例缩放字符串:
var x_scale = d3.scale.linear()
.range([0, innerwidth])
.domain([ d3.min(datasets, function(d) { return d3.min(d.x); }),
d3.max(datasets, function(d) { return d3.max(d.x); }) ]) ;
这里有两个问题:min / max函数将评估x值字符串的min / max,这可能不是您想要的min / max。同样,使用线性标尺也会出现相同的问题,它需要数字。
对于d3v3,我们可以使用序数标度:
var x_scale = d3.scale.ordinal()
.rangePoints([0, innerwidth])
.domain(datasets[0].x) ;
这假定所有数据系列都具有相同的x值
哪个给了我们
var data = [ { label: "High",
x: ["Saturday", "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"],
y: [82, 81, 81, 70, 77, 78, 79, 80] },
{ label: "Low",
x: ["Saturday", "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"],
y: [67, 59, 50, 47, 51, 60, 66, 66] } ] ;
var xy_chart = d3_xy_chart()
.width(960)
.height(500)
.xlabel("Days")
.ylabel("Temperature F*") ;
var svg = d3.select("body").append("svg")
.datum(data)
.call(xy_chart) ;
function d3_xy_chart() {
var width = 640,
height = 480,
xlabel = "X Axis Label",
ylabel = "Y Axis Label" ;
function chart(selection) {
selection.each(function(datasets) {
//
// Create the plot.
//
var margin = {top: 20, right: 80, bottom: 30, left: 50},
innerwidth = width - margin.left - margin.right,
innerheight = height - margin.top - margin.bottom ;
var x_scale = d3.scale.ordinal()
.rangePoints([0, innerwidth])
.domain(datasets[0].x) ;
var y_scale = d3.scale.linear()
.range([innerheight, 0])
.domain([ d3.min(datasets, function(d) { return d3.min(d.y); }),
d3.max(datasets, function(d) { return d3.max(d.y); }) ]) ;
var color_scale = d3.scale.category10()
.domain(d3.range(datasets.length)) ;
var x_axis = d3.svg.axis()
.scale(x_scale)
.orient("bottom") ;
var y_axis = d3.svg.axis()
.scale(y_scale)
.orient("left") ;
var x_grid = d3.svg.axis()
.scale(x_scale)
.orient("bottom")
.tickSize(-innerheight)
.tickFormat("") ;
var y_grid = d3.svg.axis()
.scale(y_scale)
.orient("left")
.tickSize(-innerwidth)
.tickFormat("") ;
var draw_line = d3.svg.line()
.interpolate("basis")
.x(function(d) { return x_scale(d[0]); })
.y(function(d) { return y_scale(d[1]); }) ;
var svg = d3.select(this)
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")") ;
svg.append("g")
.attr("class", "x grid")
.attr("transform", "translate(0," + innerheight + ")")
.call(x_grid) ;
svg.append("g")
.attr("class", "y grid")
.call(y_grid) ;
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + innerheight + ")")
.call(x_axis)
.append("text")
.attr("dy", "-.71em")
.attr("x", innerwidth)
.style("text-anchor", "end")
.text(xlabel) ;
svg.append("g")
.attr("class", "y axis")
.call(y_axis)
.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 6)
.attr("dy", "0.71em")
.style("text-anchor", "end")
.text(ylabel) ;
var data_lines = svg.selectAll(".d3_xy_chart_line")
.data(datasets.map(function(d) {return d3.zip(d.x, d.y);}))
.enter().append("g")
.attr("class", "d3_xy_chart_line") ;
data_lines.append("path")
.attr("class", "line")
.attr("d", function(d) {return draw_line(d); })
.attr("stroke", function(_, i) {return color_scale(i);}) ;
data_lines.append("text")
.datum(function(d, i) { return {name: datasets[i].label, final: d[d.length-1]}; })
.attr("transform", function(d) {
return ( "translate(" + x_scale(d.final[0]) + "," +
y_scale(d.final[1]) + ")" ) ; })
.attr("x", 3)
.attr("dy", ".35em")
.attr("fill", function(_, i) { return color_scale(i); })
.text(function(d) { return d.name; }) ;
}) ;
}
chart.width = function(value) {
if (!arguments.length) return width;
width = value;
return chart;
};
chart.height = function(value) {
if (!arguments.length) return height;
height = value;
return chart;
};
chart.xlabel = function(value) {
if(!arguments.length) return xlabel ;
xlabel = value ;
return chart ;
} ;
chart.ylabel = function(value) {
if(!arguments.length) return ylabel ;
ylabel = value ;
return chart ;
} ;
return chart;
}
body {
font: 10px sans-serif;
}
.axis path,
.axis line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
.grid path,
.grid line {
fill: none;
stroke: rgba(0, 0, 0, 0.25);
shape-rendering: crispEdges;
}
.x.axis path {
display: none;
}
.line {
fill: none;
stroke-width: 2.5px;
}
<script src="https://d3js.org/d3.v3.js"></script>
或者:
好,现在我们至少可以看到轴和线。但是,我们有一个新问题:我们有两个具有相同x值的数据点:“星期六”。比例尺将始终将给定的输入值映射到相同的输出值。因此,我们需要区分两个星期六。我们区分输入字符串的一种方法是使用它们的索引。假设输入的是序数:
这需要设置稍微不同的比例:
var x_scale = d3.scale.ordinal()
.rangePoints([0,innerwidth])
.domain(d3.range(datasets[0].y.length));
d3.range(n)生成一个从0到n-1的数字数组,非常适合复制数据数组中的每个索引
但是,现在我们必须将索引传递到使用刻度的每个位置(而不是日期)。在此示例中,我认为这只是行生成器。
var draw_line = d3.svg.line()
.interpolate("basis")
.x(function(d,i) { return x_scale(i); })
.y(function(d) { return y_scale(d[1]); }) ;
当然,现在我们需要格式化刻度线,使它们不是数字形式:
var x_axis = d3.svg.axis()
.scale(x_scale)
.orient("bottom")
.tickFormat(function(d) { return datasets[0].x[d]; })
哪个给了我们
var data = [ { label: "High",
x: ["Saturday", "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"],
y: [82, 81, 81, 70, 77, 78, 79, 80] },
{ label: "Low",
x: ["Saturday", "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"],
y: [67, 59, 50, 47, 51, 60, 66, 66] } ] ;
var xy_chart = d3_xy_chart()
.width(960)
.height(500)
.xlabel("Days")
.ylabel("Temperature F*") ;
var svg = d3.select("body").append("svg")
.datum(data)
.call(xy_chart) ;
function d3_xy_chart() {
var width = 640,
height = 480,
xlabel = "X Axis Label",
ylabel = "Y Axis Label" ;
function chart(selection) {
selection.each(function(datasets) {
//
// Create the plot.
//
var margin = {top: 20, right: 80, bottom: 30, left: 50},
innerwidth = width - margin.left - margin.right,
innerheight = height - margin.top - margin.bottom ;
var x_scale = d3.scale.ordinal()
.rangePoints([0,innerwidth])
.domain(d3.range(datasets[0].y.length)); // assuming all x axes are the same
var y_scale = d3.scale.linear()
.range([innerheight, 0])
.domain([ d3.min(datasets, function(d) { return d3.min(d.y); }),
d3.max(datasets, function(d) { return d3.max(d.y); }) ]) ;
var color_scale = d3.scale.category10()
.domain(d3.range(datasets.length)) ;
var x_axis = d3.svg.axis()
.scale(x_scale)
.orient("bottom")
.tickFormat(function(d) { return datasets[0].x[d]; })
var y_axis = d3.svg.axis()
.scale(y_scale)
.orient("left") ;
var x_grid = d3.svg.axis()
.scale(x_scale)
.orient("bottom")
.tickSize(-innerheight)
.tickFormat("") ;
var y_grid = d3.svg.axis()
.scale(y_scale)
.orient("left")
.tickSize(-innerwidth)
.tickFormat("") ;
var draw_line = d3.svg.line()
.interpolate("basis")
.x(function(d,i) { return x_scale(i); })
.y(function(d) { return y_scale(d[1]); }) ;
var svg = d3.select(this)
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")") ;
svg.append("g")
.attr("class", "x grid")
.attr("transform", "translate(0," + innerheight + ")")
.call(x_grid) ;
svg.append("g")
.attr("class", "y grid")
.call(y_grid) ;
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + innerheight + ")")
.call(x_axis)
.append("text")
.attr("dy", "-.71em")
.attr("x", innerwidth)
.style("text-anchor", "end")
.text(xlabel) ;
svg.append("g")
.attr("class", "y axis")
.call(y_axis)
.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 6)
.attr("dy", "0.71em")
.style("text-anchor", "end")
.text(ylabel) ;
var data_lines = svg.selectAll(".d3_xy_chart_line")
.data(datasets.map(function(d) {return d3.zip(d.x, d.y);}))
.enter().append("g")
.attr("class", "d3_xy_chart_line") ;
data_lines.append("path")
.attr("class", "line")
.attr("d", function(d) {return draw_line(d); })
.attr("stroke", function(_, i) {return color_scale(i);}) ;
data_lines.append("text")
.datum(function(d, i) { return {name: datasets[i].label, final: d[d.length-1]}; })
.attr("transform", function(d) {
return ( "translate(" + x_scale(d.final[0]) + "," +
y_scale(d.final[1]) + ")" ) ; })
.attr("x", 3)
.attr("dy", ".35em")
.attr("fill", function(_, i) { return color_scale(i); })
.text(function(d) { return d.name; }) ;
}) ;
}
chart.width = function(value) {
if (!arguments.length) return width;
width = value;
return chart;
};
chart.height = function(value) {
if (!arguments.length) return height;
height = value;
return chart;
};
chart.xlabel = function(value) {
if(!arguments.length) return xlabel ;
xlabel = value ;
return chart ;
} ;
chart.ylabel = function(value) {
if(!arguments.length) return ylabel ;
ylabel = value ;
return chart ;
} ;
return chart;
}
body {
font: 10px sans-serif;
}
.axis path,
.axis line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
.grid path,
.grid line {
fill: none;
stroke: rgba(0, 0, 0, 0.25);
shape-rendering: crispEdges;
}
.x.axis path {
display: none;
}
.line {
fill: none;
stroke-width: 2.5px;
}
<script src="https://d3js.org/d3.v3.js"></script>
注释
此答案假设您正在传递序数数据。这里的大多数挑战和答案都是关于相同的输入值。如果x轴的每个输入值都不同,则第一个代码段会很好(在处理序数数据时)。
如果希望图表功能接受任意数据类型,连续数据,日期/时间或顺序数据,则需要构建其他逻辑以在适当的比例之间进行选择。我没碰过那个话题,因为问题是为什么轴和刻度的行为不符合要求。