I would like to get a 2-dimensional array of data to create a stacked bar graph

###Goal
I would like to create a stacked bar graph.
└x-axis: Event name
└y-axis: Sales per member
└Legend: Member name

###Chart Plugin
I edit following Google Charts for my own use.

###Database Table Sample
| Event name | Member name | Sales |
| Event1 | MemberA | 500 |
| Event1 | MemberB | 300 |
| Event1 | MemberA | 1,000 |
| Event2 | MemberA | 3,000 |
| Event2 | MemberB | 4,000 |
| Event3 | MemberA | 3,000 |
| Event3 | MemberC | 1,000 |

Help

Here, if we could get the following data on the bubbles, there would be no problem, but there are two points that we consider difficult. 1.

  1. we do not know how to get data from bubbles in the form of a 2-dimensional array like [‘Event1’: 1500, 300, 0].
  2. if the data for sales is 0, the record is not generated and the value is stuffed

[‘MemberA’, ‘MemberB’, ‘MemberC’]
[‘Event1’: 1500, 300, 0]
[‘Event2’: 3000, 4000, 0]
[‘Event3’: 0, 0, 1000]

I am having trouble with this issue very much time.
Please someone help me.
If I am missing any necessary information, please ask.

I did something like this quite a while back with a lot of help from Stack Overflow. I have tried to adapt it to your case and hopefully it works for you or at least gives you some ideas. Essentially, you can’t create a matrix structure in the Bubble database so I needed to create a pivot table on the fly using javascript in the html element that displays the chart.

Try the following code in a html element and replace the arrays with your searches to make them dynamic (see first screenshot).

Edit: Code with hard-coded values did not work so I have updated to remove the values. Just insert your searches instead as shown in the first screenshot.

<html>
<head>
<!--Load the AJAX API-->
    <script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
    <script type="text/javascript">
  // Create and populate the data table.
google.charts.load('current', {'packages':['corechart', 'table']});
google.charts.setOnLoadCallback(drawVisualization);
function drawVisualization() {
     
var events= [""]; //insert your search for events' event names between the quotes and join with a comma within double quotes. See screenshot
var members = [""]; //insert your search for events' member names between the quotes and join with a comma within double quotes. See screenshot
var sales = []; //insert your search for events' sales between the square brackets and join with a comma. See screenshot

console.log(sales)  
var data = new google.visualization.DataTable();
  data.addColumn('string', 'Event');
  data.addColumn('string', 'Member');  
  data.addColumn('number', 'Sales');
  
  for(i = 0; i < events.length; i++)
    data.addRow([events[i], members[i], sales[i]]);

var distinctValues = data.getDistinctValues(1);
  
  var viewColumns = [0, 1];
    var groupColumns = [];
    // build column arrays for the view and grouping
    for (var i = 0; i < distinctValues.length; i++) {
        viewColumns.push({
            type: 'number',
            label: distinctValues[i],
            calc: (function (x) {
                return function (dt, row) {
                    return (dt.getValue(row, 1) == x) ? dt.getValue(row, 2) : 0;
                }
            })(distinctValues[i])
        });
        groupColumns.push({
            //column: i+2,
            column: viewColumns.length - 1,
            type: 'number',
            //label: distinctValues[i],
            aggregation: google.visualization.data.sum
        });
    }
	
	data.sort({column: 0, desc: false},{column: 1, desc: false}); 
     var view = new google.visualization.DataView(data);
    view.setColumns(viewColumns);
    
    // next, we group the view on column A, which gets us the pivoted data
    var pivotedData = google.visualization.data.group(view, [0], groupColumns);



    // draw agg table
    new google.visualization.ChartWrapper({
      chartType: 'Table',
      containerId: 'table-div',
      dataTable: pivotedData
    }).draw();

        var options = {
          vAxis: {title: 'Sales (totals)'},
          hAxis: {title: 'Members', maxTextLines: 3},
          seriesType: 'bars',
          legend: {position: 'top', maxLines: 1, alignment:'center'},
          isStacked: 'true'
        };

  // Create and draw the visualization.
 new google.visualization.ComboChart(document.getElementById('curve_chart')).
    draw(pivotedData, options);

  
      };
    </script>
  </head>
  <body>
    <div id="curve_chart" style="width: 600px; height: 400px" align="center"></div>
<div id="table-div" style="width: 600px; left: 100px" align="center"></div>
  </body>
</html>

3 Likes

Kudos @louisadekoya :+1: :+1: :+1:

1 Like

Thank you for your thoughtful response.
They really helped me. I was able to create a stacked bar graph almost exactly as I wanted.
However, there is one mysterious glitch.

It is that two names of the same event/member are displayed.
For example, the following table is being displayed. (Table ① in the screenshot)

I have tried many times to resolve this to no avail.
However, in the course of my various explorations, I confirmed a strange phenomenon.

For example, when I added a new record as shown below, it was updated from table ① in the screenshot to table ② in the screenshot. (The red square is the part that was updated.)

| Event2 | MemberC | 200 |


