我正在使用 C3.js 为我的 Django 应用创建图表。在我的 Django 模板中,我有一个像这样的 JavaScript 片段:
<script>
var chart = c3.generate({{ chart_data|safe }});
</script>
在 View 中,我使用 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 不支持表示函数,并添加 'onclick': 'function (d, i) { ... }; ' 到 Python dict 只是在 JSON 编码时产生一个字符串。尝试子类化 json.JSONEncoder 似乎没有结果,因为我需要输出的不是有效的 JSON,而是实际的 JavaScript。
有没有一种巧妙的方法来做到这一点?目前我正在做一个笨拙的解决方法,将 JavaScript 函数代码插入到 json.dumps() 的结果中。
请您参考如下方法:
经过深思熟虑,我想我要问的是以错误的方式解决问题的情况,或者 using the wrong tools to solve the problem .
c3.generate() 的数据结构包含两件事:
- 关于数据结构和图表外观的配置,以及
- 要在图表中呈现的实际数据。
没有特别的理由我需要在 Django View 代码中进行配置设置。意识到这一点后,我可以将配置(包括我想添加的有问题的“onclick”JavaScript 函数)移动到模板,并将数据注入(inject)到一个单独的变量中。
模板将是:
<script>
var columns = {{ chart_columns|safe }};
var chart = c3.generate({
bindto: '#chart',
data: {
columns: columns,
onclick: function (d, i) { /* ... */ }
}
});
</script>
和 View 代码:
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 的模型- View -模板设计。
