如何解决折线图x轴上的重叠文本错误?

时间:2019-05-20 09:29:21

标签: javascript d3.js linechart

I am building a line chart using d3.js V4 to show date in x axis and value in y axis. when I make it responsive and turn the screen small; the x axis(date) are being overlapped 

I tried to take window.innerwidth and check it with a breakpoint to see, if the x axis is small from breakpoint it will show all dates otherwise it will show only one date between two dates.

此处调整大小功能用于调整折线图的大小。我想停止重叠,如果只显示1月,2月,3月,4月的4个月,则只显示2月和4月。 redraw()函数用于选择不同的日期后再次重绘图形。我尝试使用window.innerwidth并使用断点进行检查,以查看如果x轴距断点较小,它将显示所有日期,否则将仅显示两个日期之间有一个日期。

<!doctype html>
<html>
<head>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta content="utf-8" http-equiv="encoding">

    <title>D3</title>
    <!-- <link rel="stylesheet" type="text/css" href="mystyle1.css" /> -->

    <link rel="stylesheet" type="text/css" href="roboto.css">
    <style>
        body {
            color: #000;
        }

        .plot {
            fill: #fff;
        }

        #dateselect {
            align-content: center;
            margin-left: 10%;
            width: auto;
            height: auto;
        }

        #submit {
            margin-left: 22.5%;
        }

        tooltip {
            position: absolute;
            text-align: center;
            width: 55px;
            height: 25px;
            padding: 2px;
            font-size: 11px;
            /*font: 11px sans-serif;*/
            background: lightseagreen;
            border: 1px;
            border-radius: 8px;
            pointer-events: none;
        }

        .axis path,
        .axis line {
            fill: none;
            stroke: #AFBABF;
            shape-rendering: crispEdges;
        }

        .axis text {
            /*font-family: SourceSansPro-Bold;*/
            font-size: 14px;
            fill: #AFBABF;
        }

        .x.axis path {
            fill: none;
            stroke: grey;
            stroke-width: 1px;
            shape-rendering: crispEdges;
        }

        .y.axis path {
            fill: none;
            stroke: grey;
            stroke-width: 1px;
            shape-rendering: crispEdges;
        }

        .line {
            fill: none;
            stroke: steelblue;
            stroke-linejoin: round;
            stroke-linecap: round;
        }


        .line:hover {
            fill: none;
        }

    </style>

</head>
<!--<script src="http://d3js.org/d3.v4.min.js"></script>-->
<script src="../d3.min.js"></script>
<body>
<div id="graphic"></div>
<div id="dateselect">
    From : <input type="date" name="field1" id="field1"/>
    To : <input type="date" name="field2" id="field2"/><br/><br/>
    <input id="submit" type="button" onclick="redraw(true);" value="Submit"/>
</div>

<script>
    var margin = {};
    var x, y, xAxis, yAxis, line, svg, chartWrapper, path, width, height;

    var parseDate = d3.timeParse("%Y-%m-%d");
    var formattime = d3.timeFormat("%b %d, %y");

    var format = d3.timeFormat("%b %d");


    var myData = [

        {value: 100, date: 'january', name: 'ad1'},
        {value: 150, date: 'february', name: 'ad1'},
        {value: 125, date: 'march', name: 'ad1'},
        {value: 320, date: 'april', name: 'ad1'},
        {value: 100, date: 'may', name: 'ad1'},
        {value: 150, date: 'june', name: 'ad1'},
        {value: 125, date: 'july', name: 'ad1'},
        {value: 320, date: 'august', name: 'ad1'},
        {value: 440, date: 'september', name: 'ad1'}
    ];

    myData.forEach(function (d) {
        d.date = d.date;
        d.value = +d.value;

    });

    redraw(false);
    window.addEventListener('resize', resize);

    function resize() {
        updateDimensions(window.innerWidth);

        chartWrapper = svg.append('g');
        path = chartWrapper.append('path').datum(myData).classed('line', true);
        chartWrapper.append('g').classed('x axis', true);
        chartWrapper.append('g').classed('y axis', true);

        width = document.getElementById("graphic").offsetWidth - margin.left - margin.right;
        height = document.getElementById("graphic").offsetHeight - margin.top - margin.bottom;

        svg
            .attr('width', width + margin.right + margin.left)
            .attr('height', height + margin.top + margin.bottom);
        chartWrapper.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');
        console.log(chartWrapper);


        var breakPoint = 700;

        // Update the range of the scale with new width/height
        x.range([0, width]);
        y.range([height, 0]);

        xAxis.scale(x);
        yAxis.scale(y);

        svg.selectAll('.x.axis')
            .attr('transform', 'translate(0,' + height + ')')
            .call(xAxis);


        svg.select('.y.axis')
            .call(yAxis);

        // Force D3 to recalculate and update the line
        svg.selectAll('.line')
            .attr("d", function (d) {
                return line(d.values);
            });

//        path.attr("d", line);
//         Update the tick marks
        if (window.innerWidth < breakPoint) {
            xAxis.ticks(d3.timeMonth, 2)
            console.log(1);
        }
        else {
            xAxis.ticks(d3.timeMonth, 1)
            console.log(2);
        }

    };

    function updateDimensions(winWidth) {
//        console.log(winWidth);
        margin.top = 90;
        margin.right = 160;
        margin.left = 80;
        margin.bottom = 50;

        width = winWidth - margin.left - margin.right;
        height = 700 - margin.top - margin.bottom;
    }

    function redraw(filterByDates) {

        if (filterByDates === true) {
            d3.select('svg').remove();
        }
        if (filterByDates) {
            var date1 = document.getElementById('field1').value;
            console.log(date1);
            var date2 = document.getElementById('field2').value;
            console.log(date2);

            myData = myData.filter(function (d) {
                return d.date >= date1 && d.date <= date2;
            });
            console.log(myData);
        }
        var margin = {top: 50, right: 160, bottom: 80, left: 50},
            width = 700 - margin.left - margin.right,
            height = 500 - margin.top - margin.bottom;


        svg = d3.select("#graphic").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 + ")");

        svg.append("rect")
            .attr("width", width)
            .attr("height", height)
            .attr("class", "plot");

        var clip = svg.append("clipPath")
            .attr("id", "clip")
            .append("svg:rect")
            .attr("x", 0)
            .attr("y", 0)
            .attr("width", width)
            .attr("height", height);

        var nest = d3.nest()
            .key(function (d) {
                return d.name;
            })
            .entries(myData);

