我正在从两个不同的(平面)数组创建条形图,一个数组包含计数数据,一个数组包含日期数据。我很难抓住x轴数据点(日期)以显示在工具提示中。我已经尝试过d3.zip来组合数组,但似乎无法弄清楚如何以这种方式索引值。欢迎任何建议!
var parseDate = d3.timeParse('%Y-%m-%d');
var newECdailyArray = [1, 1, 4, 5, 9];
var newEDdailyArray = ["2016-01-05", "2016-01-10", "2016-02-01", "2016-02-15", "2016-03-05"];
var tooltip = d3.select("body").append("div")
.attr("class", "toolTip")
.style("opacity", "0")
.style("position", "absolute");
var width = 500
var height = 500
var margin = {
top:30,
bottom:70,
right:30,
left:30
}
var y = d3.scaleLinear()
.domain([0, d3.max(newECdailyArray)])
.rangeRound([height, 0]);
var x = d3.scaleTime()
.domain(d3.extent(newEDdailyArray, function(d) {
return parseDate(d);
}))
.range([0, width])
.nice(d3.timeMonth);
var yAxis = d3.axisLeft(y);
var xAxis = d3.axisBottom(x);
var svg = d3.select('#thing').append('svg')
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom);
var ChartGroup = svg.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")")
ChartGroup.selectAll('rect')
.data(newECdailyArray)
.enter().append('rect')
.attr('width', 5)
.attr("height", function(d) {
return height - y(d);
})
.attr('x', function(d, i) {
return x(parseDate(newEDdailyArray[i]));
})
.attr("y", function(d) {
return y(d);
})
.attr('fill', "blue")
.on("mousemove", function(d, i) {
tooltip
.style("opacity", "1")
.style("left", d3.event.pageX - 50 + "px")
.style("top", d3.event.pageY - 70 + "px")
.style("display", "inline-block");
console.log(parseDate(newEDdailyArray[i]));
tooltip.html("count: " + d + "<br>" + "date: ");
})
.on("mouseout", function(d) {
tooltip.style("display", "none");
});
ChartGroup.append('g')
.attr("class", "axis y")
.call(yAxis);
ChartGroup.append('g')
.attr("class", "axis x")
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(x)
.tickFormat(d3.timeFormat("%Y-%m-%d")))
.selectAll("text")
.style("text-anchor", "end")
.attr("dx", "-.8em")
.attr("dy", ".15em")
.attr("transform", "rotate(-65)");
ChartGroup.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 0 - margin.left)
.attr("x", 0 - (height / 2))
.attr("dy", "1em")
.style("text-anchor", "middle")
.text("Event Count");
ChartGroup.append("text")
.attr("transform", "translate(" + (width / 2) + " ," + (height + margin.top + 60) + ")")
.style("text-anchor", "middle")
.text("Date");
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.13.0/d3.min.js"></script>
<div id='thing'></div>
我不得不把我的长代码归结为这个问题的必要部分(请原谅我可能遗漏的任何内容,并随时评论澄清。)
答案 0 :(得分:0)
您可以通过以下方式合并阵列:
var newECdailyArray = [1, 1, 4, 5, 9];
var newEDdailyArray = ["2016-01-05", "2016-01-10", "2016-02-01", "2016-02-15", "2016-03-05"];
var data=[]
for (i in newECdailyArray){
var val = {};
val['date'] = newEDdailyArray[i];
val['value'] = newECdailyArray[i];
data.push(val)
}
console.log(data)
然后使用d.date和d.value
引用它们此外,我尝试了您的代码,它工作正常。我可以在工具提示中看到日期和值。这是小提琴。
var parseDate = d3.timeParse('%Y-%m-%d');
var newECdailyArray = [1, 1, 4, 5, 9];
var newEDdailyArray = ["2016-01-05", "2016-01-10", "2016-02-01", "2016-02-15", "2016-03-05"];
var tooltip = d3.select("body").append("div")
.attr("class", "toolTip")
.style("opacity", "0")
.style("position", "absolute");
var height = 400;
var width = 600;
var margin = {
left: 30,
right: 30,
top: 30,
bottom:70,
}
var x = d3.scaleTime()
.domain(d3.extent(newEDdailyArray, function(d) {
return parseDate(d);
}))
.range([0, width],0.4)
.nice(d3.timeMonth);
var y = d3.scaleLinear()
.domain([0, d3.max(newECdailyArray)])
.rangeRound([height, 0]);
var xAxis = d3.axisBottom(x);
var yAxis = d3.axisLeft(y);
var svg = d3.select('#thing').append('svg')
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom);
var ChartGroup = svg.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")")
ChartGroup.selectAll('rect')
.data(newECdailyArray)
.enter().append('rect')
.attr('width', 15)
.attr("height", function(d) {
return height - y(d);
})
.attr('x', function(d, i) {
return x(parseDate(newEDdailyArray[i]));
})
.attr("y", function(d) {
return y(d);
})
.attr('fill', "blue")
.on("mousemove", function(d, i) {
tooltip
.style("opacity", "1")
.style("left", d3.event.pageX - 50 + "px")
.style("top", d3.event.pageY - 70 + "px")
.style("display", "inline-block");
console.log(parseDate(newEDdailyArray[i]));
tooltip.html("count: " + d + "<br>" + "date: " + newEDdailyArray[i]);
})
.on("mouseout", function(d) {
tooltip.style("display", "none");
});
ChartGroup.append('g')
.attr("class", "axis y")
.call(yAxis);
ChartGroup.append('g')
.attr("class", "axis x")
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(x)
.tickFormat(d3.timeFormat("%Y-%m-%d")))
.selectAll("text")
.style("text-anchor", "end")
.attr("dx", "-.8em")
.attr("dy", ".15em")
.attr("transform", "rotate(-65)");
ChartGroup.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 0 - margin.left)
.attr("x", 0 - (height / 2))
.attr("dy", "1em")
.style("text-anchor", "middle")
.text(" Event Count");
ChartGroup.append("text")
.attr("transform", "translate(" + (width / 2) + " ," + (height + margin.top + 60) + ")")
.style("text-anchor", "middle")
.text("Date");
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.13.0/d3.min.js"></script>
<div id='thing'></div>
答案 1 :(得分:0)
将数据存储在D3代码中的惯用(更可靠)方法是将所有不同的属性保存在单个对象中,并存储所有不同的对象(每个数据点一个)在数组中。
但是,由于两个数组包含相同序列中的数据(即它们的索引匹配),只需使用索引:
tooltip.html("count: " + d + "<br>" + "date: " + newEDdailyArray[i]);
//index here ----------------------------------------------------^
以下是仅包含此更改的代码:
var parseDate = d3.timeParse('%Y-%m-%d');
var newECdailyArray = [1, 1, 4, 5, 9];
var newEDdailyArray = ["2016-01-05", "2016-01-10", "2016-02-01", "2016-02-15", "2016-03-05"];
var tooltip = d3.select("body").append("div")
.attr("class", "toolTip")
.style("opacity", "0")
.style("position", "absolute");
var width = 500
var height = 500
var margin = {
top:30,
bottom:70,
right:30,
left:30
}
var y = d3.scaleLinear()
.domain([0, d3.max(newECdailyArray)])
.rangeRound([height, 0]);
var x = d3.scaleTime()
.domain(d3.extent(newEDdailyArray, function(d) {
return parseDate(d);
}))
.range([0, width])
.nice(d3.timeMonth);
var yAxis = d3.axisLeft(y);
var xAxis = d3.axisBottom(x);
var svg = d3.select('#thing').append('svg')
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom);
var ChartGroup = svg.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")")
ChartGroup.selectAll('rect')
.data(newECdailyArray)
.enter().append('rect')
.attr('width', 5)
.attr("height", function(d) {
return height - y(d);
})
.attr('x', function(d, i) {
return x(parseDate(newEDdailyArray[i]));
})
.attr("y", function(d) {
return y(d);
})
.attr('fill', "blue")
.on("mousemove", function(d, i) {
tooltip
.style("opacity", "1")
.style("left", d3.event.pageX - 50 + "px")
.style("top", d3.event.pageY - 70 + "px")
.style("display", "inline-block");
console.log(parseDate(newEDdailyArray[i]));
tooltip.html("count: " + d + "<br>" + "date: " + newEDdailyArray[i]);
})
.on("mouseout", function(d) {
tooltip.style("display", "none");
});
ChartGroup.append('g')
.attr("class", "axis y")
.call(yAxis);
ChartGroup.append('g')
.attr("class", "axis x")
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(x)
.tickFormat(d3.timeFormat("%Y-%m-%d")))
.selectAll("text")
.style("text-anchor", "end")
.attr("dx", "-.8em")
.attr("dy", ".15em")
.attr("transform", "rotate(-65)");
ChartGroup.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 0 - margin.left)
.attr("x", 0 - (height / 2))
.attr("dy", "1em")
.style("text-anchor", "middle")
.text("Event Count");
ChartGroup.append("text")
.attr("transform", "translate(" + (width / 2) + " ," + (height + margin.top + 60) + ")")
.style("text-anchor", "middle")
.text("Date");
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.13.0/d3.min.js"></script>
<div id='thing'></div>