tob*_*ib_ 7 javascript date d3.js nvd3.js
我在xAxis上显示日期时有一个奇怪的问题.我正在生成这样的数据:
for (i=0;i<12;i++){
date=new Date(2013,i,1);
ideas.values[i] = {"y" : Math.round(2*i*getRandom(1,2)), "x": date};
}
Run Code Online (Sandbox Code Playgroud)
在我的lineChart中,我想像这样创建x轴:
chart.xAxis.tickSize(12)
.tickFormat(function(d) {
var date = new Date(d);
testarr.push(date);
return d3.time.format('%b %y')(date);
});
Run Code Online (Sandbox Code Playgroud)
现在,如果我查看图表,只有几个日期可见.这就是为什么我为脱粒问题创建了数组"testarr".testarr的内容是8个日期而不是12个(我生成了12个)
现在更奇怪的是:将完全相同的数据放在MultiBarChart中并使用完全相同的chart.xAxis ....函数,测试数组内容为12个值
我无言以对,希望有人可以帮助我.
感谢你们!
完整代码如下:
for lineChart:lineChart Result
<script>
var chart;
nv.addGraph(function() {
chart = nv.models.lineChart()
.options({
margin: {left: 100, bottom: 100},
//x: function(d,i) { return i},
showXAxis: true,
showYAxis: true,
transitionDuration: 250
})
;
chart.xAxis.tickSize(12)
.tickFormat(function(d) {
var date = new Date(d);
return d3.time.format('%b %y')(date);
});
chart.yAxis
.axisLabel('y axis')
.tickFormat(d3.format(''))
.axisLabelDistance(50);
d3.select('#chart1 svg')
.datum(dataForChart)
.call(chart);
//TODO: Figure out a good way to do this automatically
nv.utils.windowResize(chart.update);
//nv.utils.windowResize(function() { d3.select('#chart1 svg').call(chart) });
chart.dispatch.on('stateChange', function(e) { nv.log('New State:', JSON.stringify(e)); });
return chart;
});
var dataForChart=function(){
var section1 = new Array();
section1.key="Section 1";
section1.values = new Array();
section1.color="#1F77B4";
var section2 = new Array();
section2.key="Section2";
section2.values = new Array();
section2.color="#2CA02C";
for (i=0;i<12;i++){
date=new Date(2013,i,1);
section1.values[i] = {"y" : Math.round(2*i*getRandom(1,2)), "x": date};
section2.values[i] = {"y" : Math.round(6*i+2*getRandom(1,2)), "x": date};
}
function getRandom(min, max)
{
return Math.random() * (max - min + 1) + min;
}
var dataArray=new Array();
dataArray.push(section1);
dataArray.push(section2);
return dataArray;
};
</script>
Run Code Online (Sandbox Code Playgroud)
如果我不评论出来的话
//x: function(d,i) { return i},
Run Code Online (Sandbox Code Playgroud)
截面,轴显示Jan70到处都是.
对于下面的MultiBarChart代码:MultiBar结果
<script>
var chart;
nv.addGraph(function() {
chart = nv.models.multiBarChart()
.margin({bottom: 30, top:25})
.transitionDuration(300)
.delay(0)
.groupSpacing(0.2)
.reduceXTicks(false)
.showControls(true)
.showLegend(true)
.staggerLabels(false)
;
chart.xAxis.tickSize(12)
.tickFormat(function(d) {
console.log(d,arguments);
var date = new Date(d);
return d3.time.format('%b %y')(date);
});
chart.yAxis
.axisLabel(dataForChart.ylabel)
.tickFormat(d3.format(''))
.axisLabelDistance(50);
d3.select('#chart1 svg')
.datum(dataForChart)
.call(chart);
nv.utils.windowResize(chart.update);
chart.dispatch.on('stateChange', function(e) { nv.log('New State:', JSON.stringify(e)); });
return chart;
});
var dataForChart=function(){
var section1 = new Array();
section1.key="Section 1";
section1.values = new Array();
section1.color="#1F77B4";
var section2 = new Array();
section2.key="Section2";
section2.values = new Array();
section2.color="#2CA02C";
for (i=0;i<12;i++){
date=new Date(2013,i,1);
section1.values[i] = {"y" : Math.round(2*i*getRandom(1,2)), "x": date};
section2.values[i] = {"y" : Math.round(6*i+2*getRandom(1,2)), "x": date};
}
function getRandom(min, max)
{
return Math.random() * (max - min + 1) + min;
}
var dataArray=new Array();
dataArray.push(section1);
dataArray.push(section2);
return dataArray;
};
</script>
Run Code Online (Sandbox Code Playgroud)
Ame*_*aBR 24
与所有线性轴一样,折线图轴使用刻度线来显示线上的关键点,但不是每个可能的值.在许多情况下,如果图表显示每个数据,则标记将如此靠近以至于标签将重叠并变得不可读.人们期望能够基于到相邻刻度线的距离来估计线上的位置.
相反,条形图的x值假定为不同的类别,可能没有自然顺序.它们可能是"苹果","橙子"和"香蕉".根据相邻标签("苹果"和"香蕉")的值,无法估计中间值("橙子"),因此默认情况下会显示所有标签,即使它们最终重叠且不可读.
但是你的折线图,你只有12个日期值,所以你有空间适合所有标签而不重叠?常规的d3方法告诉轴它应包括多少刻度axis.ticks().我看到你试图做类似的事情,但是axis.tickSize()方法控制每个刻度线的长度,而不是有多少.但是,axis.ticks()不能与NVD3一起使用 - 内部方法会覆盖您在轴上设置的任何值.
别担心,仍有一种方法可以控制它,但它需要一些额外的代码.该axis.tickValues()方法取代axis.ticks(),因此您可以使用它来覆盖NVD3默认值.
您包含的信息axis.tickValues()是每个tick的显式值数组.由于您的x轴值是日期,并且每个月有一个值,因此您有两种方法可以创建此数组:
选项1: 直接从数据中获取x值.
chart.xAxis.tickValues(ideas.values.map( function(d){return d.x;} ) );
//Array.map(function) creates a new array, where each value is the result of
//calling the function on the corresponding element of the original array.
//Since your data is in ideas.values as an array of {x:date, y:number} objects,
//this method creates an array containing all the dates from your data.
Run Code Online (Sandbox Code Playgroud)
选项2: 使用d3 时间间隔方法计算日期序列.
chart.xAxis.tickValues(d3.time.month.range(
new Date("2013 01"),
new Date("2014 01"),
1)
);
//d3.time.month.range(startDate, stopDate, step) creates the sequence of dates
//that are exact month values, starting with the month on or after the startDate
//and continuing to the last start of month *before* the stop date
//(so it won't include January 2014. The step value tell it how many months
//to skip at a time; we want every month, so step==1.
//There are similar methods for year, week, day, hour, minute and second,
//and also versions for weeks starting on specific days of the week;
//Just replace "month" in "d3.time.month.range" with the appropriate interval.
//For plain numbers, use d3.range(start, stop, step).
Run Code Online (Sandbox Code Playgroud)
我希望现在一切都有意义.