//        console.log(nest);

        var nestDate = d3.nest()
            .key(function (d) {
//                console.log(d.date);
                return d.date;
            })
            .entries(myData);
        console.log(nestDate);

        var keys = nestDate.map(function (d) {
            return d.key;
        });

        console.log(keys);

        var linedata = nestDate;
        console.log(linedata);

        x = d3.scalePoint()
            .range([0, width])
            .domain(keys);

        var xmax = d3.max(linedata, function (c) {
            return d3.max(c.values, function (v) {
                return v.date;
            });
        });
        console.log(xmax);

        y = d3.scaleLinear()
            .range([height, 0])
            .domain([0, d3.max(myData, function (d) {
                return d.value;
            })]);

        line = d3.line()
            .x(function (d) {
                return x(d.date);
            })
            .y(function (d) {
                return y(d.value);
            });


        xAxis = d3.axisBottom(x)

        yAxis = d3.axisLeft(y)

        svg.append("svg:g")
            .attr("class", " x axis");

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

        svg.select(".x.axis").call(xAxis)
            .attr("transform", "translate(0," + height + ")")

        svg.select(".y.axis").call(yAxis);


        var thegraph = svg.selectAll(".thegraph")
            .data(nest);

        console.log(thegraph);

        var thegraphEnter = thegraph.enter().append("g")
            .attr("clip-path", 'url(#clip)')
            .attr('id', function (d) {
                return d.key + "-line";
            })
            .attr("class", "thegraph")
            .style("stroke-width", 2.5)

        console.log(thegraphEnter);

        var tooltip = d3.select("body")
            .append("tooltip")
            .attr("class", "tooltip")
            .style("opacity", 0);

        thegraphEnter.append("path")
            .attr("class", "line")
            .attr("d", function (d) {
                return line(d.values);
            });

        svg.selectAll("dot")
            .data(myData)
            .enter().append("circle")
            .attr("r", 5)
            .attr("cx", function (d) {
                return x(d.date);
            })
            .attr("width", x.range())
            .attr("cy", function (d) {
                return y(d.value);
            })
            .attr("height", function (d) {
                return height - y(d.value);
            })
            .on("mouseover", function (d) {
                tooltip.transition()
                    .attr("r", 10)
                    .duration(200)
                    .style("opacity", .9);
                tooltip.html(format(parseDate(d.date)) + "<br>" + d.value)
                    .style("left", (d3.event.pageX) + "px")
                    .style("top", (d3.event.pageY - 28) + "px");
                d3.select(this).attr("r", 6).style("fill", "blue");
            })
            .on("mouseout", function (d) {
                tooltip.transition()
                    .duration(500)
                    .style("opacity", 0);
                d3.select(this).attr("r", 5).style("fill", "black");
            });
                .append("text")
            .attr("x", 255)
            .attr("transform", "rotate(0)")
            .attr("y", 20)
            .attr("dy", ".99em")
            .attr("fill", "#000")
            .attr("text-anchor", "start")
            .text("Date")
            .style("text-anchor", "end");

        svg.append("g")
            .append("text")
            .attr("x", -150)
            .attr("transform", "rotate(-90)")
            .attr("y", -40)
            .attr("dy", ".71em")
            .attr("fill", "#000")
            .attr("text-anchor", "start")
            .text("Adverts Shown")
            .style("text-anchor", "end");

        switchtoreadableformat();
    }

    function switchtoreadableformat() {
        d3.selectAll('.xAxis .tick text').each(function (p) {
            var parseDate = d3.timeParse("%Y-%m-%d");
            var formattime = d3.timeFormat("%b %d, %y");
            d3.select(this).html(formattime(parseDate(p)));
            d3.select(this).attr('originaldate', p);
        });
    }


</script>

</body>
</html>

0 个答案:

没有答案