关于使用echarts堆叠柱状图百分比显示的问题
先上结果图
models.py
class PresidentialApprovalRate(models.Model):
political_issue = models.CharField(max_length=255, blank=True, null=True)
support = models.CharField(max_length=255, blank=True, null=True)
oppose = models.CharField(max_length=255, blank=True, null=True)
no_opinion = models.CharField(max_length=255, blank=True, null=True)
class Meta:
managed = False
db_table = 'presidential_approval_rate'
views.py–>将‘字典’传送到‘前端’
def echarts6(request):
# 查询出表对象信息,也就是数据表中的所有数据
# 一行数据就是一个对象,一个格子的数据就是一个对象的一个属性值
all_things = models.PresidentialApprovalRate.objects.all()
political_issue = [] # 设置为list类型,一会儿将其填入data中
support = [] # 设置为list类型,一会儿将其填入data中
oppose = [] # 设置为list类型,一会儿将其填入data中
no_opinion = [] # 设置为list类型,一会儿将其填入data中
for user in all_things: # 遍历
support.append(user.support)
oppose.append(user.oppose)
no_opinion.append(user.no_opinion)
political_issue.append(user.political_issue)
new_list = []
# map() 会根据提供的函数对指定序列做映射。
mid = map(list, zip(political_issue, support, oppose, no_opinion))
for item in mid:
new_dict = dict(zip(['political_issue', 'support', 'oppose', 'no_opinion'], item))
new_list.append(new_dict)
print(new_list)
#打印效果:字典传到前端
#[{'political_issue': '种族问题', 'support': '52', 'oppose': '38', 'no_opinion': '20'},
#{'political_issue': '教育', 'support': '49', 'oppose': '40', 'no_opinion': '21'},
# {'political_issue': '恐怖活动', 'support': '48', 'oppose': '45', 'no_opinion': '17'}, ]
return render(request, 'index6.html', {'political_issue': political_issue, 'new_list': json.dumps(new_list)})
urls.py
from django.contrib import admin
from django.urls import path
from app01 import views
urlpatterns = [
path('admin/', admin.site.urls),
path('echarts6/', views.echarts),]
index6.html—>定义function和使用param的性质
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>ECharts</title>
<!-- 引入 echarts.js 引入静态文件的一种方法-->
{% load static %}
<script src="{% static '/js/echarts.min.js' %}"></script>
<link rel="shortcut icon" href='#'>
</head>
<body>
<!-- 为ECharts准备一个具备大小(宽高)的Dom 【柱状图+百分比显示】-->
<div id="main" style="width: 1000px;height:620px;"></div>
<script type="text/javascript">
// 基于准备好的dom,初始化echarts实例
var myChart = echarts.init(document.getElementById('main'));
var kv = new Array();//声明一个新的字典
data = {{ new_list|safe }};//取出后台传递的数据,此处添加safe过滤避免警告
console.log(data)
// 指定图表的配置项和数据
var option = {
tooltip: {
trigger: 'axis', //这里用的是坐标轴触发,多个数据
axisPointer: { // 坐标轴指示器,坐标轴触发有效
type: 'shadow' // 默认为直线,可选为:'line' | 'shadow'
},
//formatter格式化方法。使用formatter自定义的数据,把内容通过处理让变成我们想要的样子。
formatter: function (params) {// 这里鼠标悬浮显示对应item的每项数值
var relVal = params[0].name;
relVal += '<br/>' + params[0].marker + params[0].seriesName + ' : ' + this.data[params[0].dataIndex].support;// 支持
relVal += '<br/>' + params[1].marker + params[1].seriesName + ' : ' + this.data[params[0].dataIndex].oppose;// 反对
relVal += '<br/>' + params[2].marker + params[2].seriesName + ' : ' + this.data[params[0].dataIndex].no_opinion;// 没意见
return relVal;
},
},
legend: {
data: ['支持', '反对', '不发表意见']
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true
},
xAxis: [
{
type: 'category',
data: {{ political_issue|safe }},
axisLabel: {
interval: 0,
rotate: 40
}
}
],
yAxis: [
{
type: 'value',
max: 100,// 设置最大值是多少
splitNumber: 5,// 设置分几段显示
axisLabel: {
show: true,
interval: 'auto',
formatter: '{value} %' // 给每个数值添加%
},
show: true
}
],
series: [
{
name: '支持',
type: 'bar',
stack: '广告',
emphasis: {
focus: 'series'
},
label: {
show: true,
position: 'insideTop',// 在右边显示
formatter: '{c}%'
},
data: initData('support')
},
{
name: '反对',
type: 'bar',
stack: '广告',
emphasis: {
focus: 'series'
},
label: {
show: true,
position: 'insideTop',// 在右边显示
formatter: '{c}%'
},
data: initData('oppose')
},
{
name: '不发表意见',
type: 'bar',
stack: '广告',
emphasis: {
focus: 'series'
},
label: {
show: true,
position: 'insideTop',// 在右边显示
formatter: '{c}%'
},
data: initData('no_opinion')
},
]
};
//计算各数据占比
function initData(val) {
var serie = [];
for (var i = 0; i < this.data.length; i++) {
var num = 0
if (val == 'support') {//计算支持
num = this.data[i].support
} else if (val == 'oppose') {//计算反对
num = this.data[i].oppose
} else if (val == 'no_opinion') {//计算没意见
num = this.data[i].no_opinion
}
var total = (parseFloat(this.data[i].support) + parseFloat(this.data[i].oppose) + parseFloat(this.data[i].no_opinion)).toFixed(2);
var numcount = Percentage(num, total)
serie.push(numcount);
}
return serie;
}
//定义计算方法
function Percentage(num, total) {
return (Math.round(num / total * 10000) / 100.00);// 小数点后两位百分比
}
// 使用刚指定的配置项和数据显示图表。
myChart.setOption(option);
</script>
</body>
</html>