Weird behavior with plotly chart

Weird behavior with plotly chart

offroadbikeroffroadbiker Posts: 12Questions: 2Answers: 0

The plotly charts in this datatable render properly upon showing all entries and clicking the sort column a couple of times. I can't get them to render properly when the page is first loaded.

<!DOCTYPE html>
<html>
<head>
    <title></title>
    <style type="text/css" title="currentStyle">
        @import "https://cdn.datatables.net/1.10.19/css/jquery.dataTables.css";
    </style>

    <style>
        .plotly_datatable_gauge {
            height: 1.2em;
            width: 10em;
        }
    </style>

    <script type="text/javascript" src="http://code.jquery.com/jquery-3.3.1.min.js"></script>
    <script type="text/javascript" src="https://cdn.datatables.net/1.10.19/js/jquery.dataTables.min.js"></script>
    <script type="text/javascript" src="https://cdn.plot.ly/plotly-1.42.5.min.js"></script>
    <script type="text/javascript">
        $(document).ready(function () {

            queryData = [
                [-2],
                [-56.3],
                [6.1],
                [100],
                [13.8],
                [0],
                [-15.2],
                [0.86],
                [-4.8],
                [-33.6],
                [-75.2],
                [48],
                [66.6],
                [22.5],
                [-49.9],
                [-98.6]
            ];

            let layout = {
                autosize: true,
                margin: {
                    l: 0,
                    r: 0,
                    b: 0,
                    t: 0,
                    pad: 0
                },
                hovermode: true,
                xaxis: {
                    range: [-100.0, 100.0],
                    zeroline: true,
                    zerolinecolor: "#000",
                    showgrid: false,
                    showline: false,
                    showticklabels: false
                },
                paper_bgcolor: "rgba(0,0,0,0)",
                plot_bgcolor: "#ddd"
            };

            let dataConfig = [{
                marker: {
                    color: "rgb(0, 82, 155)", // #00529B
                    line: { width: 1 }
                },
                stackgroup: null,
                mode: "markers",
                x: [],
                y: [''],
                type: "bar",
                orientation: "h"
            }];

            $('#dynamic').html('<table id="example" class="display" width="100px"></table>');
            $('#example').dataTable({
                "order": [],
                "data": queryData,
                "columns": [
                    { "title": "Activity", "sClass": "center" }
                ],
                "columnDefs": [
                    {
                        "targets": [0],
                        "render": function (data, type, full) { return data; }
                    },
                ],
                "rowCallback": function(row, data) {

                    let t_dataConfig = dataConfig;
                    t_dataConfig[0].x = data;
                    row.children[0].innerHTML = '<div class="plotly_datatable_gauge"/>';
                    Plotly.react(
                        row.children[0].children[0],
                        t_dataConfig,
                        layout,
                        { displayModeBar: false, responsive: true, displaylogo: false }
                    )
                }
            });
        });
    </script>
</head>

<body id="dt_example">

<div id="container">
    <div id="dynamic"></div>
</div>

</body>
</html>

Any ideas on how to make them render properly upon first loading of page?

This question has accepted answers - jump to:

Answers

  • kthorngrenkthorngren Posts: 20,142Questions: 26Answers: 4,736

    Its hard to say without seeing it. Please post a link to your page or a test case so we can help debug.
    https://datatables.net/manual/tech-notes/10#How-to-provide-a-test-case

    Kevin

  • offroadbikeroffroadbiker Posts: 12Questions: 2Answers: 0

    Whoops, sorry about that. I'm a first timer here.

    http://live.datatables.net/cifotihi/1/edit

    When the page first loads, the last row's charts floats on top of all others and is too large. On the first page (Showing 1 to 10 of 16 entries) the 10th chart, whose value is -33.6, floats. On the 2nd page (Showing 11 to 16 of 16 entries) the 16th chart, whose value is -98.6, floats.

    Changing the window size (e.g. forcing redraw) resolves the problem.

  • kthorngrenkthorngren Posts: 20,142Questions: 26Answers: 4,736

    I looked at this but don't have a solution. If you inspect the over sized chart you can see the width is not what is expect, for example the width is width="700":

    <svg class="main-svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="700" height="450"><defs id="topdefs-b3aec3"><g class="clips"></g></defs><g class="layer-above"><g class="imagelayer"></g><g class="shapelayer"></g></g><g class="infolayer"><g class="g-gtitle"></g><g class="g-xtitle"></g><g class="g-ytitle"></g></g><g class="menulayer"></g><g class="zoomlayer"><path class="zoombox" transform="translate(0, 0)" d="M0,0H700V450H0V0Z" style="fill: rgba(0, 0, 0, 0); stroke-width: 0;"></path><path class="zoombox-corners" transform="translate(0, 0)" d="M0,0Z" style="fill: rgb(255, 255, 255); stroke: rgb(68, 68, 68); stroke-width: 1; opacity: 0;"></path></g><g class="hoverlayer"></g></svg>
    

    However using the same code and placing the chart in a div outside the Datatable works and the inspection shows the expected width. See this example:
    http://live.datatables.net/rolewovo/1/edit

    <svg class="main-svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="100" height="17.2656"><defs id="topdefs-fa1b03"><g class="clips"></g></defs><g class="layer-above"><g class="imagelayer"></g><g class="shapelayer"></g></g><g class="infolayer"><g class="g-gtitle"></g><g class="g-xtitle"></g><g class="g-ytitle"></g></g><g class="menulayer"></g><g class="zoomlayer"><path class="zoombox" transform="translate(0, 0)" d="M0,0H100V17H0V0Z" style="fill: rgba(0, 0, 0, 0); stroke-width: 0;"></path><path class="zoombox-corners" transform="translate(0, 0)" d="M0,0Z" style="fill: rgb(255, 255, 255); stroke: rgb(68, 68, 68); stroke-width: 1; opacity: 0;"></path></g><g class="hoverlayer"></g></svg>
    

    As a work around I tried copying that div into the table but its not quite right:
    http://live.datatables.net/gefabofe/1/edit

    If I get a chance later I take a further look. Maybe @allan or @colin have ideas.

    I recommend posting a question in the plotly support area (not sure where that is). Ask them about why the SVG width doesn't follow the width of the div its going into. There may be a setting you can change to help this.

    Kevin

  • allanallan Posts: 61,446Questions: 1Answers: 10,054 Site admin
    Answer ✓

    Its a timing issue. When rowCallback is called, the dom elements are ready for use, but they haven't actually been inserted into the document yet! So they don't have any height or width, hence the sizing issue.

    Adding a small timeout let's DataTables get them into the document: http://live.datatables.net/cifotihi/3/edit .

    The other (and probably better) way would be to listen for draw, but then you need to loop over the rows, which could be done with the API.

    Also you should probably use columns.createdCell for injecting the div element. Otherwise it will be creating a new chart on every draw (sort / filter / etc).

    Allan

  • offroadbikeroffroadbiker Posts: 12Questions: 2Answers: 0

    Thank you both so much! I moved the Plotly code into drawCallback and it works mighty fine. Here it is: http://live.datatables.net/zivuhice/1/

    I would like to make the Activity column be not visible. However, when I do this, the charts disappear from the SAI column. Any ideas on how I can hide the Activity column without affecting the row charts?

  • kthorngrenkthorngren Posts: 20,142Questions: 26Answers: 4,736
    Answer ✓

    Looks like all that needs to be done is to add columns.visible false to column 0 and to change the selector and rowCallback to $('td:eq(0)', row). Here is the updated example:
    http://live.datatables.net/tejereji/1/edit

    Kevin

  • offroadbikeroffroadbiker Posts: 12Questions: 2Answers: 0

    Thank you gentlemen. Much appreciated.

    A token of gratitude: donation receipt number: 1VL97044DP488520E.

  • allanallan Posts: 61,446Questions: 1Answers: 10,054 Site admin

    Thanks :).

    Allan

This discussion has been closed.