第一个故事 - 简单的入门案例

我们从一个静态的散点图开始讲述一个故事。简单的实例,开始你的数据可视化。

image

你需要准备:

  1. 一台联网的电脑;

  2. 一个代码编辑器,支持javascript编写(甚至只是一个txt编辑器);

  3. 一个充满好奇心的大脑;

正式开始

  1. 数据获取:

    数据通常可以直接由他人提供。你的同事们经常可以替你分担数据收集这份工作(埋点日志或者其它数据统计)。如果你计划制作几个图表用于描述情况,或者领导希望你能分析年度的数据,那么你通常能拿到一些excel或者其它的电子表格;如果你计划设计一个数据监控后台,那么你的数据来源就是后端的研发同事。

    ECharts的不同图表需要不同形式的数据,但通常都是json格式。我们现在绘制的散点图,需要的数据是二维结构。ECharts官网有一个表格工具,利用这个工具,可以轻松地将excel表转化为可用的数据结构

    这里直接给出我们的第一份数据(json格式)你可能注意到数据被一个函数index()包含,这个单纯为了避免浏览器的跨域问题。你无需下载数据,根据后文内容直接引用地址即可

  1. 数据分析:

    数据是笔者直接提供的,所以至少在格式上不存在问题。但对于数据内容,你绝对不应该认为它是正确无疑的。

    记住,绝不能只因为它是数字就相信它就是正确的

    我们要注意的是那些不太对头的东西···如果任何东西看上去有些异常,我们就需要到源头去进行验证。

    大部分异常都只是笔误而已,但有些异常却真的存在,而它们就是有意思的地方。可以作为故事重点。

    不过笔者不希望第一个故事就如此复杂。笔者将在文末讲解如何筛选无意义或错误数据,最终获得可用的数据的具体方法。

  1. 初始图表:

    打开你的编辑器,是时候写(粘贴)一波代码了。

    1. 引入ECharts:不需要考虑太多,将下文的代码全部粘贴到你的编辑器中就好了。代码几乎引入了你全部可能用到的库,后续编写其它的图表也可以继续沿用这个head。

      <!DOCTYPE html>
      <html>
      <head>
          <meta charset="utf-8">
          <title>ECharts</title>
          <!-- 引入 echarts.js -->
          <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/echarts/dist/echarts.min.js"></script>
          <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/echarts-gl/dist/echarts-gl.min.js"></script>
          <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/echarts-stat/dist/ecStat.min.js"></script>
          <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/echarts/dist/extension/dataTool.min.js"></script>
          <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/echarts/map/js/china.js"></script>
          <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/echarts/map/js/world.js"></script>
          <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/echarts/dist/extension/bmap.min.js"></script>
          <script type="text/javascript" src="https://www.jb51.net/jslib/jquery/jquery.min.js"></script>
      </head>
      <body>
          <!--这里暂时没有内容-->
      </body>
      </html>
      
    2. 接下来我们在<body></body>中完成我们的内容(不必担心,笔者会在最后给出完整代码):

      1. 为ECharts准备一个具备大小(宽高)的容器:

        <div id="scatter1" style="width:100%;height:900px;"></div>
        
      2. 准备一个javaScript块,后续内容都在其中完成:

        <script type="text/javascript"></script>
        
      3. 基于准备好的容器,初始化ECharts实例(//之后内容为注释,不会影响你的代码):

        <script type="text/javascript">
                // 基于准备好的dom,初始化echarts实例
                var myChart = echarts.init(document.getElementById('scatter1'));
        </script>
        
      4. 使用 option 来表述图表信息:数据,数据如何映射成图形,交互行为。具体可查看代码内注释:

        var option = {
           //图表标题,当前为空
           title: {},
           //提示框,当前为空
           tooltip: {},
          
           //横坐标设置,当前仅设置类别为‘category‘,即‘类目’
           xAxis: {
                   type: 'category',
           },
           //纵坐标设置,当前仅设置类别为‘value‘,即‘值’
           yAxis: {
                   type: 'value',
           },
           //坐标系设置,如上下左右离边框距离等属性,当前为空
           grid: {},  
          
           //系列列表,用于指定图表名称、类型,数据等,当前类型为‘scatter’,即‘散点图’;数据有四行,每个类目对应一个值,将绘制一幅包含四个点的散点图
           series: [{
                   name: 'scatter',
                   type: 'scatter',
                   data: [
                      ["安徽省当涂第一中学",61],
                      ["安徽省六安第一中学",14],
                      ["安庆市第十一中学校",4],
                      ["安庆市第一中学",36],
                ]
           }]
        };
        
      5. 使用刚指定的配置项和数据显示图表:

        // 使用刚指定的配置项和数据显示图表。
        myChart.setOption(option);
        
      6. 完成!

    3. 当前全部的代码如下。现在你可以把文件保存为XXX.html,然后用浏览器打开,查看下你使用ECharts绘制的第一幅图表吧(你甚至只需要新建一个txt文件,将代码粘贴进去后保存为.html):

      <!DOCTYPE html>
      <html>
      <head>
          <meta charset="utf-8">
          <title>ECharts</title>
          <!-- 引入 echarts.js -->
          <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/echarts/dist/echarts.min.js"></script>
          <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/echarts-gl/dist/echarts-gl.min.js"></script>
          <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/echarts-stat/dist/ecStat.min.js"></script>
          <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/echarts/dist/extension/dataTool.min.js"></script>
          <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/echarts/map/js/china.js"></script>
          <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/echarts/map/js/world.js"></script>
          <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/echarts/dist/extension/bmap.min.js"></script>
          <script type="text/javascript" src="https://www.jb51.net/jslib/jquery/jquery.min.js"></script>
      </head>
      <body>
          <!-- 为ECharts准备一个具备大小(宽高)的Dom -->
          <div id="scatter1" style="width:100%;height:900px;"></div>
          <script type="text/javascript">
              // 基于准备好的dom,初始化echarts实例
              var myChart = echarts.init(document.getElementById('scatter1'));      
              var option = {
                title: {},
                tooltip: {},
                //xAxis:{},
                xAxis: {
                  type: 'category',
                },
                yAxis: {
                  type: 'value',
                },
                grid: {},  
                series: [{
                  name: 'scatter',
                  type: 'scatter',
                  data: [
                    ["安徽省当涂第一中学",61],
                    ["安徽省六安第一中学",14],
                    ["安庆市第十一中学校",4],
                    ["安庆市第一中学",36]
                  ],
                }]
              };
              // 使用刚指定的配置项和数据显示图表。
              myChart.setOption(option);
          </script>
      </body>
      </html>
      
      image
    4. 然而现在作为初始的图表还不够格,你肯定不会满足于四个数据的散点图。第一节笔者提供了一个json,里面有400个数据,现在我们使用这份数据进行图表绘制(你将初次接触跨域问题):

      引用网络数据并不简单,如果你使用的是chrome浏览器(建议),你将不得不解决跨域问题(简单的说就是数据来源不同于.html文件的地址,chrome会禁止数据的获取)。不过笔者最终找到了一个比较简单的方法(jsonp):

      1. 回到第二节第5步,完成之后我们将4、5步的内容包含在一个回调函数中。并将 <font color ='blue'>data</font> 指向函数 index (data) 中的 <font color ='blue'>data</font>

        //jsonp读取本地json文件
        //回调函数名称(index),需要与 src 中一致,而且要与文件地址中名一致。jsonp格式 名称([])
        //不然无法获取到对应的文件
        function index(data){
               //4、5步完成的内容
            var option = {
                title: {},
                tooltip: {},
                //xAxis:{},
                xAxis: {
                   type: 'category',
                },
                yAxis: {
                   type: 'value',
                },
                grid: {},  
                series: [{
                    name: 'scatter',
                    type: 'scatter',
                   //data指向index(data)中的data
                    data: data,
                }]
            };
            // 使用刚指定的配置项和数据显示图表。
            myChart.setOption(option);
          
        };
        
      2. 我们尚未引用网络数据,现在我们完成这个步骤,并回调上文定义的方法。新建一个javaScript块,写入以下内容:

        <!--jsonp中 需要注意的是
             <script  src="jq.json?callback=loa"></script>
             src ? 之前为文件地址,? 之后为回调函数callback名称,
            回调函数可以简写为 cb ,  然后 回调函数 名称要与引用文件中的名称一致
            可以在对应的文件名中看下,如:jq.json?callback=loa,jq.json的函数名称为 loa-->
        <script type="text/javascript" src="https://guozhe-1300242195.cos.ap-beijing.myqcloud.com/2020-01-14-scatterDegree-1.json?callback=index"></script>
        

        注意,包含的都是注释内容,实际生效的只有<script>这里是代码</script>包含的代码。其中,src 指向基础数据的地址,这个地址一直到 ?callback 前为止。后文中给出了新的数据地址,你只需要替换代码中的地址即可。

      3. 完成!

    5. 现在的完整代码如下。生成的初始图表为:

      <!DOCTYPE html>
      <html>
      <head>
          <meta charset="utf-8">
          <title>ECharts</title>
          <!-- 引入 echarts.js -->
          <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/echarts/dist/echarts.min.js"></script>
          <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/echarts-gl/dist/echarts-gl.min.js"></script>
          <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/echarts-stat/dist/ecStat.min.js"></script>
          <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/echarts/dist/extension/dataTool.min.js"></script>
          <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/echarts/map/js/china.js"></script>
          <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/echarts/map/js/world.js"></script>
          <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/echarts/dist/extension/bmap.min.js"></script>
          <script type="text/javascript" src="https://www.jb51.net/jslib/jquery/jquery.min.js"></script>
      </head>
      <body>
          <!-- 为ECharts准备一个具备大小(宽高)的Dom -->
          <div id="scatter1" style="width:100%;height:900px;"></div>
          <script type="text/javascript">
              // 基于准备好的dom,初始化echarts实例
              var myChart = echarts.init(document.getElementById('scatter1'));      
              
              //jsonp读取本地json文件
              //回调函数名称(index),需要与 src 中一致,而且要与文件地址中名一致。jsonp格式 名称([])
              //不然无法获取到对应的文件
              function index(data){
                  
                  var option = {
                      title: {},
                      tooltip: {},
                      //xAxis:{},
                      xAxis: {
                          type: 'category',
                      },
                      yAxis: {
                          type: 'value',
                      },
                      grid: {},  
                      series: [{
                          name: 'scatter',
                          type: 'scatter',
                          data: data,
                      }]
                  };
                  // 使用刚指定的配置项和数据显示图表。
                  myChart.setOption(option);
              };
          </script>
          <!--jsonp中 需要注意的是
           <script  src="jq.json?callback=loa"></script>
           src ? 之前为文件地址,? 之后为回调函数callback名称,
          回调函数可以简写为 cb ,  然后 回调函数 名称要与  文件中的名称一致
          可以在 对应的文件名中看下,如,jq.json?callback=loa,jq.json的  名字为  loa-->
          <script type="text/javascript" src="https://guozhe-1300242195.cos.ap-beijing.myqcloud.com/2020-01-14-scatterDegree-1.json?callback=index"></script>
      </body>
      </html>
      
      image
    6. 挺不错的嘛!有了初始的图表,现在我们可以对其进行美化,使其更引人注目。

  1. 图表美化:

    图表的美化主要依靠修改/增加 option (第二节第4步)中的信息。现在我们依次修改设置,逐步美化图表:

    1. 我们首先设置一个背景颜色(笔者绘制图表喜欢深色色调)。rgba大家应当非常熟悉,前三个数值设置了颜色,第四个数值制定了颜色的透明程度。现在的颜色相当黑,但不是纯黑(为什么不选择纯黑?):

      //背景颜色,当前透明度为100%,接近纯黑色
      backgroundColor:'rgba(1, 1, 1, 1)',
      
    2. 接下来修改坐标系设置 grid ,令坐标系上下左右分别距离边框一个给定的百分比。我们来看一下现在图表的样式吧:

      //坐标系设置,距离上边框较远,左右居中
      grid: {
          left: '5%',
          right: '5%',
          top:'15%',
          bottom: '7%'
      },
      
      image

      好吧,似乎变得更加难以辨别了(因为坐标系尚未调整,几乎无法辨别,分割线却过于明显)。不要灰心,我们继续编码。

    3. 表格上方预留了足够的空间,接下来我们设置一下标题内容:

      //标题
      title: {
            //标题内容
            text: '学校与排课次数散点图',
          //标题字体颜色及字体大小
          textStyle:{
                color:'#fff',
              fontSize:30,
          },
          //离上边框距离
          top:'5%',
          //离左边框距离,当前为‘居中’
          left: 'center',
      },
      

      现在我们有了一个居中置顶(保持一定距离)的标题,你可以保存文件用浏览器查看效果。

    4. 接下来我们编辑一下两个坐标轴的格式

      //横坐标设置
      xAxis: {
          //类型为‘类目轴’,即种类而非数值
          type: 'category',
          //坐标轴刻度文字格式
          axisLabel:{
              //设置不显示,后续设置无效
              show:false,
          },
          //坐标轴线设置
          axisLine:{
              lineStyle:{
                  color:'#fff',//坐标轴颜色为白色
                  width:2,//坐标轴线宽度2个像素
              }
          }
      },
      

      横坐标我们设置其不显示刻度上的各标签(因为标签过多无法全部显示,也显示必要性)。坐标轴线为白色,这样在深色背景下容易辨认。坐标轴分割线无需设置,因为当前为类目轴,无分割线。

      //纵坐标设置
      yAxis: {
            //类型为‘数值轴’,自带分割线
            type: 'value',
          //纵坐标轴名称
          name:' (次)',
          //坐标轴名称格式设置
          nameTextStyle:{
              //设置行高及对齐方式,使得坐标轴名称达到图形所示效果
              fontSize:20,//字体大小
              verticalAlign:'top',//垂直对齐方式,搭配行高使用,控制垂直方向高度
              align:'left',//水平对齐方式
              lineHeight:10//行高
          },
          //data:[50,100],//值范围,本例不使用
          //分割线格式设置
          splitLine:{
              show:true,//显示
              //分割线设置
              lineStyle:{
                  opacity:0.3,//透明度:0.3
                  type:'dotted'//类型,除此之外还有‘solid’‘dashed’,可以切换观察效果
              }
          },
          //坐标轴刻度文字格式
          axisLabel:{
              //通过以下设置,使得坐标轴标签在刻度上方
                fontSize:20,//字体大小
                    align:'right',
                  verticalAlign:'bottom',
          },
          //坐标轴线设置,由于设置的宽度为0,不显示坐标轴
          axisLine:{
                lineStyle:{
                            color:'#fff',
                  width:0,//不显示坐标轴
              }
          }
      },
      

      纵坐标设置较为复杂,我们设置了坐标轴的名称(将显示在坐标轴尾端),规定分割线的透明度为0.3,保证分割线不影响图表观看。调整了坐标轴刻度标签的格式,使其落于刻度之上。最后,我们隐藏了纵坐标轴线,使得整个图表更加凸显重点(散点本身,而非坐标轴)。

      现在的图表如下。与上图相比,重点已经相当突出了:

      image
    5. 还没有结束,深色背景搭配红色散点可不是个好选择。我们应当对散点进行一些格式的设置,使其从背景中抽离出来。这一切都需要在 series 中完成:

      series: {
          name: 'scatter',
          type: 'scatter',
          //散点大小,当前为 10 像素
          symbolSize:10,
          //散点格式(非选定状态下)
          itemStyle:{
              color:'red',//颜色为红色
              borderColor:'#fff',//边框颜色为白色
              borderWidth:2,//边框 2 个像素
              shadowBlur:3,//阴影 3 个像素
              shadowColor:'#eac736'//阴影颜色,接近于橙黄色,产生光亮效果
          },
          //散点格式(选定状态下),emphasis即为选中状态,与normal相对
          emphasis: {
              itemStyle: {
                  //color: 'red',
                  borderColor: '#fff',//边框颜色为白色
                  borderWidth: 5,//边框 5 个像素
                  shadowBlur: 15,//阴影 15 个像素
                  shadowColor: '#eac736'//阴影颜色,接近于橙黄色,产生光亮效果
              }
          },
          //散点的值(value)格式设置
          label: {
              //仅当选中状态下显示
              emphasis: {
                  show: true,//显示
                  position: 'left',//左侧
                  //字体格式
                  textStyle: {
                      color: '#fff',//颜色为白色
                      fontSize: 16//字体大小 16 个像素
                  }
              }
          },
          data: data,
      },
      
      image

      现在,你的图表应当足够吸引人眼球了。如果你有别的想法,可以根据官方文档,或者在上文的基础上对代码做一些修改。

    6. 现在给出散点图的完整代码。将其粘贴到你的编辑器中,另存为XXX.html文件然后使用浏览器打开即可。或者新建一个txt文件,将内容粘贴进去,修改后缀为.html,使用浏览器打开同样可以查看结果(当然,笔者希望读者能够按步骤逐渐完成,而不是直接复制最终的代码):

      <!DOCTYPE html>
      <html>
      <head>
          <meta charset="utf-8">
          <title>ECharts</title>
          <!-- 引入 echarts.js -->
          <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/echarts/dist/echarts.min.js"></script>
          <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/echarts-gl/dist/echarts-gl.min.js"></script>
          <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/echarts-stat/dist/ecStat.min.js"></script>
          <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/echarts/dist/extension/dataTool.min.js"></script>
          <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/echarts/map/js/china.js"></script>
          <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/echarts/map/js/world.js"></script>
          <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/echarts/dist/extension/bmap.min.js"></script>
          <script type="text/javascript" src="https://www.jb51.net/jslib/jquery/jquery.min.js"></script>
      </head>
      <body>
          <!-- 为ECharts准备一个具备大小(宽高)的Dom -->
          <div id="scatter1" style="width:100%;height:900px;"></div>
          <script type="text/javascript">
              // 基于准备好的dom,初始化echarts实例
              var myChart = echarts.init(document.getElementById('scatter1'));      
              
              //jsonp读取本地json文件
              //回调函数名称(index),需要与 src 中一致,而且要与文件地址中名一致。jsonp格式 名称([])
              //不然无法获取到对应的文件
              function index(data){
                  //使用option表述图表信息
                  var option = {
                      backgroundColor:'rgba(1, 1, 1, 1)',
                        //图表的标题
                      title: {
                          text: '学校与排课次数散点图',//标题内容
                            //标题字体设置
                          textStyle:{
                              color:'#fff',//标题字体颜色
                              fontSize:30,//字体大小
                          },
                          top:'5%',//距离容器上端的百分比
                          left: 'center',//居中
                      },
                      //提示框,当前为空
                      tooltip: {},
                      //横坐标设置
                      xAxis: {
                          //类型为‘类目轴’,即种类而非数值
                          type: 'category',
                          //坐标轴刻度文字格式
                          axisLabel:{
                              //设置不显示,后续设置无效
                              show:false,
                          },
                          //坐标轴线设置
                          axisLine:{
                              lineStyle:{
                                  color:'#fff',//坐标轴颜色为白色
                                  width:2,//坐标轴线宽度2个像素
                              }
                          }
                      },
                      //纵坐标设置
                      yAxis: {
                          //类型为‘数值轴’,自带分割线
                          type: 'value',
                          //纵坐标轴名称
                          name:' (次)',
                          //坐标轴名称格式设置
                          nameTextStyle:{
                              //设置行高及对齐方式,使得坐标轴名称达到图形所示效果
                              fontSize:20,//字体大小
                              verticalAlign:'top',//垂直对齐方式,搭配行高使用,控制垂直方向高度
                              align:'left',//水平对齐方式
                              lineHeight:10//行高
                          },
                          //data:[50,100],//值范围,本例不使用
                          //分割线格式设置
                          splitLine:{
                              show:true,//显示
                              //分割线设置
                              lineStyle:{
                                  opacity:0.3,//透明度:0.3
                                  type:'dotted'//类型,除此之外还有‘solid’‘dashed’,可以切换观察效果
                              }
                          },
                          //坐标轴刻度文字格式
                          axisLabel:{
                              //通过以下设置,使得坐标轴标签在刻度上方
                              fontSize:20,//字体大小
                              align:'right',
                              verticalAlign:'bottom',
                          },
                          //坐标轴线设置,由于设置的宽度为0,不显示坐标轴
                          axisLine:{
                              lineStyle:{
                                  color:'#fff',
                                  width:0,//不显示坐标轴
                              }
                          }
                      },
                      grid: {
                          left: '5%',
                          right: '5%',
                          top:'15%',
                          bottom: '7%',
                          //containLabel: true,
                      },  
                      series: {
                          name: 'scatter',
                          type: 'scatter',
                          //散点大小,当前为 10 像素
                          symbolSize:10,
                          //散点格式(非选定状态下)
                          itemStyle:{
                              color:'red',               //颜色为红色
                              borderColor:'#fff',  //边框颜色为白色
                              borderWidth:2,             //边框 2 个像素
                              shadowBlur:3,              //阴影 3 个像素
                              shadowColor:'#eac736'//阴影颜色,接近于橙黄色,产生光亮效果
                          },
                          //散点格式(选定状态下),emphasis即为选中状态,与normal相对
                          emphasis: {
                              itemStyle: {
                                  //color: 'red',
                                  borderColor: '#fff',  //边框颜色为白色
                                  borderWidth: 5,             //边框 5 个像素
                                  shadowBlur: 15,               //阴影 15 个像素
                                  shadowColor: '#eac736'//阴影颜色,接近于橙黄色,产生光亮效果
                              }
                          },
                          //散点的值(value)格式设置
                          label: {
                              //仅当选中状态下显示
                              emphasis: {
                                  show: true,            //显示
                                  position: 'left',//左侧
                                  //字体格式
                                  textStyle: {
                                      color: '#fff',//颜色为白色
                                      fontSize: 16  //字体大小 16 个像素
                                  }
                              }
                          },
                          data: data,
                      },
                  };
                  // 使用刚指定的配置项和数据显示图表。
                  myChart.setOption(option);
              };
          </script>
          <!--jsonp中 需要注意的是
           <script  src="jq.json?callback=loa"></script>
           src ? 之前为文件地址,? 之后为回调函数callback名称,
          回调函数可以简写为 cb ,  然后 回调函数 名称要与  文件中的名称一致
          可以在 对应的文件名中看下,如,jq.json?callback=loa,jq.json的  名字为  loa-->
          <script type="text/javascript" src="https://guozhe-1300242195.cos.ap-beijing.myqcloud.com/2020-01-14-scatterDegree-1.json?callback=index"></script>
      </body>
      </html>        
      
    7. 使用 ECharts 的部分基本完成,接下来笔者使用 hype(我们将在另一个手册对其进行介绍) 对图表作进一步改进(读者可以将图表保存为图片,然后进行编辑):

      1. 分析基础数据,得出中位数及平均数,分别为12和22.7
      2. 在hype中绘制矢量图形,添加中位数线和平均值线,并分别指出线类型及具体数值
      3. 也许你对这个背景感兴趣。笔者设置图表的背景透明,然后底层的图形上添加了毛玻璃效果
      image
    8. 现在图表绘制完成,添加上下文:本图表绘制的是学校使用排课引擎的次数图,每个点指代一个学校,可以看到,多数学校集中在0~30的区间内。少数学校调用次数超过90次,最多的调用为193次。

      添加上下文非常重要,因为当你的读者在阅读图表的时候不能保证你总在旁边。我们的散点图如果没有标题及上下文,读者根本不可能知道其代表的意义(或许是公司员工迟到分钟数?那最高值很可能是笔者本人)。

  1. 该图表的意义

    散点图展示了一段时间内300余所学校调用排课引擎的情况。我们预期的调用次数应当在10次左右,并且多次的调用没有实际意义(具体不做解释)。但实际情况可以看到,平均数比中位数多10,存在相当多的点调用次数在30次以上,最高的点调用次数为193次。

    散点的集中状态基本符合预期,但是调用次数多的点明显存在问题。应当对其进行记录,观察是否存在地域特征,做进一步分析。

  1. 数据图表相互演进

    正如笔者前面所述,数据可视化的流程不是线性的。只需要简单调整一下数据的输入,即便是同一套数据,也会呈现出不同的效果。

    1. 笔者按排课次数排序,得到了新的基础数据。可以看到,各点不再散乱分布于各处,而是按从小到大依次排序,呈现出指数函数一般的图形(显然我们的数据本身并不具备指数函数的特征)。

      现在,根据这张图表,你能得到哪些信息?(别忘了,我们的中位数是12,平均值是22.7)

      image
    2. 笔者按地区排序,再次得到了新的基础数据。新的图表似乎与之前并没有什么区别。你可以试着在图表上将各个区域划分开(从左到右),观察不同区域(政策)之间是否存在着点位分布上的规律。

      实际上规律并不明显,你可能只感觉到福建和广东地区相比其它地区点位更加散乱一些。不如试着统计下各地区的中位数和平均数?这里列举一些地区的数值:

      1. 北京:「中位数:11」,「平均数:22.6」
      2. 福建:「中位数:25」,「平均数:36.6」
      3. 广东:「中位数:13」,「平均数:27.6」

      结果确实如此,福建的两个数值都远远超过平均值。现在你的故事开始有趣起来了,你应该把它讲给你的福建同事听,询问他们其中的原因。这些应该能对你的产品改进提供帮助。

      image
    3. 两者结合或许也会非常有趣,如果你有时间,可以试着先按地区排序,再把地区内部按次数排序,这里笔者就不再赘述,只给出最终图表,你能从中分析出什么结果?

      image

故事结束

第一个故事到此差不多也可以结束了。

你可能觉得作为第一个入门故事,代码内容有点过多,这一点笔者也深有同感。但因为对于不同的图表,ECharts的编码内容基本相同(坐标系设置,内容设置),举一反三相当简单,所以笔者尽量对每一行代码做了解释。后续笔者的编码介绍内容将逐渐简化(不要担心,笔者总会给出完整代码),而把重点放在数据分析和图表美化(当然也少不了图表本身的分析),以及通过一些初级的 javaScript 编码实现简单交互上。

好了,休息一下,倒杯热茶,然后开始我们的第二个故事。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,968评论 6 482
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,601评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,220评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,416评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,425评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,144评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,432评论 3 401
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,088评论 0 261
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,586评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,028评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,137评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,783评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,343评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,333评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,559评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,595评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,901评论 2 345