javascript - 多线图 x 轴刻度未与数据点对齐

标签 javascript d3.js

我正在尝试使用 D3.js 绘制多折线图。图表绘制正确,但 x 轴刻度未与数据点圆正确对齐。 在此处找到示例代码:https://jsfiddle.net/gopal31795/qsLd7pc5/9/

我假设创建点的代码中存在一些错误。

// Creating Dots on line
segment.selectAll("dot")
  .data(function(d) {
    return d.linedata;
  })
  .enter().append("circle")
  .attr("r", 5)
  .attr("cx", function(d) {
    //return x(parseDate(new Date(d.mins))) + x.rangeBand() / 2;
    return x(d.mins);
  })
  .attr("cy", function(d) {
    return y(d.value);
  })
  .style("stroke", "white")
  .style("fill", function(d) {
    return color(this.parentNode.__data__.name);
  })

  .on("mouseenter", function(d) {
    d3.select(this).transition().style("opacity", "0.25");
    tooltip.html("<span style='color:" + color(this.parentNode.__data__.name) + ";'>" + this.parentNode.__data__.name + "</span>: " + (d.value + "s")).style("visibility", "visible").style("top", (event.pageY + 10) + "px").style("left", (event.pageX) + "px");
  })
  .on("mouseleave", function(d) {
    d3.select(this).transition().style("opacity", "1");
    tooltip.style("visibility", "hidden");
  });

最佳答案

您的代码(使用旧的 v3)中的问题是您使用的是 rangeRoundBands。例如,如果您有条形图,那将是正确的选择。

但是,由于您正在处理数据点,因此您应该使用 rangePointsrangeRoundPoints ,其中:

Sets the output range from the specified continuous interval. The array interval contains two elements representing the minimum and maximum numeric value. This interval is subdivided into n evenly-spaced points, where n is the number of (unique) values in the input domain.

所以,应该是:

var x = d3.scale.ordinal()
    .rangeRoundPoints([0, width]);

这里是你的代码有那个变化:

var Data = [{
    "name": "R",
    "linedata": [{
        "mins": 0,
        "value": 1120
      },
      {
        "mins": 2,
        "value": 1040
      },
      {
        "mins": 4,
        "value": 1400
      },
      {
        "mins": 6,
        "value": 1500
      }
    ]
  },
  {
    "name": "E",
    "linedata": [{
        "mins": 0,
        "value": 1220
      },
      {
        "mins": 2,
        "value": 1500
      },
      {
        "mins": 4,
        "value": 1610
      },
      {
        "mins": 6,
        "value": 1700
      }
    ]
  }
];

var margin = {
    top: 20,
    right: 90,
    bottom: 35,
    left: 90
  },
  width = $("#lineChart").width() - margin.left - margin.right,
  height = $("#lineChart").width() * 0.3745 - margin.top - margin.bottom;

//var parseDate = d3.time.format("%d-%b");

var x = d3.scale.ordinal()
  .rangeRoundPoints([0, width]);

var y = d3.scale.linear()
  .range([height, 0]);

var color = d3.scale.category10();

var xAxis = d3.svg.axis()
  .scale(x)
  .orient("bottom");

var yAxis = d3.svg.axis()
  .scale(y)
  .orient("left")
  .ticks(5);

var xData = Data[0].linedata.map(function(d) {
  return d.mins;
});


var line = d3.svg.line()
  .interpolate("linear")
  .x(function(d) {
    return x(d.mins);
  })
  .y(function(d) {
    return y(d.value);
  });

function transition(path) {
  path.transition()
    .duration(4000)
    .attrTween("stroke-dasharray", tweenDash);
}

function tweenDash() {
  var l = this.getTotalLength(),
    i = d3.interpolateString("0," + l, l + "," + l);
  return function(t) {
    return i(t);
  };
}
var svg = d3.select("#lineChart").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 + ")");

color.domain(Data.map(function(d) {
  return d.name;
}));

x.domain(xData);

var valueMax = d3.max(Data, function(r) {
  return d3.max(r.linedata, function(d) {
    return d.value;
  })
});
var valueMin = d3.min(Data, function(r) {
  return d3.min(r.linedata, function(d) {
    return d.value;
  })
});
y.domain([valueMin, valueMax]);

//Drawing X Axis
svg.append("g")
  .attr("class", "x-axis")
  .attr("transform", "translate(0," + height + ")")

  .call(xAxis)
  .append("text")
  .attr("class", "xAxisText")
  .attr("x", width)
  .attr("dy", "-.41em")
  .style("text-anchor", "end")
  .style("fill", "white")
  .text("Time(m)");


svg.append("g")
  .attr("class", "y-axis")

  .call(yAxis)
  .append("text")
  .attr("transform", "rotate(-90)")
  .attr("y", 6)
  .attr("dy", ".71em")
  .style("text-anchor", "end")
  .style("fill", "none")
  .style("stroke", "white")
  .style("stroke-width", 0.8)
  .text("Duration(s)");

// Drawing Lines for each segments
var segment = svg.selectAll(".segment")
  .data(Data)
  .enter().append("g")
  .attr("class", "segment");

segment.append("path")
  .attr("class", "line")
  .attr("id", function(d) {
    return d.name;
  })
  .attr("visible", 1)
  .call(transition)
  //.delay(750)
  //.duration(1000)
  //.ease('linear')           
  .attr("d", function(d) {
    return line(d.linedata);
  })
  .style("stroke", function(d) {
    return color(d.name);
  });


// Creating Dots on line
segment.selectAll("dot")
  .data(function(d) {
    return d.linedata;
  })
  .enter().append("circle")
  .attr("r", 5)
  .attr("cx", function(d) {
    //return x(parseDate(new Date(d.mins))) + x.rangeBand() / 2;
    return x(d.mins);
  })
  .attr("cy", function(d) {
    return y(d.value);
  })
  .style("stroke", "white")
  .style("fill", function(d) {
    return color(this.parentNode.__data__.name);
  })

  .on("mouseenter", function(d) {
    d3.select(this).transition().style("opacity", "0.25");
    tooltip.html("<span style='color:" + color(this.parentNode.__data__.name) + ";'>" + this.parentNode.__data__.name + "</span>: " + (d.value + "s")).style("visibility", "visible").style("top", (event.pageY + 10) + "px").style("left", (event.pageX) + "px");
  })
  .on("mouseleave", function(d) {
    d3.select(this).transition().style("opacity", "1");
    tooltip.style("visibility", "hidden");
  });
path {
  fill: none;
  stroke: black;
}

line {
  stroke: black;
}
<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/3.5.17/d3.min.js"></script>
<div class="card-body" id="lineChart">
</div>

最后,作为一个提示:不要混用 D3 和 jQuery。

关于javascript - 多线图 x 轴刻度未与数据点对齐,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55535974/

相关文章:

javascript - 如何从 mapCenter 获取纬度和经度作为单独的变量

d3.js - d3.js 有反向缓动功能吗?

javascript - GeoJson 和 D3.js 多面体

javascript - html javascript 简单交换播放器转

javascript - 循环遍历数组并设置系列对象 jVectormap 的值

javascript - 是否可以通过滚动到元素来滚动元素上方/下方

java - 在 java 中运行 d3 javascript

d3.js - D3/咖啡气泡图中的不同状态

javascript - 是否可以在 d3 中将一个(或多个)布局嵌套在另一个不同的布局中?

java - 如何使用 JavaScript 加载 Google Chart API 的 session 数据