鍍金池/ 問答/HTML/ d3.js 4.x 數(shù)據(jù)經(jīng)過遍歷后,比例尺出錯(cuò)

d3.js 4.x 數(shù)據(jù)經(jīng)過遍歷后,比例尺出錯(cuò)

數(shù)據(jù)結(jié)構(gòu):

var jsonData = [
    { "date": new Date(2018, 2, 8), "count": 22 },
    { "date": new Date(2018, 2, 9), "count": 9 },
    { "date": new Date(2018, 2, 10), "count": 3 },
    { "date": new Date(2018, 2, 11), "count": 4 },
    { "date": new Date(2018, 2, 12), "count": 16 },
    { "date": new Date(2018, 2, 13), "count": 11 },
    { "date": new Date(2018, 2, 14), "count": 11 }
];

結(jié)果顯示正常

clipboard.png

如果數(shù)據(jù)經(jīng)過遍歷后,比例尺會(huì)出現(xiàn)第一項(xiàng)被刪除

var lineData = [
    { "date": "2018-03-08", "count": 22 },
    { "date": "2018-03-09", "count": 9 },
    { "date": "2018-03-10", "count": 3 },
    { "date": "2018-03-11", "count": 4 },
    { "date": "2018-03-12", "count": 16 }, 
    { "date": "2018-03-13", "count": 11 }, 
    { "date": "2018-03-14", "count": 11 }
];

var jsonData = [];
for (var i = 0; i < length; i++) {
    var curData = lineData[i];
    curData.date = new Date(curData.date);
    jsonData.push(curData);
}

clipboard.png

完整代碼

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        .axis path,
        .axis line {
            fill: none;
            stroke: none;
            shape-rendering: crispEdges;
        }

        .xAxis path {
            stroke-dasharray: 3 2;
            stroke: #d0cfd4;
        }
        .xAxis line {
            stroke: none;
        }
        .rank-line {
            width: 650px;
            height: 240px;
        }
        .tick text {
            fill: #8b8a90;
            font-weight: 500;
            font-size: 14px;
        }
        .rank-path {
            fill: none;
            stroke: #744bfb;
            stroke-width: 3px;
        }
        .rank-fill {
        //fill: #000
        fill-opacity: .7;
        }
        .rank-date {
            color: #bfbec6;
        }
        .rank-date-line {
            stroke-dasharray: 3 2;
            stroke: #8b8a90;
        }
    </style>
</head>
<body>
<div class="wrap">
    <div class="rank-line"></div>
</div>
<script src="../node_modules/d3/build/d3.min.js"></script>
<script>
    var lineData = [
    { "date": "2018-03-08", "count": 22 },
    { "date": "2018-03-09", "count": 9 },
    { "date": "2018-03-10", "count": 3 },
    { "date": "2018-03-11", "count": 4 },
    { "date": "2018-03-12", "count": 16 },
    { "date": "2018-03-13", "count": 11 },
    { "date": "2018-03-14", "count": 11 }
    ];
    var length = lineData.length;

    var jsonData = [];
    for (var i = 0; i < length; i++) {
    var curData = lineData[i];
    curData.date = new Date(curData.date);
    jsonData.push(curData);
    }


    var lastItem = jsonData[length - 1];

    var width = 650, height = 240;
    var rangeWidth = width - 60;

    var a = d3.rgb(116, 75, 251), b = d3.rgb(255, 255, 255);

    var rankLine = d3.select('.rank-line');
    var svg = rankLine.append('svg')
    .attr('class', 'rankLine')
    .attr('width', width)
    .attr('height', height);

    var compute = d3.interpolate(a, b);

    var defs = svg.append('defs');

    var lg = defs.append('linearGradient')
    .attr('id', 'linearColor')
    .attr('x1', '0%')
    .attr('y1', '0%')
    .attr('x2', '0%')
    .attr('y2', '100%');

    lg.append('stop')
    .attr('offset', '0%')
    .style('stop-color', a.toString());

    lg.append('stop')
    .attr('offset', '100%')
    .style('stop-color', b.toString());


    var yMax = d3.max(jsonData, function (d) {
    return d.count;
    });

    var yRange = Math.ceil(yMax / 100) * 100;

    var xScale = d3.scaleTime()
    .domain(d3.extent(jsonData, function (d) {
        return d.date;
    }))
    .range([0, rangeWidth]);

    // 輸出都正常

    console.log(xScale(jsonData[0].date));
    console.log(xScale(jsonData[1].date));
    console.log(xScale(jsonData[2].date));
    console.log(xScale(jsonData[3].date));
    console.log(xScale(jsonData[4].date));
    console.log(xScale(jsonData[5].date));
    console.log(xScale(jsonData[6].date));

    var xAxis = d3.axisBottom(xScale)
    .ticks(length)
    .tickFormat(d3.timeFormat('%m月%e'));

    svg.append('g')
    .attr('class', 'axis xAxis')
    .attr('transform', 'translate(38, 220)')
    .call(xAxis);


    var yScale = d3.scaleLinear()
    .domain([yRange, 0])
    .range([0, height - 40]);

    var yAxis = d3.axisLeft(yScale)
    .ticks(5);

    var hScale = height - yScale(lastItem.count) - 40;


    var rAxis = d3.axisRight(yScale)
    .ticks(5)
    .tickSize(rangeWidth);

    svg.append('g')
    .attr('class', 'axis')
    .attr('transform', 'translate(38, 20)')
    .call(yAxis);


    var line = d3.line()
    .x(function (d) {
        return xScale(d.date);
    })
    .y(function (d) {
        return yScale(d.count);
    })
    .curve(d3.curveCardinal);

    svg
    .append('g')
    .attr('transform', 'translate(38, 20)')
    .call(customYAxis);

    var g = svg
    .append('g')
    .attr('transform', 'translate(38, 20)');


    g
    .append('path')
    .attr('class', 'rank-fill')
    .attr('d', line(jsonData) + ' l0,' + hScale + ' l-' + rangeWidth + ',0')
    .style('fill', 'url(#' + lg.attr('id') + ')');

    g
    .append('path')
    .attr('class', 'rank-path')
    .attr('d', line(jsonData));

    function customYAxis(g) {
    g.call(rAxis);
    g.select(".domain").remove();
    g.selectAll(".tick line").attr("stroke", "#d0cfd4").attr("stroke-dasharray", "3, 2");
    g.selectAll(".tick text").remove();
    }
</script>
</body>
</html>
回答
編輯回答
純妹

原因

經(jīng)過數(shù)據(jù)對(duì)比,兩個(gè)數(shù)據(jù)得到的時(shí)間結(jié)果不一樣

,如圖:

clipboard.png

經(jīng)過遍歷得來的時(shí)間對(duì)象為 08:00:00,需要使數(shù)據(jù)為時(shí)間為 0:0:0

2018年7月27日 13:16