简体   繁体   English

d3.js:在工具提示中使用两个单独的数组显示x轴值和y轴值

[英]d3.js: Display x-axis value and y-axis value in tooltip with two separate arrays

I'm creating a bar chart from two different (flat) arrays, one array with count data and one array with date data. 我正在从两个不同的(平面)数组创建一个条形图,一个数组包含计数数据,一个数组包含日期数据。 I am having difficulty grabbing the x-axis data point (date) to display in the tooltip. 我很难抓住x轴数据点(日期)以显示在工具提示中。 I've tried d3.zip to combine the arrays but can't seem to figure out how to index the values that way either. 我已经尝试过d3.zip合并数组,但是似乎也无法弄清楚如何以这种方式索引值。 Any suggestions welcome! 任何建议欢迎!

 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> 

I had to boil down my longer code to just the necessary parts for this question (please excuse anything I may have left out, and feel free to comment for clarification.) 我不得不将更长的代码精简为该问题的必要部分(请原谅我可能遗漏的任何内容,并随时发表评论以澄清问题。)

You can merge your arrays in this way: 您可以通过以下方式合并数组:

 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) 

and then reference them using d.date and d.value 然后使用d.date和d.value引用它们

Also I tried your code and it works fine. 我也尝试了您的代码,它工作正常。 I can see the date and the value in the tooltip. 我可以在工具提示中看到日期和值。 Here's the fiddle. 这是小提琴。

 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> 

The idiomatic (and more reliable) way to store the data in a D3 code is keeping all the different properties in a single object , and storing all the different objects (one for each data point) in an array. 在D3代码中存储数据的惯用方式(更可靠)是将所有不同的属性保留在单个对象中 ,并将所有不同的对象(每个数据点一个)存储在一个数组中。

However, since the two arrays you have contain the data in the same sequence (ie, their indices match), just use the index: 但是,由于您拥有的两个数组包含相同顺序的数据(即它们的索引匹配),因此只需使用索引:

tooltip.html("count: " + d + "<br>" + "date: " + newEDdailyArray[i]);
//index here ----------------------------------------------------^

Here is your code with that change only: 这只是您所做的更改的代码:

 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> 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM