Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Feed google charts custom properties like color through gviz_api

I'm having trouble propagating custom_properties like color into my google chart through the python layer gviz_api.

I would like to create a bar chart with individually colored bars such as in the example here: https://developers.google.com/chart/interactive/docs/gallery/barchart#BarStyles

But I can't figure out how to set this up throug the gviz_api (http://code.google.com/p/google-visualization-python/).

I'm fine feeding the data in any way, dictionaries, lists, tuplets, one row at a time, as long as I can color the bars individually. Here's my latest non-working attempt, generate.py:

import gviz_api
def main():
    # Creating the data
    description = {"test" : ("string", "Test name"),
                   "duration" : ("number", "Duration")}
    data = [dict(test="test A", duration=1000, custom_properties={"role":"color:green"}),
            {"test": "test B", "duration": 4000}]

    # Loading it into gviz_api.DataTable
    data_table = gviz_api.DataTable(description, custom_properties={"role":"style"})
    data_table.LoadData(data)

    # Creating a JSon string
    json = data_table.ToJSon(columns_order=("test", "duration"), order_by="test")

    # Read page_template from file
    f = open('template.html', 'r')
    page_template = f.read()
    # Putting the JSon string into the template
    print page_template.format(json)

if __name__ == '__main__':
    main()

And the corresponding template.html:

<html>
<script src="https://www.google.com/jsapi" type="text/javascript"></script>
<script>
google.load('visualization', '1', {{packages:['corechart']}});

google.setOnLoadCallback(drawChart);
function drawChart() {{
  var options = {{
    title: 'Test results',
    legend: 'none',
    chartArea: {{ width: "50%", height: "70%" }}
  }}

  var json_chart = new google.visualization.BarChart(document.getElementById('chart_div'));
  var json_data = new google.visualization.DataTable({0}, 0.6);
  json_chart.draw(json_data, options);
}}
</script>
<body>
  <div id="chart_div"></div>
</body>
</html>
like image 447
oflisback Avatar asked Oct 20 '22 20:10

oflisback


2 Answers

I found the solution for this.

To your description/data, add a third column which will contain your property.

description = {"test" : ("string", "Test name"),
                   "duration" : ("number", "Duration"), "property": ("string", '', {'role':'style'})}

data = [dict(test="test A", duration=1000, property = "color:green" ),
            {"test": "test B", "duration": 4000, property = "color:red"}]

This should work unless the order of the columns gets messed up. Make sure that the order is test, duration, property. It wont work if it's test, property, duration, and it wont come up with error. If you end up without test being first it will pop up with a domain error.

Hope this helps anyone looking to do this!

like image 64
Jglstewart Avatar answered Oct 31 '22 09:10

Jglstewart


After struggling some more with gviz_api and taking a peek at its implementation I gave up and decided not to use the gviz_api wrapper. Instead I transferred the data to the template via an array and got the individually colored bars I was after. With the gviz_api dependency out of the way, Google Chart, different color for each bar held good information.

generate.py:

f = open('template.html', 'r')
page_template = f.read()
f.close()

testData = ['Test 1', 43, 'PASS', 'Test 2', 54, 'FAIL']

print page_template.format(testData)

template.html:

<html>
<script src="https://www.google.com/jsapi" type="text/javascript"></script>
<script type="text/javascript">
google.load("visualization", '1.1', {{packages:['corechart']}});
google.setOnLoadCallback(drawChart);
function drawChart() {{
  var options = {{
    title: 'Test results',
    legend: 'none',
    chartArea: {{ width: "50%", height: "70%" }}
  }}

  var barChart = new google.visualization.BarChart(document.getElementById('chart_div'));
  var dataTable = new google.visualization.DataTable();
    dataTable.addColumn('string', 'Test name');
    dataTable.addColumn('number', 'Duration');
    dataTable.addColumn({{ type: 'string', role: 'style' }});

    // Import array with contents: [<test name>, <duration>, <result>, .. }}
    testData = {0}

    dataTable.addRows(testData.length/3);
    for (i = 0; i < testData.length/3;i++) {{
      dataTable.setValue(i, 0, testData[i*3]);
      dataTable.setValue(i, 1, testData[i*3+1]);
      if (testData[i*3+2] == 'PASS') {{
        dataTable.setValue(i, 2, 'color:green');
      }} else
        dataTable.setValue(i, 2, 'color:red');
      }}
    }}
    barChart.draw(dataTable, options);
  }}
</script>
<body>
  <div id="chart_div"></div>
</body>
</html>

The doubled curly braces in the template are there to enable use of the python string.format() method.

like image 43
oflisback Avatar answered Oct 31 '22 11:10

oflisback