Echarts 图表的option序列化

413 阅读1分钟

Echarts的option里可能有function【如formatter函数】、date等,把它序列化时需要考虑下这些,用JSON.stringify无果,故自写一个stringify。 直接上代码。

<!--
  此示例下载自:明点小助手
  本页面主要代码来自:https://echarts.apache.org/examples/zh/editor.html
-->
<!DOCTYPE html>
<html lang="zh-CN" style="height: 100%">
<head>
  <meta charset="utf-8">
</head>
<body style="height: 100%; margin: 0">
  <div id="container" style="height: 100%"></div>
  <div style="position:absolute;top:10px;">
	<input type=button value="下载离线报告" id=btn>
  </div>

  <script type="text/javascript" src="https://fastly.jsdelivr.net/npm/echarts@5.3.3/dist/echarts.min.js"></script>

  <script type="text/javascript">
    var dom = document.getElementById('container');
    var myChart = echarts.init(dom, null, {
      renderer: 'canvas',
      useDirtyRect: false
    });

    var option = {"toolbox":{"feature":{"saveAsImage":{"show":true},"dataView":{"show":true},"restore":{"show":true}}},"title":{"text":"默认计数","left":10},"tooltip":{"trigger":"item","formatter":function(e){return!e.treePathInfo||e.treePathInfo.length<2?"":e.name+": "+1*e.value.toFixed(5)+" ("+1*(100*e.value/e.treePathInfo[e.treePathInfo.length-2].value).toFixed(2)+"%)"}},"series":{"type":"sunburst","sort":null,"radius":[0,"90%"],"label":{"rotate":"radial"},"data":[{"name":"研发六部","value":36,"children":[{"name":"二组","value":9,"children":[{"name":"社招","value":6,"children":[]},{"name":"校招","value":3,"children":[]}]},{"name":"一组","value":7,"children":[{"name":"校招","value":4,"children":[]},{"name":"社招","value":3,"children":[]}]},{"name":"四组","value":7,"children":[{"name":"社招","value":4,"children":[]},{"name":"校招","value":3,"children":[]}]},{"name":"三组","value":6,"children":[{"name":"校招","value":3,"children":[]},{"name":"社招","value":3,"children":[]}]},{"name":"五组","value":6,"children":[{"name":"社招","value":4,"children":[]},{"name":"校招","value":2,"children":[]}]},{"name":"碎项","value":1}]}]}};

    if (option && typeof option === 'object') {
      myChart.setOption(option);
    }

    window.addEventListener('resize', myChart.resize);


// 以下代码,给页面添加一个下载离线报告
document.getElementById('btn').onclick=function(){downloadEchartPage(option)}

function downloadEchartPage (options) {
  let optionText = stringify(options);
  let downloadText = `
<!--
  此示例下载自:明点小助手
  本页面主要代码来自:https://echarts.apache.org/examples/zh/editor.html
-->
<!DOCTYPE html>
<html lang="zh-CN" style="height: 100%">
<head>
  <meta charset="utf-8">
</head>
<body style="height: 100%; margin: 0">
  <div id="container" style="height: 100%"></div>

  <script type="text/javascript" src="https://fastly.jsdelivr.net/npm/echarts@5.3.3/dist/echarts.min.js"><\/script>

  <script type="text/javascript">
    var dom = document.getElementById('container');
    var myChart = echarts.init(dom, null, {
      renderer: 'canvas',
      useDirtyRect: false
    });

    var option = ${optionText};

    if (option && typeof option === 'object') {
      myChart.setOption(option);
    }

    window.addEventListener('resize', myChart.resize);
  <\/script>
</body>
</html>`

  let url = 'data:text/html;charset=UTF-8,' + encodeURIComponent(downloadText);
  const a = document.createElement('a');
  a.href = url
  a.download = 'MingdianReport-echarts-test.html';
  a.click();
}

function stringify(obj) {
  if (obj == null) {return 'null'; }
  let type = Object.prototype.toString.call(obj).slice(8, -1);
  switch (type) {
    case 'Date' :
      return 'new Date(' + obj.getTime() + ')';
    case 'Function' :
      return obj.toString();
    case 'Array' :
      var ar = [];
      for (let i = 0; i < obj.length; i++) {ar[i] = stringify(obj[i]); }
      return '[' + ar.join(',') + ']';
    case 'Object':
      var ar2 = [];
      for (let i in obj) {
        ar2.push( JSON.stringify(i) + ':' + stringify(obj[i]));
      }
      return '{' + ar2.join(',') + '}';
  }
  return JSON.stringify(obj)
}

  </script>
</body>
</html>