数据点未正确放置在x轴上

时间:2017-04-03 15:10:11

标签: javascript d3.js

大家好我正在d3中构建一个区域线图,一切都很顺利,直到我创建了一个网格并发现数据点和线与x轴不正确对齐。正如您在JSfiddle中看到的那样,数据点位于网格右侧以及x轴刻度线稍微多一点。我让几个人检查出来,但没有人能找到解决方案,我怀疑它与之有关:

xLine.domain(d3.extent(data, function(d) { return d.date; }));

也可能是网格和x轴没有正确放置。

我创建了一个具有相同问题的JSfiddle: https://jsfiddle.net/kmafcLh2/

提前多多感谢!

2 个答案:

答案 0 :(得分:1)

不使用Date.parse,而是使用D3方法d3.timeParse

var parseTime = d3.timeParse("%Y-%m-%d")

data.forEach(function(d) {
    d.date = parseTime(splitDate(d));
})

以下是工作代码,圆圈和面积图与时间刻度匹配:

var line1_data = [{
  "date": "2017-03-22",
  "value": 5742008
}, {
  "date": "2017-03-23",
  "value": 4394721
}, {
  "date": "2017-03-24",
  "value": 3275048
}, {
  "date": "2017-03-25",
  "value": 2693866
}, {
  "date": "2017-03-26",
  "value": 2773392
}];

// set the dimensions and margins of the graph
var marginLine = {
    top: 30,
    right: 40,
    bottom: 30,
    left: 85
  },
  widthLine = parseInt(d3.select('.line-chart').style('width'), 10) - marginLine.right - marginLine.left,
  heightLine = parseInt(d3.select('.line-chart').style('width'), 10) * 0.5 - marginLine.top - marginLine.bottom;

// set the ranges
var xLine = d3.scaleTime()
  .range([0, widthLine]);

var yLine = d3.scaleLinear().range([heightLine, 0]);

// define the line
var valueline = d3.line()
  .x(function(d) {
    return xLine(d.date);
  })
  .y(function(d) {
    return yLine(d.value);
  });

var area = d3.area()
  .x(function(d) {
    return xLine(d.date);
  })
  .y0(heightLine)
  .y1(function(d) {
    return yLine(d.value);
  });

var divLine = d3.select('body').append("div")
  .attr('class', 'chart-tooltip')
  .style("opacity", 0);

// gridlines in x axis function
function make_x_gridlines() {
  return d3.axisBottom(xLine)
    .ticks(10)
}

// gridlines in y axis function
function make_y_gridlines() {
  return d3.axisLeft(yLine)
    .ticks(5)
}


// append the svg obgect to the body of the page
// appends a 'group' element to 'svg'
// moves the 'group' element to the top left margin
var svgLine = d3.select(".line-chart").append("svg")
  .attr("width", widthLine + marginLine.left + marginLine.right)
  .attr("height", heightLine + marginLine.top + marginLine.bottom)
  .append("g")
  .attr("transform",
    "translate(" + marginLine.left + "," + marginLine.top + ")");

function splitDate(data) {
  var dateLine = data.date.split('T');
  return dateLine[0];


}
// Get the data
data = line1_data

var parseTime = d3.timeParse("%Y-%m-%d")

data.forEach(function(d) {
  d.date = parseTime(splitDate(d));
})

//if (error) throw error;
var maxYLine = d3.max(data, function(d) {
  return d.value + d.value * 0.1;
});

var ticklength = data.length;


// Scale the range of the data
xLine.domain(d3.extent(data, function(d) {
  return d.date;
}));
yLine.domain([0, maxYLine]);
// Add the valueline path.
svgLine.append("path")
  .data([data])
  .attr("class", "line")
  .attr("d", valueline);

svgLine.append("linearGradient")
  .attr("id", "temperature-gradient")
  .attr("gradientUnits", "userSpaceOnUse")
  .attr("x1", 0).attr("y1", yLine(data.value))
  .attr("x2", 0).attr("y2", yLine(heightLine))
  .selectAll("stop")
  .data([{
    offset: "0%",
    color: "#a7e1b8"
  }, {
    offset: "100%",
    color: "white"
  }])
  .enter().append("stop")
  .attr("offset", function(d) {
    return d.offset;
  })
  .attr("stop-color", function(d) {
    return d.color;
  });

svgLine.append("path")
  .data([data])
  .attr("class", "area")
  .attr("d", area);