Each time a new record is added, the member name of the new record is duplicated, and conversely, the previously duplicated member name is returned to one.

I am very troubled by this phenomenon.
If you could help me out it would be greatly appreciated.

Hi @hideyamiyazaki0037 ,

I’m pleased to learn that my suggestion helped and that you have made some progress. The new issues you describe are indeed strange. It would be useful to see the following:

  1. Your data structure and data in Bubble for the records in your example above.
  2. Your code for the chart
  3. Screenshots of your search criteria for the variables used in the code.

I’m not an expert with charts or with Javascript by any means but I may be able to spot something.

Thanks for your response!
If I’m missing some information, please let me know.

  1. My data structure is shown in screenshot (1).
    I don’t think it has anything to do with this issue, but there is actually a table called “Merchandise” for each event. And sales are stored in a separate table called “Event/member merchandise sales”. This stores which Member sold which Merchandise in which Event.

  2. The code is as follows, as I have not changed the one you provided.

<html>
<head>
<!--Load the AJAX API-->
    <script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
    <script type="text/javascript">
  // Create and populate the data table.
google.charts.load('current', {'packages':['corechart', 'table']});
google.charts.setOnLoadCallback(drawVisualization);
function drawVisualization() {
     
var events= [""]; //insert your search for events' event names between the quotes and join with a comma within double quotes. See screenshot
var members = [""]; //insert your search for events' member names between the quotes and join with a comma within double quotes. See screenshot
var sales = []; //insert your search for events' sales between the square brackets and join with a comma. See screenshot

console.log(sales)  
var data = new google.visualization.DataTable();
  data.addColumn('string', 'Event');
  data.addColumn('string', 'Member');  
  data.addColumn('number', 'Sales');
  
  for(i = 0; i < events.length; i++)
    data.addRow([events[i], members[i], sales[i]]);

var distinctValues = data.getDistinctValues(1);
  
  var viewColumns = [0, 1];
    var groupColumns = [];
    // build column arrays for the view and grouping
    for (var i = 0; i < distinctValues.length; i++) {

        viewColumns.push({
            type: 'number',
            label: distinctValues[i],
            calc: (function (x) {
                return function (dt, row) {
                    return (dt.getValue(row, 1) == x) ? dt.getValue(row, 2) : 0;
                }
            })(distinctValues[i])
        });
        groupColumns.push({
            //column: i+2,
            column: viewColumns.length - 1,
            type: 'number',
            //label: distinctValues[i],
            aggregation: google.visualization.data.sum
        });
    }
	
	data.sort({column: 0, desc: false},{column: 1, desc: false}); 
     var view = new google.visualization.DataView(data);
    view.setColumns(viewColumns);
    
    // next, we group the view on column A, which gets us the pivoted data
    var pivotedData = google.visualization.data.group(view, [0], groupColumns);



    // draw agg table
    new google.visualization.ChartWrapper({
      chartType: 'Table',
      containerId: 'table-div',
      dataTable: pivotedData
    }).draw();

        var options = {
          vAxis: {title: 'Sales (totals)'},
          hAxis: {title: 'Members', maxTextLines: 3},
          seriesType: 'bars',
          legend: {position: 'top', maxLines: 1, alignment:'center'},
          isStacked: 'true'
        };

  // Create and draw the visualization.
 new google.visualization.ComboChart(document.getElementById('curve_chart')).
    draw(pivotedData, options);

  
      };
    </script>
  </head>
  <body>
    <div id="curve_chart" style="width: 600px; height: 400px" align="center"></div>
<div id="table-div" style="width: 600px; left: 100px" align="center"></div>
  </body>
</html>
  1. I will send you a screenshot. (I have described the table name in Japanese, so I have supplemented the English.

I’m sorry but I cannot reproduce the issue you are seeing - it works fine for me, even after recreating a data structure similar to yours. I don’t know what could be wrong.

You could try feeding your exact code with sample data to ChatGPT and describing the problem - it might be able to suggest some changes to the code to fix the issue.

Thank you for your help.
I will ask ChatGPT and investigate.

I was embarrassed to put a space in front of the ". This caused the last event name to be judged differently.
This solved the problem successfully. Thank you so much.

By the way, do you know how to change the color for each legend (member)? If possible, it would be very helpful if you could tell me that.

1 Like

Great to see that you managed to find and resolve the issue.

You can add a colors attribute to the options variable. See चार्ट को पसंद के मुताबिक बनाने का तरीका  |  Charts  |  Google for Developers

If you want the colours to be dynamic, perhaps you could add another variable called vColours at the start of the code (along with events, members and sales), and set it to a search of the colours you want, then set the ‘colors’ attribute in options to ‘vColours’. I’ve never done this but it should work. Edit: I had a quick play and it was a little bit more involved than I suggested. Have a look at this jsfiddle here. Note that the code has changed a little from what it was. Below is a screenshot that might help as well …

All the best.

I could add a color column to the member table and reference your code to set the color!
Thank you so much for all your help.
I appreciate it.

1 Like

This topic was automatically closed after 70 days. New replies are no longer allowed.