Grist-plugin-api.js

Hello there !

I am trying to retrieve data from a filtered table in a view inside a custom widget with grist-plugin-api.
I firstly tried grist.docApi.fetchTable("Animals").then((resp) => { do stuff};
Works nicely but I filter Table in the current view it keeps the initial values (sounds logic)

so I tried instead grist.viewApi.fetchSelectedTable("Animals").then((resp) => {do stuff};
But it does not work neither, it returns all the data while the view is filtered.

Is there a simple way to do this ?

Hi @Sylvain_Page,

Unfortunately no, the custom widget doesn’t have access to the filtered data, you will always receive all rows from a table.

@jarek , thanks.
Is there anychance to get filter information from the custom-widget so we can make the filter logic inside the custom widget ?
If not Last option → Move filtering in a filter table, adding it as an editable card and fetching the information from this table to do the logic and filtering the view accordingly;

If the filters are on the custom widget itself, and you are looking for the filtered data in the table backing the custom widget itself, then you can receive filtered data by listening with grist.onRecords, see for example:
https://public.getgrist.com/doc/911KcgKA95oQ~jvUkurRFSHTY7YwVVMChmB~26
But I don’t know if that is what you are looking for @Sylvain_Page?

By the way, fetchSelectedTable() doesn’t take an argument, it just returns (all) data from the table backing the custom widget.

Hi @paul-grist ,

Thanks my bad indeed I tried to filter the table instead of the widget.
Your example is a good start as filtering with onRecords works well.
Yet in my example the chart does not update when I am filtering and remains the same.
Basically I need to perform basic test on smaller data, I suspect plotlyjs to freeze with large superposed set of data.

Thanks for your support, I’ll give you result of investigation in a couple of days.

1 Like

Hi @paul-grist ,

Thanks for your help, I’m posting there my custom widget with plotlyjs mixed chart (bars + line) & column mapping. It could certainly be pushed further adding special option for bar type etc…
I’ve seen lots of peaple wanting better chart inetgration, but I do believe it is quite complex to handle all cases and customization… (having a look at grist-core source for the charting file glupsss).

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <title>My Grist Chart Widget</title>
    <!-- Include Plotly.js library -->
    <script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
    <script src="https://docs.getgrist.com/grist-plugin-api.js"></script>
  </head>

  <body>
    <!-- Create a container element for the chart -->
    <div id="myDiv" style="position: relative; height: 100vh"></div>

    <script>
      // Wait for the Grist API to be ready
      grist.ready({
        columns: ["Date", "Result", "Target"],
        requiredAccess: "read table",
      });

      const plotDiv = document.getElementById("myDiv");

      // Set the height and width of the Plotly chart to match the iframe
      const layout = {
        autosize: true,
        margin: {
          l: 5,
          r: 5,
          t: 5,
          pad: 0,
        },
      };

      const config = {
        displayModeBar: false, // this is the line that hides the bar.
        responsive: true,
      };

      // When a new record is selected in the Grist table, render a chart based on its data
      grist.onRecords(function (records, mappings) {
        let mapped = grist.mapColumnNames(records);
        if (mapped) {
          // mJson = mapped Json from mapped column
          let mResults = mapped.map(({ Result, Date }) => ({ Result, Date }));
          let mTargets = mapped.map(({ Target, Date }) => ({ Target, Date }));
          mTargets.sort((a, b) => {
            return a.Date - b.Date;
          });

          let traceResult = {
            x: mResults.map((obj) => obj.Date),
            y: mResults.map((obj) => obj.Result),
            type: "bar",
          };
          let traceTarget = {
            x: mTargets.map((obj) => obj.Date),
            y: mTargets.map((obj) => obj.Target),
            type: "scatter",
          };

          let data = [traceResult, traceTarget];
          Plotly.newPlot("myDiv", data, layout, config);
        } else {
          // Helper returned a null value. It means that not all
          // required columns were mapped.
          console.error("Please map all columns");
        }
      });
    </script>
  </body>
</html>
1 Like

If you apply filters directly to the custom widget (not another widget with the same data table) then grist.viewApi.fetchSelectedTable (or just grist.fetchSelectedTable) will use those filters. It also uses the filtering from ‘Select by’. Maybe this was only implemented recently, although I can’t see any sign of such changes.

Hello @Alex_Hall ,

Yes this is now ok for me.I’m using grist.onRecords and filter widget, works well.