code: def highcharts_heatmap (data, xcats, ycats, pconfig=None):
      
      if pconfig is None:
          pconfig = {}
  
      # Reformat the data for highcharts
      pdata = []
      for i, arr in enumerate(data):
          for j, val in enumerate(arr):
              pdata.append([j,i,val])
  
      # Get the plot ID
      if pconfig.get('id') is None:
          pconfig['id'] = 'mqc_hcplot_'+''.join(random.sample(letters, 10))
  
      # Sanitise plot ID and check for duplicates
      pconfig['id'] = report.save_htmlid(pconfig['id'])
  
      # Build the HTML for the page
      html = '<div class="mqc_hcplot_plotgroup">'
  
      # The 'sort by highlights button'
      html += """<div class="btn-group hc_switch_group">
          <button type="button" class="mqc_heatmap_sortHighlight btn btn-default btn-sm" data-target="#{id}" disabled="disabled">
              <span class="glyphicon glyphicon-sort-by-attributes-alt"></span> Sort by highlight
          </button>
      </div>""".format(id=pconfig['id'])
  
      # The plot div
      html += '<div class="hc-plot-wrapper"><div id="{id}" class="hc-plot not_rendered hc-heatmap"><small>loading..</small></div></div></div> \n'.format(id=pconfig['id'])
  
      report.num_hc_plots += 1
  
      report.plot_data[pconfig['id']] = {
          'plot_type': 'heatmap',
          'data': pdata,
          'xcats': xcats,
          'ycats': ycats,
          'config': pconfig
      }
  
      return html
docs: Build the HTML needed for a HighCharts line graph. Should be
      called by plot_xy_data, which properly formats input data.