2015-10-14 75 views
2

我正在使用C3.js为我的Django应用程序创建图表。在我的Django模板,我有JavaScript片段是这样的:将Python数据结构转换为JavaScript,包括函数

<script> 
var chart = c3.generate({{ chart_data|safe }}); 
</script> 

在视图中,我建立使用Python数据结构,它是由该模板被呈现之前被转换为JSON图表:

chart = { 
    'bindto': '#chart', 
    'data': { 
     'columns': [ 
      ['data1', 30, 200, 100, 400, 150, 250], 
      ['data2', 50, 20, 10, 40, 15, 25] 
     ] 
    } 
} 
return render_to_response('chart.html', {'chart_data': json.dumps(chart)}) 

工作正常,我得到类似this example

对于更复杂的C3图表,我需要能够在c3.generate的参数中包含JavaScript函数。 (例如this donut chart中的onclick值。)但JSON不支持表示函数,并且向Python dict添加'onclick': 'function (d, i) { ... };'只会在JSON编码时产生字符串。尝试子类json.JSONEncoder似乎没有结果,因为我需要输出的是无效的JSON,它是实际的JavaScript。

有没有一个干净的方式做到这一点?目前我正在做一个kludgy解决方法,将JavaScript函数代码插入到json.dumps()的结果中。

回答

2

经过反思,我认为我所要求的是一个以错误的方式接近问题的案例,或using the wrong tools to solve the problem

c3.generate()的数据结构包含两两件事:图表应该如何将数据结构以及如何看待

  1. 配置和
  2. 在图表中呈现的实际数据。

没有特别的理由我需要在Django视图代码中进行配置设置。通过这种实现,我可以将配置(包括我想添加的有问题的“onclick”JavaScript函数)移动到模板中,并将数据注入到单独的变量中。

模板将是:

<script> 
var columns = {{ chart_columns|safe }}; 
var chart = c3.generate({ 
    bindto: '#chart', 
    data: { 
     columns: columns, 
     onclick: function (d, i) { /* ... */ } 
    } 
}); 
</script> 

和视图代码:

chart = [ 
    ['data1', 30, 200, 100, 400, 150, 250], 
    ['data2', 50, 20, 10, 40, 15, 25] 
] 
return render_to_response('chart.html', {'chart_columns': json.dumps(chart)}) 

除了解决我的问题,这符合Django的模型 - 视图 - 模板设计更好。