d3.js:在工具提示中显示带有两个独立数组的x轴值和y轴值

时间:2018-02-11 02:41:10

标签: javascript arrays d3.js

我正在从两个不同的(平面)数组创建条形图,一个数组包含计数数据,一个数组包含日期数据。我很难抓住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>

我不得不把我的长代码归结为这个问题的必要部分(请原谅我可能遗漏的任何内容,并随时评论澄清。)

2 个答案:

答案 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>