Вставка заголовка в линейный график на d3. js - PullRequest
0 голосов
/ 03 мая 2020

У меня есть эта линейная диаграмма, которая работает, но проблема в том, что я пытаюсь поместить заголовок на линейную диаграмму над ней, и она не будет работать, потому что d3. js продолжает добавлять его внутри элементов диаграмма. Как я могу это исправить? Ниже приведен фрагмент моего кода:

$(document).ready(() => {
    // set the dimensions and margins of the graph
    var margin = { top: 20, right: 20, bottom: 30, left: 50 },
        width = 1000 - margin.left - margin.right,
        height = 500 - margin.top - margin.bottom;

    // parse the date / time
    var parseTime = d3.timeParse("%H:%M:%S");


    // set the ranges
    var x = d3.scaleTime().range([0, width]);
    var y = d3.scaleLinear().range([height, 0]);

    // define the line
    var valueline = d3.line()
        .x(function (d) { return x(d.availability_time); })
        .y(function (d) { return y(d.total_hour_percentage); });

    // 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 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 + ")");

    function draw(data) {
        console.log(data[0].availability_time);

        // format the data
        data.forEach(function (d) {
            d.availability_time = (parseTime(d.availability_time));
            d.total_hour_percentage = d.total_hour_percentage;
        });

        // sort time ascending
        data.sort(function (a, b) {
            return a["availability_time"] - b["availability_time"];
        })

        // Scale the range of the data
        x.domain(d3.extent(data, function (d) {
            return d.availability_time;
        }));
        y.domain([0, d3.max(data, function (d) {
            return Math.max(d.total_hour_percentage);
        })]);

        // Add the valueline path.
        svg.append("path")
            .data([data])
            .attr("class", "line")
            .attr("d", valueline);
        // Add the X Axis
        svg.append("g")
            .attr("transform", "translate(0," + height + ")")
            .call(d3.axisBottom(x).ticks(d3.timeHour.every(1)).tickFormat(d3.timeFormat('%H:%M')));

        // Add the Y Axis
        svg.append("g")
            .call(d3.axisLeft(y));
    }

    svg.append('text')
        .attr('class', 'title')
        .attr('x', width / 2 + margin)
        .attr('y', 40)
        .attr('text-anchor', 'middle')
        .text('Availability (%) of CAM for date: ');
    // Get the data
    // var perHourResult = "/perHourAvailabilities/" + defaultDate;
    // console.log(perHourResult);

    var perHourResult =
        [
            { "id": 0, "availability_time": "00:00:00", "total_hour_percentage": 99.55 },
            { "id": 0, "availability_time": "01:00:00", "total_hour_percentage": 100.0 },
            { "id": 0, "availability_time": "02:00:00", "total_hour_percentage": 100.0 },
            { "id": 0, "availability_time": "03:00:00", "total_hour_percentage": 100.0 },
            { "id": 0, "availability_time": "04:00:00", "total_hour_percentage": 100.0 },
            { "id": 0, "availability_time": "05:00:00", "total_hour_percentage": 100.0 },
            { "id": 0, "availability_time": "06:00:00", "total_hour_percentage": 100.0 },
            { "id": 0, "availability_time": "07:00:00", "total_hour_percentage": 100.0 },
            { "id": 0, "availability_time": "08:00:00", "total_hour_percentage": 100.0 },
            { "id": 0, "availability_time": "09:00:00", "total_hour_percentage": 100.0 },
            { "id": 0, "availability_time": "10:00:00", "total_hour_percentage": 100.0 },
            { "id": 0, "availability_time": "11:00:00", "total_hour_percentage": 100.0 },
            { "id": 0, "availability_time": "12:00:00", "total_hour_percentage": 100.0 },
            { "id": 0, "availability_time": "13:00:00", "total_hour_percentage": 100.0 },
            { "id": 0, "availability_time": "14:00:00", "total_hour_percentage": 100.0 },
            { "id": 0, "availability_time": "15:00:00", "total_hour_percentage": 99.75 },
            { "id": 0, "availability_time": "16:00:00", "total_hour_percentage": 100.0 },
            { "id": 0, "availability_time": "17:00:00", "total_hour_percentage": 100.0 },
            { "id": 0, "availability_time": "18:00:00", "total_hour_percentage": 100.0 },
            { "id": 0, "availability_time": "19:00:00", "total_hour_percentage": 100.0 },
            { "id": 0, "availability_time": "20:00:00", "total_hour_percentage": 100.0 },
            { "id": 0, "availability_time": "21:00:00", "total_hour_percentage": 100.0 },
            { "id": 0, "availability_time": "22:00:00", "total_hour_percentage": 100.0 },
            { "id": 0, "availability_time": "23:00:00", "total_hour_percentage": 100.0 }
        ];

    console.log(perHourResult[0].availability_time); //shows 00:00:00

    draw(perHourResult);
});
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>DASHBOARD</title>

    <!--Lib css-->
    <!--bootstrap-->
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css"
        integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
    <!--fontawesome-->
    <link href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet"
        integrity="sha384-wvfXpqpZZVQGK6TAh5PVlGOfQNHSoD2xbE+QkPxCAFlNEevoEH3Sl0sibVcOQVnN" crossorigin="anonymous">

    <!--jquery-->
    <script src="https://code.jquery.com/jquery-3.5.0.js"
        integrity="sha256-r/AaFHrszJtwpe+tHyNi/XCfMxYpbsRg2Uqn0x3s2zc=" crossorigin="anonymous"></script>

    <!--own css-->
    <style>
        @import "https://fonts.googleapis.com/css?family=Poppins:300,400,500,600,700";

        body {
            font-family: 'Poppins', sans-serif;
            background: #fafafa;
        }

        p {
            font-family: 'Poppins', sans-serif;
            font-size: 1.1em;
            font-weight: 300;
            line-height: 1.7em;
            color: #999;
        }

        a,
        a:hover,
        a:focus {
            color: inherit;
            text-decoration: none;
            transition: all 0.3s;
        }

        .navbar {
            padding: 15px 10px;
            background: #fff;
            border: none;
            border-radius: 0;
            margin-bottom: 40px;
            box-shadow: 1px 1px 3px rgba(0, 0, 0, 0.1);
        }

        .navbar-btn {
            box-shadow: none;
            outline: none !important;
            border: none;
        }


        /* ---------------------------------------------------
    SIDEBAR STYLE
----------------------------------------------------- */

        .wrapper {
            display: flex;
            width: 100%;
            align-items: stretch;
        }

        #sidebar {
            min-width: 250px;
            max-width: 250px;
            background: rgb(60, 95, 238);
            color: #fff;
            transition: all 0.3s;
        }

        #sidebar.active {
            margin-left: -250px;
        }

        #sidebar .sidebar-header {
            padding: 20px;
            background: rgb(90, 121, 243);
        }

        #sidebar ul.components {
            padding: 20px 0;
            border-bottom: 1px solid #47748b;
        }

        #sidebar ul p {
            color: #fff;
            padding: 10px;
        }

        #sidebar ul li a {
            padding: 10px;
            font-size: 1.1em;
            display: block;
        }

        #sidebar ul li a:hover {
            color: #7386D5;
            background: #fff;
        }

        #sidebar ul li.active>a,
        a[aria-expanded="true"] {
            color: #fff;
            background: #6d7fcc;
        }

        a[data-toggle="collapse"] {
            position: relative;
        }

        .dropdown-toggle::after {
            display: block;
            position: absolute;
            top: 50%;
            right: 20px;
            transform: translateY(-50%);
        }

        ul ul a {
            font-size: 0.9em !important;
            padding-left: 30px !important;
            background: #6d7fcc;
        }

        ul.CTAs {
            padding: 20px;
        }

        ul.CTAs a {
            text-align: center;
            font-size: 0.9em !important;
            display: block;
            border-radius: 5px;
            margin-bottom: 5px;
        }

        a.download {
            background: #fff;
            color: #7386D5;
        }

        a.article,
        a.article:hover {
            background: #6d7fcc !important;
            color: #fff !important;
        }

        /* ---------------------------------------------------
    CONTENT STYLE
----------------------------------------------------- */

        #content {
            width: 100%;
            padding: 20px;
            min-height: 100vh;
            transition: all 0.3s;
        }

        /* ---------------------------------------------------
    MEDIAQUERIES
----------------------------------------------------- */

        @media (max-width: 768px) {
            #sidebar {
                margin-left: -250px;
            }

            #sidebar.active {
                margin-left: 0;
            }

            #sidebarCollapse span {
                display: none;
            }
        }

        /* ---------------------------------------------------
    CHART STYLE
----------------------------------------------------- 

        /* LINE CHART STYLE */

        .axis--x path {
            display: none;
        }

        .line {
            fill: none;
            stroke: steelblue;
            stroke-width: 1.5px;
        }
    </style>

    <!--lib js-->

    <!--bootstrap-->
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js"
        integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6"
        crossorigin="anonymous"></script>

    <!--fontawesome js-->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.13.0/js/all.min.js"></script>

    <!--d3(chart) js-->
    <script src="https://d3js.org/d3.v5.min.js"></script>

