1

So I am working on a dashboard in which there are bunch of KPIs and Graphs. The dashboard have filters that when applied, filter whole dashboard. Before I was totally reloading the page and every thing was updated perfectly. But then I decided to make it update without reloading. For that purpose I had to use AJAX JS and I have very less experience in JS. Now the problem I am facing is that on the backend the data is updated and new graphs are also generated. On front end the KPIs are also updated without reload but the graphs are not updated immediately. But when I reload the page manually then the new graphs are shown.

Below is the app route in Flask Python that fetch all the filtered data from database and return then in json format.

@app.route("/update_dashboard", methods=["POST"])
@login_required
def update_dashboard():
    filters = request.get_json()
    for key in filter_state:
        filter_state[key] = filters.get(key, [])

    # KPIs
    overview_kpis = incidents_overview_kpi_data()
    dept_kpis = departments_overview_kpis()
    type_kpis = incident_types_overview_kpis()

    # Charts
    fig1, fig2 = get_incident_overview_figures()
    dept_donut, dept_bar = get_department_overview_figures()
    type_donut, type_bar = get_incident_type_overview_figures()
`your text`
    with open("incident_fig1_debug.json", "w") as f:
        f.write(json.dumps(json_item(fig2, "incident-chart"), indent=2))

    return jsonify({
        "overview_kpis": {
            "total_incidents": overview_kpis["total"],
            "total_injuries": overview_kpis["injuries"],
            "total_days_lost": overview_kpis["days_lost"],
        },
        "dept_kpis": {
            "total_by_department": dept_kpis["by_department"],
            "most_incidents_department": dept_kpis["most_incidents_dept"],
            "most_injuries_department": dept_kpis["most_injuries_dept"],
        },
        "type_kpis": {
            "total_by_type": type_kpis["by_type"],
            "most_common_type": type_kpis["most_common_type"],
            "most_severe_type": type_kpis["most_severe_type"]
        },
        "incident_fig1": json_item(fig1, "incident-chart"),
        "incident_fig2": json_item(fig2, "injury-chart"),
        "dept_donut": json_item(dept_donut, "dept-donut"),
        "dept_bar": json_item(dept_bar, "dept-bar"),
        "type_donut": json_item(type_donut, "type-donut"),
        "type_bar": json_item(type_bar, "type-bar"),

        "applied_filters": filter_state
    })

I receive the data from /update_dashboard in this JS function:

function applyFilters() {
        const form = document.getElementById("filter-form");
        const formData = new FormData(form);
        const filters = {};

        // Extract filters from form
        for (const [key, value] of formData.entries()) {
            if (!filters[key]) filters[key] = [];
            filters[key].push(value);
          }

          // Send filters via AJAX
          fetch("/update_dashboard", {
            method: "POST",
            headers: { "Content-Type": "application/json" },
            body: JSON.stringify(filters),
          })
            .then((res) => res.json())
            .then((data) => {
              // Update filters and KPIs
              updateAppliedFilters(data.applied_filters);
              updateKPI("total-incidents", data.overview_kpis.total_incidents);
              updateKPI("total-injuries", data.overview_kpis.total_injuries);
              updateKPI("total-days-lost", data.overview_kpis.total_days_lost);
              updateKPI("dept-most", data.dept_kpis.most_incidents_department);
              updateKPI("dept-injuries", data.dept_kpis.most_injuries_department);
              updateKPI("type-most", data.type_kpis.most_common_type);
              updateKPI("type-severe", data.type_kpis.most_severe_type);
              updateDepartmentDistribution(data.dept_kpis.total_by_department);
              updateIncidentTypeDistribution(data.type_kpis.total_by_type);

              // Clear existing Bokeh state
              for (const key in Bokeh.index) {
                if (Bokeh.index.hasOwnProperty(key)) {
                  delete Bokeh.index[key];
                }
              }
              Bokeh.index = {};

              // Reset plot containers (hide → reflow → show)
              const plotDivs = [
                "incident-chart",
                "injury-chart",
                "dept-donut",
                "dept-bar",
                "type-donut",
                "type-bar",
              ];

              plotDivs.forEach((id) => {
                const el = document.getElementById(id);
                el.innerHTML = "";            // Clear previous plot
                el.style.display = "none";    // Hide
                void el.offsetWidth;          // Force reflow
                el.style.display = "block";   // Show
              });

              // Log debug (optional)
              if (data.incident_fig1) {
                console.log("✅ New incident_fig1 received, re-embedding...");
              }

              // Re-embed all plots using requestAnimationFrame x2
              requestAnimationFrame(() => {
                requestAnimationFrame(() => {
                  Bokeh.embed.embed_item(data.incident_fig1, "incident-chart");
                  Bokeh.embed.embed_item(data.incident_fig2, "injury-chart");
                  Bokeh.embed.embed_item(data.dept_donut, "dept-donut");
                  Bokeh.embed.embed_item(data.dept_bar, "dept-bar");
                  Bokeh.embed.embed_item(data.type_donut, "type-donut");
                  Bokeh.embed.embed_item(data.type_bar, "type-bar");
                });
              });
            });
        }
  • I am clearing the plots from respected divs before adding new ones

Now in this these things are confirm and verified:

  1. The target div ids are correct and plots are assigned to correct divs
  2. The plots are successfully generated before the embedding take place
  3. The plots are there on screen but they don't show up/display until I reload.

Here are some visuals of what's happening:

Before applying any filter

After applying filter (the graphs are gone but new graphs are generated on backend and kpis are updated)

After reloading page (new graphs are here)

I have tried setting a wait time for graphs to be embedded with the divs but still the issue is as it is. I have verified all the div ids match the ids I am trying to target in embedding.

0

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.