svgLine.selectAll("circle")
  .data(data)
  .enter()
  .append("circle")
  // .on('mouseover', function() {
  //     divLine
  //         .attr('class', 'chart-tooltip')
  //         .html("<div class='line-tooltip'>" +
  //             "fjnaidnasjdnasjdnasjdn" +
  //             "</div>")
  //     divLine
  //         .style('top', d3.event.pageY - 40 + 'px')
  //         .style('left', d3.event.pageX - parseInt(d3.select('.chart-tooltip').style('width')) + 'px');
  //
  //     divLine.transition()
  //         .duration(200)
  //         .style('opacity', .9);
  //
  // })
  // .on('mouseout', function(d) {
  //     divLine
  //         .transition()
  //         .duration(200)
  //         .style('opacity', 0);
  // })

.attr("r", 4)
  .attr("cx", function(d) {
    return xLine(d.date)
  })
  .attr("cy", function(d) {
    return yLine(d.value)
  })
  .attr("fill", "#2ECC71")
  .attr("stroke", "#2ECC71");

// add the X gridlines
svgLine.append("g")
  .attr("class", "grid")
  .attr("transform", "translate(0," + heightLine + ")")
  .call(make_x_gridlines()
    .tickSize(-heightLine)
    .tickFormat("")
  )

// add the Y gridlines
svgLine.append("g")
  .attr("class", "grid")
  .call(make_y_gridlines()
    .tickSize(-widthLine)
    .tickFormat("")
  )
  // Add the X Axis
svgLine.append("g")
  .attr("transform", "translate(0," + heightLine + ")")
  .call(d3.axisBottom(xLine)
    .tickFormat(d3.timeFormat("%B %d"))
    .ticks(ticklength)
  );

// Add the Y Axis
svgLine.append("g")
  .call(d3.axisLeft(yLine));
/* Bar chart */

.bar-chart {
  position: relative;
}

.bar-chart-tooltip {
  position: absolute;
  background-color: #f3f3f3;
  padding: 0.5em;
  pointer-events: none;
  z-index: 1000;
}

.chart-tooltip {
  position: absolute;
  background-color: #f3f3f3;
  padding: 0.5em;
  pointer-events: none;
}

.bar {
  transition: opacity 1s;
}

.bar:hover {
  opacity: 0.5;
}

.number {
  font-weight: 600;
}

.domain {
  stroke: none;
}

.arrow-up {
  position: absolute;
  width: 0px;
  height: 0px;
  border-left: 30px solid transparent;
  border-right: 30px solid transparent;
  border-bottom: 30px solid #f3f3f3;
}

.div-container {
  display: flex;
  justify-content: space-around;
}

.section-label {
  display: inline-block;
  width: 33%;
  text-align: center;
  border-right: 1px solid #707070;
  color: #707070;
}

.x-axis line {
  display: none;
}

.section-label:last-child {
  border-right: none;
}

text {
  font-size: 14px;
  fill: grey;
}


/*horizontal stacked chart*/


/* Line chart */

.line-chart .grid line {
  stroke: lightgrey;
  stroke-opacity: 0.7;
  shape-rendering: crispEdges;
}

.line-chart .grid path {
  stroke-width: 0;
}

.line {
  fill: none;
  stroke: #2ecc71;
  stroke-width: 4px;
}

.area {
  fill: url(#temperature-gradient);
  stroke-width: 05px;
}


/* multi-line */


/* Pie chart */

.pie-chart text {
  fill: white;
}

.arc path {
  transition: opacity 1s;
}

.arc path:hover {
  opacity: 0.5;
}


/*CircleChart*/

.percentageText {
  display: block;
  font-size: 48;
}

.percentageTextSmall {
  font-size: 33;
}


/* Scatter plot */

.dot {
  transition: opacity 1s;
}

.dot:hover {
  opacity: 0.5;
}


/* Map chart */


/* Bar small chart */

.x-axis .tick text {
  display: none;
}

.bar-small-chart {
  position: relative;
}
<script src="https://d3js.org/d3.v4.min.js"></script>
<div class="line-chart">
</div>

答案 1 :(得分:0)

看起来问题在于解析日期。 Javascript,由deafult将任何新日期放入浏览器的时区,例如&#34; 2017-02-02&#34;可能会在美国中部时间(UTC-6)成为Date(2017, 2, 1, 18, 0, 0)。可能如果您只使用Date.UTC,您可以获得所需的结果。