</head>

<body>
    <div class="wrapper">
        <!-- Sidebar -->
        <nav id="sidebar">
            <ul class="list-unstyled components">
                <li class="active">
                    <a href="/">DASHBOARD</a>
                </li>
            </ul>
            <!--End of nav.sidebar-->
        </nav>

        <!--Page content-->
        <div id="content">
            <!-- navbar -->
            <nav class="navbar navbar-expand-lg navbar-light bg-light">
                <div class="container-fluid">
                    <button type="button" id="sidebarCollapse" class="btn btn-info">
                        <i class="fas fa-align-justify"></i>
                    </button>
                </div>
            </nav>

            <!--End of div.row-->
            <div class="row">
                <div class="col-12">
                    <div class="card shadow mb-5">
                        <div class="card-body">
                            <div id="lineChart">
                            </div>
                        </div>
                    </div>
                </div>
            </div>
            <!--End of div.row-->
        </div>


    </div>
    <!--End of div.content-->

    </div>
    <!--End of div.wrapper-->

    <!--Lib <script>-->


    <!--own <script>-->

    <script src="js/script3.js"></script>


</body>

</html>

Я попытался создать другой элемент, чтобы удерживать svg в качестве контейнера и добавить все характеристики c линейной диаграммы под текстовым элементом, который содержит заголовок линейного графика, но в результате он добавляется в элемент <text>. Пожалуйста, помогите.

