最近要在系统中增加一个桑基图,要求桑基图可以根据选择的分析因子重新绘图。
仔细看了下echarts的示例,桑基图本身很简单,困难的是如何根据数据资料整理成桑基图的数据格式,并且实现选择分析因子重新绘图。
研究了几天的数据资料,特将方法写个demo记录下。
<script src="./plugins/echarts.min.js"></script> <div> <label><input type="checkbox" name="factor" value="city" />city</label> <label><input type="checkbox" name="factor" value="degree" />degree</label> <label><input type="checkbox" name="factor" value="type" />type</label> <button onclick="handleSankeyChart()">确定</button> </div> <div id="main3" style="height: 400px"></div> <script> const data_orig = [ { city: "北京", degree: "本科", value: 300, type: "减少" }, { city: "广州", degree: "硕士", value: 400, type: "增加" }, { city: "深圳", degree: "硕士", value: 360, type: "增加" }, { city: "北京", degree: "硕士", value: 250, type: "减少" }, { city: "上海", degree: "本科", value: 350, type: "减少" }, { city: "重庆", degree: "本科", value: 300, type: "增加" }, { city: "深圳", degree: "本科", value: 230, type: "增加" }, ]; //统计数据 const data = {}; for (let i in data_orig) { const key_arr = []; for (let key in data_orig[i]) { if (key != "value") { key_arr.push(data_orig[i][key]); } } const key_str = key_arr.join("|"); if (!(key_str in data)) data[key_str] = 0; data[key_str] += data_orig[i]["value"]; } //数据key中分析因子的顺序,后面可根据此顺序获取对应的值 const key_order = ["city", "degree", "type"]; function handleSankeyChart() { const params = []; document.querySelectorAll("input[name=factor]").forEach((e, i) => { if (e.checked) params.push(e.value); }); const data_links_all = []; for (let key in data) { const key_arr = key.split("|"); for (let i = 1; i < params.length; i++) { const order_index = key_order.indexOf(params[i]); const target = key_arr[order_index]; const source = key_arr[key_order.indexOf(params[i - 1])]; data_links_all.push({ source: source, target: target, value: data[key], }); } } //links 去掉source=target的项(会报错),合并source和target分别相同的项 const data_links = []; const pairs = []; for (let i in data_links_all) { const key = data_links_all[i]["source"] + "|" + data_links_all[i]["target"]; const index = pairs.indexOf(key); if (index == -1 && data_links_all[i]["source"] != data_links_all[i]["target"]) { pairs.push(key); data_links.push(data_links_all[i]); } else if (data_links_all[i]["source"] != data_links_all[i]["target"]) { data_links[index]["value"] += data_links_all[i]["value"]; } } //根据links,组装节点数据 const data_nodes = []; const items = []; if (data_links.length > 0) { for (let i in data_links) { if (items.indexOf(data_links[i]["source"]) === -1) { data_nodes.push({ name: data_links[i]["source"], }); items.push(data_links[i]["source"]); } if (items.indexOf(data_links[i]["target"]) === -1) { data_nodes.push({ name: data_links[i]["target"], }); items.push(data_links[i]["target"]); } } } drawSankeyChart(data_nodes, data_links); } function drawSankeyChart(data_nodes, data_links) { var chartDom = document.getElementById("main3"); var myChart = echarts.init(chartDom); var option; option = { tooltip: { trigger: "item", triggerOn: "mousemove", }, series: [ { type: "sankey", //严格按照数据节点的顺序显示 layoutIterations: 0, emphasis: { focus: "series", }, //定义文本宽度及超出后的换行 label: { width: 100, overflow: "break", }, data: data_nodes, links: data_links, }, ], }; option && myChart.setOption(option); } </script>
实现了如下的效果:
当桑基图中 layoutIterations 配置项取默认的值32时,echarts会优化图形的显示,减少连线交叉
标签:画桑,const,links,value,source,基图,key,data,echarts From: https://www.cnblogs.com/caroline2016/p/17916134.html