2021-004 格子設計打造數據動圖

如果懂一些些 JavaScript 程式設計,經常可以參考網路範例,做出絢麗數據動圖,例如我們可以一字不差的照抄下面這個範例 https://www.amcharts.com/demos/force-directed-tree/ ,就能得到彈性超好的圓圈圈跟連結線動圖:

str_html='''
<script src="https://cdn.amcharts.com/lib/4/core.js"></script>
<script src="https://cdn.amcharts.com/lib/4/charts.js"></script>
<script src="https://cdn.amcharts.com/lib/4/plugins/forceDirected.js"></script>
<script src="https://cdn.amcharts.com/lib/4/themes/animated.js"></script>
<div id="chartdiv"></div>
<style>
body {
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
}
#chartdiv {
  width: 100%;
height:550px;
max-width:100%;
}
</style>
<script>
/**
 * ---------------------------------------
 * This demo was created using amCharts 4.
 * 
 * For more information visit:
 * https://www.amcharts.com/
 * 
 * Documentation is available at:
 * https://www.amcharts.com/docs/v4/
 * ---------------------------------------
 */
// Themes begin
am4core.useTheme(am4themes_animated);
// Themes end
var chart = am4core.create("chartdiv", am4plugins_forceDirected.ForceDirectedTree);
var networkSeries = chart.series.push(new am4plugins_forceDirected.ForceDirectedSeries())
chart.data = [
  {
    name: "{{核心元素}}",
    children: [
      {
        name: "{{第一元素}}",
        children: [
          { name: "A1", value: 100 },
          { name: "A2", value: 60 }
        ]
      },
      {
        name: "{{第二元素}}",
        children: [
          { name: "B1", value: 135 },
          { name: "B2", value: 98 }
        ]
      },
      {
        name: "{{第三元素}}",
        children: [
          {
            name: "C1",
            children: [
              { name: "EE1", value: 130 },
              { name: "EE2", value: 87 },
              { name: "EE3", value: 55 }
            ]
          },
          { name: "C2", value: 148 },
          {
            name: "C3", children: [
              { name: "CC1", value: 53 },
              { name: "CC2", value: 30 }
            ]
          },
          { name: "C4", value: 26 }
        ]
      },
      {
        name: "Fourth",
        children: [
          { name: "D1", value: 415 },
          { name: "D2", value: 148 },
          { name: "D3", value: 89 }
        ]
      },
      {
        name: "Fifth",
        children: [
          {
            name: "E1",
            children: [
              { name: "EE1", value: 33 },
              { name: "EE2", value: 40 },
              { name: "EE3", value: 89 }
            ]
          },
          {
            name: "E2",
            value: 148
          }
        ]
      }
    ]
  }
];
networkSeries.dataFields.value = "value";
networkSeries.dataFields.name = "name";
networkSeries.dataFields.children = "children";
networkSeries.nodes.template.tooltipText = "{name}:{value}";
networkSeries.nodes.template.fillOpacity = 1;
networkSeries.nodes.template.label.text = "{name}"
networkSeries.fontSize = 10;
networkSeries.links.template.strokeWidth = 1;
var hoverState = networkSeries.links.template.states.create("hover");
hoverState.properties.strokeWidth = 3;
hoverState.properties.strokeOpacity = 1;
networkSeries.nodes.template.events.on("over", function(event) {
  event.target.dataItem.childLinks.each(function(link) {
    link.isHover = true;
  })
  if (event.target.dataItem.parentLink) {
    event.target.dataItem.parentLink.isHover = true;
  }
})
networkSeries.nodes.template.events.on("out", function(event) {
  event.target.dataItem.childLinks.each(function(link) {
    link.isHover = false;
  })
  if (event.target.dataItem.parentLink) {
    event.target.dataItem.parentLink.isHover = false;
  }
})
</script>
'''
with open("/results/output.html","w") as f:
  f.write(str_html)
0.0s
Python

挖格子,填格子

繪製數據動圖一定非得要會 JavaScript 嗎?如果只是想要修改動圖裡面的一些文字、資料、顏色,難道不能用變數替換的方式進行嗎?如果有可能像填寫試算表格子一樣簡單,就製作出數據動圖,我們就把程式設計師的威力,釋放給那些看不懂程式碼的夥伴們也能發揮創意了呀!我們來實驗看看吧。眼尖的夥伴應該已經發現,我們在上面的 JavaScript 程式碼埋入幾個中文字串 {{核心元素}} 以及 {{第一元素}} 等等,這些挖格子的動作,都是為了讓我們可以填格子時,能夠把變數直接放入數據動圖當中。

# 讓我們先來準備一個簡單的 CSV 檔案
str_csv='''變數,值
核心元素,卡米爾夥伴群
第一元素,隨性舞團
第二元素,英雄舞團
第三元素,少女舞團'''
with open("/results/output.csv","w") as f:
  f.write(str_csv)
0.0s
Python
def csv_to_dic():
  lst_lines=open(
output.csv
,"r").readlines()
  dic={}
  for i in lst_lines:
    str_key,str_value=i.split(",")[0], i.split(",")[1]
    dic[str_key]=str_value.strip()
  return dic
csv_to_dic()
0.1s
Python
# 先安裝模板工具 mustache (這工具在 Python 語言的實現版本叫做 chevron)
pip install chevron
3.7s
Bash in Python
# 透過 mustache 模板工具(在 Python 語言稱之為 chevron),進行變數替換填格子動作
import chevron,json
str_html=open(
output.html
,"r").read()
with open("/results/output_v2.html","w") as f:
  f.write(chevron.render(str_html, csv_to_dic()))
0.1s
Python
Runtimes (1)