Report Sorting

I am working on building a report function within my database, but the feature in Knack does not seem to allow basic functions like sorting. For instance If I am displaying a field on a bar graph and it calculates the total record count. I cannot sort that total record count by high to low. I can only sort by fields in the table.

I am working on creating a top ten list for their results. So getting the record count was the first step, but now I need to sort by that record count High to Low, and that doesnt seem to be a function.

Any advice?

Hi @Ben3,
This is one I’ve wanted to solve for a while. I’ve developed a JS solution (with a little help from ChatGPT) that allows you to sort (asc or desc) and specify top N results that you want to see.


Code

Click here to expand for the code
$(document).on('knack-view-render.any', function (event, view, data) {

  if (view.key === 'view_xx') {
    sortChart({ chartId: '#kn-report-view_xx-1', topN: 5, descending: true });
    sortChart({ chartId: '#kn-report-view_xx-2' });
  }
  
});

// -----------------------------------------------------------------------------------------------
// Purpose: Sorts a Highcharts chart by value, and limits to top N results
function sortChart({ chartId, topN, descending = false, sortSeriesIndex = 0 }) {

  const chart = Highcharts.charts.filter(c => c && c.renderTo && c.renderTo.closest(chartId)).pop(); // Find the latest chart in this container (last one is the newest)
  if (!chart) return; // Exit if chart does not exist

  const categories = chart.xAxis[0].categories;

  const combined = categories.map((cat, i) => {
    const sortValue = chart.series[sortSeriesIndex]?.data[i]?.y || 0;
    return { category: cat, sortValue, values: chart.series.map(s => s.data[i]?.y || 0) };
  });

  combined.sort((a, b) => descending ? b.sortValue - a.sortValue : a.sortValue - b.sortValue); // Sort by the chosen series' value
  const topData = topN ? combined.slice(0, topN) : combined; // Get top N (if specified)
  chart.xAxis[0].setCategories(topData.map(d => d.category), false); // Update categories
  chart.series.forEach((s, idx) => {
    s.setData(topData.map(d => d.values[idx]), true);
  });
}

Explanation:

  • view_xx - The view that contains your charts
  • #kn-report-view_xx-1 - The first chart’s ID within your view
  • #kn-report-view_xx-2 - The second chart’s ID within your view
  • topN: X - An optional parameter to only include the top X items
  • descending: true - An optional parameter to sort from highest to lowest value
  • sortSeriesIndex: X - An optional parameter to sort by a different series in the chart if you have multiple (default is 0)

You can identify your chart ID’s using the browser’s developer/inspect tool:


Preview

Before:

After:


Limitations

  • This code does not work for pivot tables or pie charts, but will work for column/bar, line, and area charts.

Feel free to DM me if you’d like some help installing the code!

2 Likes