How to feed the result of flux query to Business Graph plugin

  • What Grafana version and what operating system are you using?
    Grafana 11, Windows, InfluxDB2.0, querying with Flux

  • What are you trying to achieve?
    Create a graph visualization of each column names as x-axis and the row values in y-axis

  • How are you trying to achieve it?
    Query a table with columns x1…xn and set it as x-axis.
    Then set the data values where each row is one graph.

  • What happened?
    Clueless how to bring that queried data to the javascript code.

  • What did you expect to happen?
    This is what happened with a static data (also see code below for reference!)

  • Can you copy/paste the configuration(s) that you are having problems with?
    Here’s the code in JavaScript for static values:

const columns = ["X_1", "X_2", "X_3", "X_4", "X_5", "X_6", "X_7", "X_8", "X_9", "X_10", "X_11", "X_12", "X_13", "X_14", "X_15", "X_16"];
const data = [-0.63, 1.86, 0.36, 0.05, -2.48, 1.68, 1.34, 0.31, -0.94, 4.12, 0.55, 1.55, -0.55, 2.56, 1.85, 1.96];  // Example data from one row

const seriesData = columns.map((col, index) => ({ name: col, value: data[index] }));

const options = {
  backgroundColor: 'transparent',
  tooltip: {
    trigger: 'axis',
  },
  legend: {
    data: ['Values'],
    textStyle: {
      color: 'rgba(128, 128, 128, .9)',
    },
  },
  xAxis: {
    type: 'category',
    data: columns,
    axisLabel: {
      interval: 0,
      rotate: 45,
    },
  },
  yAxis: {
    type: 'value',
  },
  series: [
    {
      name: 'Values',
      type: 'line',
      data: seriesData,
    },
  ],
};

return options;

  • Did you receive any errors in the Grafana UI or in related logs? If so, please tell us exactly what they were.
    Not really.
  • Did you follow any online instructions? If so, what is the URL?
    The official business graph tutorials don’t have examples of dynamic data fetches…:frowning:

Hey, I think this code might work for your situation.

// Function to extract unique columns from all series
function getUniqueColumns(series) {
  const columnSet = new Set();
  series.forEach(s => {
    s.fields.filter(f => f.type === 'number').forEach(field => {
      columnSet.add(field.name);
    });
  });
  // Convert set to array and sort the columns numerically by extracting the number part
  return Array.from(columnSet).sort((a, b) => {
    const numA = parseInt(a.match(/\d+/)[0], 10); // Extracts number from strings like 'X_1'
    const numB = parseInt(b.match(/\d+/)[0], 10);
    return numA - numB;
  });
}

// Assuming you have access to the panel data like this:
const series = context.panel.data.series.map((s) => {
  // Get unique columns for this series dynamically
  const columns = getUniqueColumns([s]); // Pass current series to find its columns

  // Generate a series for each row of data
  return s.fields.find(f => f.type === 'number').values.map((_, index) => {
    const data = columns.map(col => {
      const field = s.fields.find(f => f.name === col);
      const value = field ? field.values[index] : null; // Check if the field exists
      return [col, value];
    }).filter(pair => pair[1] !== null); // Filter out any pairs that didn't have a field

    return {
      name: `${s.refId} Row ${index + 1}`,
      type: 'line',
      showSymbol: false,
      lineStyle: {
        width: 1,
      },
      data: data,
    };
  });
}).flat(); // Flatten the array as map within map produces an array of arrays

return {
  backgroundColor: 'transparent',
  tooltip: {
    trigger: 'axis',
  },
  xAxis: {
    type: 'category',
    data: getUniqueColumns(context.panel.data.series), // Get unique columns from all series
    axisLabel: {
      interval: 0, // Display all labels
      rotate: 45,  // Rotate labels if they are too long
    },
  },
  yAxis: {
    type: 'value',
  },
  grid: {
    left: '2%',
    right: '2%',
    top: '2%',
    bottom: 24,
    containLabel: true,
  },
  series,
};

Thanks!