1 Ответ

1 голос
/ 03 мая 2020

переменная svg фактически является элементом, который вы добавили. Если вы хотите добавить заголовок поверх элемента, вам нужна переменная для хранения элемента. Также margin является объектом, вам необходимо указать свойство, содержащее значение.

$(document).ready(() => {
    // set the dimensions and margins of the graph
    var margin = { top: 40, right: 20, bottom: 30, left: 50 },
        width = 1000 - margin.left - margin.right,
        height = 500 - margin.top - margin.bottom;

    // parse the date / time
    var parseTime = d3.timeParse("%H:%M:%S");


    // set the ranges
    var x = d3.scaleTime().range([0, width]);
    var y = d3.scaleLinear().range([height, 0]);

    // define the line
    var valueline = d3.line()
        .x(function (d) { return x(d.availability_time); })
        .y(function (d) { return y(d.total_hour_percentage); });

    // 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 svgp = d3.select("#lineChart").append("svg")
        .attr("width", width + margin.left + margin.right)
        .attr("height", height + margin.top + margin.bottom)

     var svg= svgp.append("g")
        .attr("transform",
            "translate(" + margin.left + "," + margin.top + ")");

    function draw(data) {
        console.log(data[0].availability_time);

        // format the data
        data.forEach(function (d) {
            d.availability_time = (parseTime(d.availability_time));
            d.total_hour_percentage = d.total_hour_percentage;
        });

        // sort time ascending
        data.sort(function (a, b) {
            return a["availability_time"] - b["availability_time"];
        })

        // Scale the range of the data
        x.domain(d3.extent(data, function (d) {
            return d.availability_time;
        }));
        y.domain([0, d3.max(data, function (d) {
            return Math.max(d.total_hour_percentage);
        })]);

        // Add the valueline path.
        svg.append("path")
            .data([data])
            .attr("class", "line")
            .attr("d", valueline);
        // Add the X Axis
        svg.append("g")
            .attr("transform", "translate(0," + height + ")")
            .call(d3.axisBottom(x).ticks(d3.timeHour.every(1)).tickFormat(d3.timeFormat('%H:%M')));

        // Add the Y Axis
        svg.append("g")
            .call(d3.axisLeft(y));
    }

    svgp.append('text')
        .attr('class', 'title')
        .attr('x', width / 2)
        .attr('y', margin.top/2)
        .attr('text-anchor', 'middle')
        .text('Availability (%) of CAM for date: ');
    // Get the data
    // var perHourResult = "/perHourAvailabilities/" + defaultDate;
    // console.log(perHourResult);

    var perHourResult =
        [
            { "id": 0, "availability_time": "00:00:00", "total_hour_percentage": 99.55 },
            { "id": 0, "availability_time": "01:00:00", "total_hour_percentage": 100.0 },
            { "id": 0, "availability_time": "02:00:00", "total_hour_percentage": 100.0 },
            { "id": 0, "availability_time": "03:00:00", "total_hour_percentage": 100.0 },
            { "id": 0, "availability_time": "04:00:00", "total_hour_percentage": 100.0 },
            { "id": 0, "availability_time": "05:00:00", "total_hour_percentage": 100.0 },
            { "id": 0, "availability_time": "06:00:00", "total_hour_percentage": 100.0 },
            { "id": 0, "availability_time": "07:00:00", "total_hour_percentage": 100.0 },
            { "id": 0, "availability_time": "08:00:00", "total_hour_percentage": 100.0 },
            { "id": 0, "availability_time": "09:00:00", "total_hour_percentage": 100.0 },
            { "id": 0, "availability_time": "10:00:00", "total_hour_percentage": 100.0 },
            { "id": 0, "availability_time": "11:00:00", "total_hour_percentage": 100.0 },
            { "id": 0, "availability_time": "12:00:00", "total_hour_percentage": 100.0 },
            { "id": 0, "availability_time": "13:00:00", "total_hour_percentage": 100.0 },
            { "id": 0, "availability_time": "14:00:00", "total_hour_percentage": 100.0 },
            { "id": 0, "availability_time": "15:00:00", "total_hour_percentage": 99.75 },
            { "id": 0, "availability_time": "16:00:00", "total_hour_percentage": 100.0 },
            { "id": 0, "availability_time": "17:00:00", "total_hour_percentage": 100.0 },
            { "id": 0, "availability_time": "18:00:00", "total_hour_percentage": 100.0 },
            { "id": 0, "availability_time": "19:00:00", "total_hour_percentage": 100.0 },
            { "id": 0, "availability_time": "20:00:00", "total_hour_percentage": 100.0 },
            { "id": 0, "availability_time": "21:00:00", "total_hour_percentage": 100.0 },
            { "id": 0, "availability_time": "22:00:00", "total_hour_percentage": 100.0 },
            { "id": 0, "availability_time": "23:00:00", "total_hour_percentage": 100.0 }
        ];

    console.log(perHourResult[0].availability_time); //shows 00:00:00

    draw(perHourResult);
});
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>DASHBOARD</title>

    <!--Lib css-->
    <!--bootstrap-->
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css"
        integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
    <!--fontawesome-->
    <link href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet"
        integrity="sha384-wvfXpqpZZVQGK6TAh5PVlGOfQNHSoD2xbE+QkPxCAFlNEevoEH3Sl0sibVcOQVnN" crossorigin="anonymous">

    <!--jquery-->
    <script src="https://code.jquery.com/jquery-3.5.0.js"
        integrity="sha256-r/AaFHrszJtwpe+tHyNi/XCfMxYpbsRg2Uqn0x3s2zc=" crossorigin="anonymous"></script>

    <!--own css-->
    <style>
        @import "https://fonts.googleapis.com/css?family=Poppins:300,400,500,600,700";

        body {
            font-family: 'Poppins', sans-serif;
            background: #fafafa;
        }

        p {
            font-family: 'Poppins', sans-serif;
            font-size: 1.1em;
            font-weight: 300;
            line-height: 1.7em;
            color: #999;
        }

        a,
        a:hover,
        a:focus {
            color: inherit;
            text-decoration: none;
            transition: all 0.3s;
        }

        .navbar {
            padding: 15px 10px;
            background: #fff;
            border: none;
            border-radius: 0;
            margin-bottom: 40px;
            box-shadow: 1px 1px 3px rgba(0, 0, 0, 0.1);
        }

        .navbar-btn {
            box-shadow: none;
            outline: none !important;
            border: none;
        }


        /* ---------------------------------------------------
    SIDEBAR STYLE
----------------------------------------------------- */

        .wrapper {
            display: flex;
            width: 100%;
            align-items: stretch;
        }

        #sidebar {
            min-width: 250px;
            max-width: 250px;
            background: rgb(60, 95, 238);
            color: #fff;
            transition: all 0.3s;
        }

        #sidebar.active {
            margin-left: -250px;
        }

        #sidebar .sidebar-header {
            padding: 20px;
            background: rgb(90, 121, 243);
        }

        #sidebar ul.components {
            padding: 20px 0;
            border-bottom: 1px solid #47748b;
        }

        #sidebar ul p {
            color: #fff;
            padding: 10px;
        }

        #sidebar ul li a {
            padding: 10px;
            font-size: 1.1em;
            display: block;
        }

        #sidebar ul li a:hover {
            color: #7386D5;
            background: #fff;
        }

        #sidebar ul li.active>a,
        a[aria-expanded="true"] {
            color: #fff;
            background: #6d7fcc;
        }

        a[data-toggle="collapse"] {
            position: relative;
        }

        .dropdown-toggle::after {
            display: block;
            position: absolute;
            top: 50%;
            right: 20px;
            transform: translateY(-50%);
        }

        ul ul a {
            font-size: 0.9em !important;
            padding-left: 30px !important;
            background: #6d7fcc;
        }

        ul.CTAs {
            padding: 20px;
        }

        ul.CTAs a {
            text-align: center;
            font-size: 0.9em !important;
            display: block;
            border-radius: 5px;
            margin-bottom: 5px;
        }

        a.download {
            background: #fff;
            color: #7386D5;
        }

        a.article,
        a.article:hover {
            background: #6d7fcc !important;
            color: #fff !important;
        }

        /* ---------------------------------------------------
    CONTENT STYLE
----------------------------------------------------- */

        #content {
            width: 100%;
            padding: 20px;
            min-height: 100vh;
            transition: all 0.3s;
        }

        /* ---------------------------------------------------
    MEDIAQUERIES
----------------------------------------------------- */

        @media (max-width: 768px) {
            #sidebar {
                margin-left: -250px;
            }

            #sidebar.active {
                margin-left: 0;
            }

            #sidebarCollapse span {
                display: none;
            }
        }

        /* ---------------------------------------------------
    CHART STYLE
----------------------------------------------------- 

        /* LINE CHART STYLE */

        .axis--x path {
            display: none;
        }

        .line {
            fill: none;
            stroke: steelblue;
            stroke-width: 1.5px;
        }
    </style>

    <!--lib js-->

    <!--bootstrap-->
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js"
        integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6"
        crossorigin="anonymous"></script>

    <!--fontawesome js-->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.13.0/js/all.min.js"></script>

    <!--d3(chart) js-->
    <script src="https://d3js.org/d3.v5.min.js"></script>

</head>

<body>
    <div class="wrapper">
        <!-- Sidebar -->
        <nav id="sidebar">
            <ul class="list-unstyled components">
                <li class="active">
                    <a href="/">DASHBOARD</a>
                </li>
            </ul>
            <!--End of nav.sidebar-->
        </nav>

        <!--Page content-->
        <div id="content">
            <!-- navbar -->
            <nav class="navbar navbar-expand-lg navbar-light bg-light">
                <div class="container-fluid">
                    <button type="button" id="sidebarCollapse" class="btn btn-info">
                        <i class="fas fa-align-justify"></i>
                    </button>
                </div>
            </nav>

            <!--End of div.row-->
            <div class="row">
                <div class="col-12">
                    <div class="card shadow mb-5">
                        <div class="card-body">
                            <div id="lineChart">
                            </div>
                        </div>
                    </div>
                </div>
            </div>
            <!--End of div.row-->
        </div>


    </div>
    <!--End of div.content-->

    </div>
    <!--End of div.wrapper-->

    <!--Lib <script>-->


    <!--own <script>-->

    <script src="js/script3.js"></script>


</body>

</html>
...