在D3 X轴图上放置自定义标签

时间:2018-10-06 17:56:21

标签: javascript d3.js

我在图表上取得的进步似乎可以正常工作。但是,我正在努力将数据值放在x轴上。在这种情况下,应该有3个轴标签(test1,test2,test3)。

// Data
var dataset = [{
    name: "test1",
    y: 0.1
  },
  {
    name: "test2",
    y: 0.6
  },
  {
    name: "test3",
    y: 0.9
  }
];

似乎只是用有多少个条目(0,1,2)来标记它,而不是使用名称。我试图改变的是这个:

var line = d3.line()
  .x(function(d, i) {
    return xScale(i);

对此(我必须承认,这只是个猜测)。

var line = d3.line()
  .x(function(d, i) {
    return xScale(d.name);

不幸的是,这没有用,我不确定下一步该怎么做。这是完整的代码(如果有帮助的话)。

http://jsfiddle.net/spadez/cfz3g4w2/

1 个答案:

答案 0 :(得分:1)

您为x数据使用了错误的比例。您有离散数据,并且需要ordinal scale

// Data
var dataset = [{
    name: "test1",
    y: 0.1
  },
  {
    name: "test2",
    y: 0.6
  },
  {
    name: "test3",
    y: 0.9
  }
];

// Count number of datapoints
var n = Object.keys(dataset).length;

// Find max of the data points for Y axis
var mymax = Math.max.apply(Math, dataset.map(function(o) {
  return o.y;
}));

// 2. Use the margin convention practice 
var margin = {
    top: 50,
    right: 50,
    bottom: 50,
    left: 50
  },
  width = window.innerWidth - margin.left - margin.right;
height = window.innerHeight - margin.top - margin.bottom;


// 5. X scale will use the index of our data
var xScale = d3.scalePoint()
  .domain(dataset.map(d => d.name)) // input
  .range([0, width]); // output

// 6. Y scale will use the randomly generate number 
var yScale = d3.scaleLinear()
  .domain([0, mymax]) // input 
  .range([height, 0]); // output 

// 7. d3's line generator
var line = d3.line()
  .x(function(d, i) {
    return xScale(d.name);
  }) // set the x values for the line generator
  .y(function(d) {
    return yScale(d.y);
  }) // set the y values for the line generator 
  .curve(d3.curveMonotoneX) // apply smoothing to the line

// 1. Add the SVG to the page and employ #2
var svg = d3.select("body").append("svg")
  .attr("width", width + margin.left + margin.right)
  .attr("height", height + margin.top + margin.bottom)
  .append("g")
  .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

// 3. Call the x axis in a group tag
svg.append("g")
  .attr("class", "x axis")
  .attr("transform", "translate(0," + height + ")")
  .call(d3.axisBottom(xScale)); // Create an axis component with d3.axisBottom

// 4. Call the y axis in a group tag
svg.append("g")
  .attr("class", "y axis")
  .call(d3.axisLeft(yScale)); // Create an axis component with d3.axisLeft

// 9. Append the path, bind the data, and call the line generator 
svg.append("path")
  .datum(dataset) // 10. Binds data to the line 
  .attr("class", "line") // Assign a class for styling 
  .attr("d", line); // 11. Calls the line generator 

// 12. Appends a circle for each datapoint 
svg.selectAll(".dot")
  .data(dataset)
  .enter().append("circle") // Uses the enter().append() method
  .attr("class", "dot") // Assign a class for styling
  .attr("cx", function(d, i) {
    return xScale(d.name)
  })
  .attr("cy", function(d) {
    return yScale(d.y)
  })
  .attr("r", 5)
  .on("mouseover", function(a, b, c) {
    console.log(a)
    this.attr('class', 'focus')
  })
  .on("mouseout", function() {})
  .on("mousemove", mousemove);

var focus = svg.append("g")
  .attr("class", "focus")
  .style("display", "none");

focus.append("circle")
  .attr("r", 4.5);

focus.append("text")
  .attr("x", 9)
  .attr("dy", ".35em");

svg.append("rect")
  .attr("class", "overlay")
  .attr("width", width)
  .attr("height", height)
  .on("mouseover", function() {
    focus.style("display", null);
  })
  .on("mouseout", function() {
    focus.style("display", "none");
  })
  .on("mousemove", mousemove);

function mousemove() {
  var x0 = x.invert(d3.mouse(this)[0]),
    i = bisectDate(data, x0, 1),
    d0 = data[i - 1],
    d1 = data[i],
    d = x0 - d0.date > d1.date - x0 ? d1 : d0;
  focus.attr("transform", "translate(" + x(d.date) + "," + y(d.close) + ")");
  focus.select("text").text(d);
}

运行代码:

.line {
  fill: none;
  stroke: #ffab00;
  stroke-width: 3;
}

.overlay {
  fill: none;
  pointer-events: all;
}

/* Style the dots by assigning a fill and stroke */

.dot {
  fill: #ffab00;
  stroke: #fff;
}

.focus circle {
  fill: none;
  stroke: steelblue;
}
<!-- Load in the d3 library -->
<script src="https://d3js.org/d3.v5.min.js"></script>
a = div.getElementsById("hobbies");