1

TL;DR - the .on event listner in Plotly JS seems to be undefined, therefore I can't setup any interactive graph features.

Details:

Using Ploty JS in a Flask project, I am creating several graphs as div's in a boostrap grid and then filling them with graphs from a element. The graphs are plottings four different features of a audio waveform with timestamps, plus the waveform, so I would like to synchronize the axis zooms across the four charts. enter image description here

The HTML for this page looks like this:


<script src="{{ url_for('static', filename='js/d3.v7.min.js') }}"></script>
<script src="{{ url_for('static', filename='js/jquery-3.3.1.slim.min.js') }}"></script>
<script src="{{ url_for('static', filename='js/plotly-2.9.0.js') }}"></script>

...

<div class="row">
    <div class="col-6">
        <div id="zcs_plot" style="width:auto; height:225px;"></div>
        <div id="energy_plot" style="width:auto; height:225px;"></div>
    </div>
    <div class="col-6">
        <div id="centroid_plot" style="width:auto; height:225px;"></div>
        <div id="spectrogram_plot" style="width:auto; height:225px;"></div>
    </div>
</div>
<div class="row">
    <div class="col-12">
        <div id="audio_plot" style="width:auto; height:225px;"></div>
    </div>
</div>
<div class="row">
    <div class="col-12">
        <audio style="width: 100%" controls>
            <!--source src="{{wav_json}}" type="audio/wav"-->
            <source src="{{url_for('soundserve', day=file_day, hour=file_hour, file=file_file)}}"
                    type="audio/wav">
        </audio>
    </div>
</div>

Using the example code from Plotly's website (https://plotly.com/javascript/zoom-events/), and refining based on the example in this post (How do I synchronize the zoom level of multiple charts with Plotly.js?) it looks like I need to use the .on() event listener from Plotly in the JS.

<script type="text/javascript">
    console.log(Plotly.version)
    console.log(d3.version)

    //ZCS
    var zcs_plot = document.getElementById('zcs_plot');
    data = d3.json("{{ url_for('zcs_stat', day=file_day, hour=file_hour, file=file_file) }}").then(
        json => {
            const data = json.data;
            var layout = {
                title: {text: "Zero Crossings (per sec)", font:{color: "#F0F0F0"}},
                xaxis:{gridcolor:'#252525', gridwidth: 1, tickfont: {color: "#F0F0F0"} },
                yaxis:{gridcolor:'#252525', gridwidth: 1, tickfont: {color: "#F0F0F0"} },
                showlegend: false,
                margin: {t: 30, b: 40, l: 30, r: 5},
                paper_bgcolor: "black",
                plot_bgcolor: "black"
            }
            plt = Plotly.newPlot(zcs_plot,
                data,
                layout,
                {displayModeBar: false}
            );
            }
        ).catch(error => {
            console.error(error);
        }
    );

    //...^^that is repeated for the other 4 graphs as well

    zcs_plot.on('plotly_relayout',
    function(eventdata){
        alert( 'ZOOM!' + '\n\n' +
            'Event data:' + '\n' +
             JSON.stringify(eventdata) + '\n\n' +
            'x-axis start:' + eventdata['xaxis.range[0]'] + '\n' +
            'x-axis end:' + eventdata['xaxis.range[1]'] );
    });
    //...the production version of this will loop over each plots and then update all, but for TS this should work

</script>

However, when I try to run this page, I get the following error in the web console:

(index):294 Uncaught TypeError: zcs_plot.on is not a function
    at (index):294:16
(anonymous) @ (index):294

and the page doesn't exhibit the expected response when I zoom the graph.

I also looked at this post: Plotly javascript. 'plotly_click' gets on is not a function, which appears to be almost the exact same problem, but I can't even make the accepted solution there work either. Possibly something has changed that didn't get updated in the Docs.

Note: btw I have tried linking the source JS directly from the CDNs as a web url instead of using a locally downloaded version, same results. I'm using local downloads because ultimately this app will be deployed in a location with poor to no internet service.

1 Answer 1

0

Plotly adds the "on" function to the div once the chart is initialized. Your chart is initialized asynchronously in a callback after getting the data from a json file. Your zcs_plot.on() is most likely called before the chart is even there. In order to prevent this, you should call zcs_plot.on() in the callback after Plotly.newPlot().

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.