text: var $chart = $('#cheat-chart');
  var width = $chart.width();
  var heightRatio = width > 400 ? 0.5 : 1.5;
  var height = width * heightRatio;
  var maxWidth = 848;
  $chart.height(height);
  
  var highlightFill = 'rgba(132, 181, 228, 0.5)';
  
  var grid = {
      left: 60,
      top: 100,
      bottom: 70,
      right: 100
  };
  grid.width = width - grid.left - grid.right;
  grid.height = height - grid.top - grid.bottom;
  
  var xScale = grid.width / (maxWidth - grid.left - grid.right);
  var yScale = grid.height / (maxWidth * heightRatio - grid.top - grid.bottom);
  
  var chart;
  var option;
  
  var $detail = $('#cheat-detail');
  
  var selectedRegion = null;
  $(window).click(function (e) {
      // When click outside of chart or detail area, cancel selection
      if (e.target !== $('#cheat-chart canvas')[0]
          && $(e.target).closest($('#cheat-detail')).length < 1
      ) {
          selectedRegion = null;
          _doUnhighlight(option.graphic.elements, true);
          chart.setOption(option);
      }
  });
  
  var baseOption = {
      title: {
          text: '图表的标题',
          left: 5,
          top: 5
      },
      tooltip: {
          trigger: 'axis',
          axisPointer: {
              type: 'cross'
          },
          silent: true,
          renderMode: 'richText'
      },
      toolbox: {
          right: 15,
          top: 5,
          feature: {
              dataView: {
                  show: true,
                  readOnly: false
              },
              magicType: {
                  show: true,
                  type: ['line', 'bar']
              },
              restore: {
                  show: true
              },
              saveAsImage: {
                  show: true
              }
          }
      },
      visualMap: {
          inRange: {
              symbolSize: [5, 20],
              color: ['#2F4554', '#C23431']
          },
          min: 0,
          max: 25,
          seriesIndex: 2,
          left: 80,
          top: 80,
          itemWidth: 20,
          itemHeight: 80,
          calculable: true
      },
      dataZoom: {
          type: 'slider',
          show: true,
          yAxisIndex: 1
      },
      legend: {
          data: ['蒸发量', '降水量', '平均温度'],
          top: 35,
          left: 5
      },
      grid: grid,
      xAxis: [{
          type: 'category',
          data: ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月']
      }],
      yAxis: [{
              type: 'value',
              name: '水量',
              min: 0,
              max: 250,
              interval: 50,
              axisLabel: {
                  formatter: '{value} ml'
              }
          },
          {
              type: 'value',
              name: '温度',
              min: 0,
              max: 25,
              interval: 5,
              axisLabel: {
                  formatter: '{value} °C'
              }
          }
      ],
      series: [{
              name: '蒸发量',
              type: 'bar',
              data: [2.0, 4.9, 7.0, 23.2, 25.6, 76.7, 135.6, 162.2, 32.6, 20.0, 6.4, 3.3],
              silent: true
          },
          {
              name: '降水量',
              type: 'bar',
              data: [2.6, 5.9, 9.0, 26.4, 28.7, 70.7, 175.6, 182.2, 48.7, 18.8, 6.0, 2.3],
              silent: true
          },
          {
              name: '平均温度',
              type: 'line',
              yAxisIndex: 1,
              data: [2.0, 2.2, 3.3, 5, 6.3, 10.2, 20.3, 23.4, 23.0, 16.5, 12.0, 6.2],
              silent: true,
              symbol: 'circle',
              markPoint: {
                  data: [{
                      coord: ['4月', 5],
                      value: '5℃'
                  }]
              }
          }
      ],
      graphic: {
          elements: [{
              type: 'sector',
              position: [220, 140],
              shape: {
                  r: 50,
                  r0: 20,
                  cx: 0,
                  cy: 0,
                  startAngle: 0,
                  endAngle: Math.PI * 1.2
              },
              style: {
                  fill: '#C23431'
              }
          }, {
              type: 'text',
              position: [210, 120],
              style: {
                  text: '绘制图形和文字',
                  fill: '#2F4554',
                  font: '14px Arial'
              }
          }]
      },
      timeline: {
          data: [
              '2010', '2011', '2012', '2013', '2014', '2015', '2016'
          ],
          axisType: 'category',
          show: true,
          autoPlay: false
      }
  };
  
  var baseActions = [{
      type: 'showTip',
      seriesIndex: 0,
      dataIndex: 7,
      position: [width * 0.65, height * 0.45]
  }];
  
  var regions = [{
      left: grid.left,
      top: grid.top,
      width: grid.width,
      height: grid.height,
      option: {
          id: 'grid',
          desc: '直角坐标系内绘图区域'
      }
  }, {
      group: (function () {
          var group = [];
          for (var i = 0; i < 12; ++i) {
              group.push({
                  left: grid.left + grid.width / 12 * (i + 0.05),
                  bottom: grid.bottom,
                  width: grid.width / 12 * 0.9,
                  height: grid.height / 25 * baseOption.series[2].data[i] + 10
              });
          }
          return group;
      })(),
      option: {
          id: 'series.itemStyle',
          desc: '系列的图形样式，对不同类型的图表有不同的意义。\n对折线图而言，这个配置项用于设置拐点处图形的样式；对柱状图而言，用于设置柱子的样式。该配置项是对整个系列的图形做设置，如果要对其中的某一个特定数据点做设置，应使用 <a href="option.html#series-line.data.itemStyle" target="_blank"><code>series.data.itemStyle</code></a>。'
      }
  }, {
      left: 10,
      top: 5,
      width: 100,
      height: 24,
      option: {
          id: 'title',
          desc: '图表的标题'
      }
  }, {
      left: 10,
      top: 35,
      width: 238,
      height: 24,
      option: {
          id: 'legend',
          desc: '图例，展现了不同系列的标记、颜色和名字'
      }
  }, {
      right: 15,
      top: 5,
      width: 133,
      height: 29,
      option: {
          id: 'toolbox',
          desc: '工具栏，提供操作图表的工具，可自定义'
      }
  }, {
      left: 5,
      top: grid.top - 35,
      width: 70,
      height: grid.height + 40,
      option: {
          id: 'yAxis',
          desc: '直角坐标系 grid 中的 y 轴'
      }
  }, {
      left: grid.left - 3,
      top: grid.top,
      width: 6,
      height: grid.height,
      option: {
          id: 'yAxis.axisLine',
          desc: 'y 轴轴线'
      }
  }, {
      left: grid.left + grid.width - 15,
      top: grid.top - 35,
      width: 60,
      height: grid.height + 40,
      option: {
          id: 'yAxis',
          desc: '直角坐标系 grid 中的 y 轴；第二个 y 轴默认显示在右边'
      }
  }, {
      left: grid.width + grid.left - 3,
      top: grid.top,
      width: 6,
      height: grid.height,
      option: {
          id: 'yAxis.axisLine',
          desc: 'y 轴轴线'
      }
  }, {
      group: [{
          left: grid.left + grid.width - 20,
          top: grid.top - 30,
          width: 40,
          height: 20
      }, {
          left: 38,
          top: grid.top - 30,
          width: 40,
          height: 20
      }],
      option: {
          id: 'yAxis.name',
          desc: 'y 轴名称，可以通过<code>nameLocation</code>改变位置'
      }
  }, {
      group: (function () {
          var group = [];
          for (var i = 0; i < 6; ++i) {
              group.push({
                  left: 11,
                  top: grid.top + grid.height / 5 * i - 9,
                  width: 42,
                  height: 18
              });
          }
          for (var i = 0; i < 6; ++i) {
              group.push({
                  left: grid.left + grid.width,
                  top: grid.top + grid.height / 5 * i - 9,
                  width: 42,
                  height: 18
              });
          }
          return group;
      })(),
      option: {
          id: 'yAxis.axisLabel',
          desc: '坐标轴刻度标签'
      }
  }, {
      group: (function () {
          var group = [];
          for (var i = 0; i < 5; ++i) {
              group.push({
                  left: grid.left,
                  top: grid.top + grid.height / 5 * i - 3,
                  width: width - grid.left - grid.right,
                  height: 6
              });
          }
          return group;
      })(),
      option: {
          id: 'yAxis.splitLine',
          desc: '坐标轴分割线，除此之外，还有 <code>splitArea</code> 设置背景色分割'
      }
  }, {
      group: (function () {
          var group = [];
          for (var i = 0; i < 6; ++i) {
              group.push({
                  left: 50,
                  top: grid.top + grid.height / 5 * i - 5,
                  width: 10,
                  height: 10
              });
          }
          for (var i = 0; i < 6; ++i) {
              group.push({
                  left: grid.left + grid.width,
                  top: grid.top + grid.height / 5 * i - 5,
                  width: 10,
                  height: 10
              });
          }
          return group;
      })(),
      option: {
          id: 'yAxis.axisTick',
          desc: '坐标轴刻度'
      }
  }, {
      left: grid.left,
      bottom: grid.bottom - 3,
      width: grid.width,
      height: 6,
      option: {
          id: 'xAxis',
          desc: '直角坐标系 grid 中的 x 轴'
      }
  }, {
      left: grid.left,
      bottom: grid.bottom - 3,
      width: grid.width,
      height: 6,
      option: {
          id: 'xAxis.axisLine',
          desc: 'x 轴轴线'
      }
  }, {
      group: (function () {
          var group = [];
          for (var i = 0; i < 12; ++i) {
              group.push({
                  left: grid.left + grid.width * (i + 0.5) / 12 - 20 * xScale,
                  bottom: grid.bottom - 25,
                  width: 40 * xScale,
                  height: 20
              });
          }
          return group;
      })(),
      option: {
          id: 'xAxis.axisLabel',
          desc: '坐标轴刻度标签'
      }
  }, {
      group: (function () {
          var group = [];
          for (var i = 0; i < 13; ++i) {
              group.push({
                  left: grid.left + grid.width * (i / 12) - 5,
                  bottom: grid.bottom - 5,
                  width: 10,
                  height: 10
              });
          }
          return group;
      })(),
      option: {
          id: 'xAxis.axisTick',
          desc: '坐标轴刻度'
      }
  }, {
      left: width * 0.65 - 5,
      top: height * 0.45 - 5,
      width: 118,
      height: 80,
      option: {
          id: 'tooltip',
          desc: '提示框'
      }
  }, {
      left: grid.width / 12 * 7.5 + grid.left - 3,
      top: grid.top,
      width: 6,
      height: grid.height,
      option: {
          id: 'tooltip.axisPointer.lineStyle',
          desc: '提示框坐标轴指示器的线条样式'
      }
  }, {
      left: grid.left,
      bottom: grid.height / 250 * 162.2 + grid.bottom - 4,
      width: grid.width,
      height: 6,
      option: {
          id: 'tooltip.axisPointer.crossStyle',
          desc: '提示框坐标轴指示器的十字线样式'
      }
  }, {
      group: [{
          left: 5,
          bottom: grid.height / 250 * 162.2 + grid.bottom - 10,
          width: 50,
          height: 20
      }, {
          left: width - grid.right + 3,
          bottom: grid.height / 250 * 162.2 + grid.bottom - 10,
          width: 43,
          height: 20
      }, {
          left: grid.width / 12 * 7.5 + grid.left - 16,
          bottom: grid.bottom - 24,
          width: 32,
          height: 20
      }],
      option: {
          id: 'tooltip.axisPointer.label',
          desc: '提示框坐标轴指示器的文字'
      }
  }, {
      left: baseOption.visualMap.left,
      top: baseOption.visualMap.top,
      width: 60,
      height: 110,
      option: {
          id: 'visualMap',
          desc: '视觉映射，可以将数据值映射到图形的形状、大小、颜色等。\n除了这个例子中连续型的视觉映射之外，还有<a href="option.html#series-line.data.itemStyle" target="_blank">离散型的视觉映射</a>。'
      }
  }, {
      group: [{
          left: baseOption.visualMap.left + 20,
          top: baseOption.visualMap.top,
          width: 40,
          height: 20
      }, {
          left: baseOption.visualMap.left + 20,
          top: baseOption.visualMap.top + 90,
          width: 40,
          height: 20
      }],
      option: {
          id: 'visualMap.calculable',
          desc: '是否显示拖拽用的手柄（手柄能拖拽调整选中范围）'
      }
  }, {
      right: 5,
      top: grid.top - 5,
      height: grid.height + 12,
      width: 34,
      option: {
          id: 'dataZoom',
          desc: '区域缩放，用来放大一部分的数据，以看清细节'
      }
  }, {
      left: 160,
      top: 105,
      width: 150,
      height: 90,
      option: {
          id: 'graphic',
          desc: '绘制图形元素，包括：image, text, circle, sector, ring, polygon, polyline, rect, line, bezierCurve, arc, group 等'
      }
  }, {
      left: 150,
      top: grid.top + grid.height + 20,
      width: grid.width - 120,
      height: 45,
      option: {
          id: 'timeline',
          desc: '多个 option 切换，展现不同时间段的数据'
      }
  }, {
      left: grid.left + grid.width / 12 * 3,
      width: grid.width / 12,
      bottom: grid.bottom + grid.height / 5,
      height: 50,
      option: {
          id: 'series.markPoint',
          desc: '标记点。\n除此之外，还可以用 <code>markLine</code> 设置标记线，<code>markArea</code> 设置标记区域'
      }
  }];
  
  setSheet(baseOption, baseActions, regions);
  
  function setSheet(baseOption, actions, regions) {
      getBaseChart(width, height, baseOption, actions, function (baseImage) {
          chart = echarts.init($chart[0]);
  
          option = {
              graphic: {
              }
          };
  
          var elements = [];
  
          var createRect = function (region, regionId, group) {
              return {
                  type: 'rect',
                  left: region.left,
                  top: region.top,
                  right: region.right,
                  bottom: region.bottom,
                  shape: {
                      width: region.width,
                      height: region.height
                  },
                  style: {
                      fill: 'transparent',
                      stroke: 'transparent'
                  },
                  onmouseover: function () {
                      highlight(chart, elements, regionId, option, group || region);
                  },
                  onmouseout: function () {
                      unhighlightAll(chart, elements, option);
                      if (selectedRegion) {
                          setDetailHtml(selectedRegion.option);
                      }
                  },
                  onclick: function (e) {
                      // Selecting region
                      if (selectedRegion) {
                          _doUnhighlight(elements, true);
                      }
                      selectedRegion = group || region;
                      highlight(chart, elements, regionId, option, group || region, true);
                      e.event.stopPropagation();
                  }
              };
          };
  
          for (var i = 0; i < regions.length; ++i) {
              var shape;
              if (regions[i].group) {
                  var group = regions[i].group;
                  shape = {
                      type: 'group',
                      children: [],
                      width: '100%',
                      height: '100%'
                  };
                  for (var g = 0; g < group.length; ++g) {
                      var rect = createRect(group[g], i, regions[i]);
                      shape.children.push(rect);
                  }
              }
              else {
                  shape = createRect(regions[i], i);
              }
              elements.push(shape);
          }
  
          elements.push({
              type: 'image',
              style: {
                  image: baseImage,
                  width: width,
                  height: height
              },
              silent: true,
              z: -1
          });
  
          option.graphic.elements = elements;
  
          chart.setOption(option);
      });
  }
  
  function getBaseChart(width, height, option, actions, callback) {
      var canvas = document.createElement('canvas');
      canvas.width = width;
      canvas.height = height;
      var chart = echarts.init(canvas, null, {
          devicePixelRatio: 2
      });
      option.animation = false;
      option = {
          baseOption: option
      };
      chart.setOption(option);
  
      for (var i = 0; actions && i < actions.length; ++i) {
          chart.dispatchAction(actions[i]);
      }
  
      if (typeof callback === 'function') {
          setTimeout(function () {
              callback(canvas.toDataURL());
          }, 10);
      }
  }
  
  function highlight(chart, elements, highlightIndex, option, region, isSelect) {
      setDetailHtml(region.option);
  
      if (!isSelect) {
          _doUnhighlight(elements);
      }
  
      if (elements[highlightIndex].type === 'group') {
          var children = elements[highlightIndex].children;
          for (var i = 0; i < children.length; ++i) {
              if (isSelect) {
                  children[i].style.stroke = '#24c';
              }
              else {
                  children[i].style.fill = highlightFill;
              }
          }
      }
      else {
          if (isSelect) {
              elements[highlightIndex].style.stroke = '#24c';
          } else {
              elements[highlightIndex].style.fill = highlightFill;
          }
      }
      chart.setOption(option);
  }
  
  function unhighlightAll(chart, elements, option) {
      $detail.text('');
      _doUnhighlight(elements);
      chart.setOption(option);
  }
  
  function _doUnhighlight(elements, isSelect) {
      for (var i = 0; i < elements.length; ++i) {
          if (elements[i].type === 'rect') {
              elements[i].style.fill = 'transparent';
              if (isSelect) {
                  elements[i].style.stroke = 'transparent';
              }
          }
          else if (elements[i].type === 'group') {
              var children = elements[i].children;
              for (var j = 0; j < children.length; ++j) {
                  children[j].style.fill = 'transparent';
                  if (isSelect) {
                      children[j].style.stroke = 'transparent';
                  }
              }
          }
      }
  }
  
  function setDetailHtml(option) {
      var link = option.id;
      switch (link) {
          case 'series.itemStyle':
              link = 'series-line.itemStyle';
              break;
  
          case 'dataZoom.handleStyle':
              link = 'dataZoom-slider.handleStyle';
              break;
  
          case 'series.markPoint':
              link = 'series-line.markPoint';
              break;
      }
  
      var html = [
          '<h3>',
              option.id,
          '</h3>',
          '<p class="desc">点击图形固定说明文字</p>',
          '<p>',
              option.desc.split('\n').join('</p><p>'),
          '</p>',
          '<p>',
              '<a href="./option.html#' + link + '" target="_blank">',
                  '查看配置项手册',
              '</a>',
          '</p>'
      ].join('');
  
      $detail.html(html);
  }
  