1. 程式人生 > >d3繪製地圖+heatmap.js實現熱力圖

d3繪製地圖+heatmap.js實現熱力圖

目錄

 

1、背景

2、思路

3、區域圖直接在一個g元素上進行繪製。

4、使用svg繪製的熱力圖效果不太好,因此通過引入heatmap.js進行繪製。

5、參考資料

1、背景

有個需求,希望在地圖上展示資料的區域圖和熱力圖。通過切換來改變展示形式。

angular:  6.1.0

d3: 5.0.0

heatmap: 2.0

2、思路

由於是使用d3繪製的地圖,且請求的json資料量很大(包含中國省市區縣),隱藏地圖只繪製一次,其他的變化都是在地圖上的資料層做繪製。把地圖的svg元素和熱力圖的div元素通過定位,放在同一個位置上。

d3使用npm下載匯入

heatmap.js是使用靜態js匯入

注:1)在angular.json中引入heatmap.js(下載路徑見5、參考資料)

"scripts": [
              "./src/assets/js/heatmap.js"
            ]

2)import * as heatmap from 'assets/js/heatmap.js';

      <svg class="chart-cursor-d3" id="app-d3chart_{{type}}_{{id}}"
           [ngStyle]="{'height':height + 'px','background-color': itemGraph ? null : getColor('bg')}">
      </svg>
      <div id="app-d3chart_heatmap_{{id}}" [hidden]="chartType !== 'heat'"
           [ngStyle]="{'float': 'left','height':height + 'px', 'margin-top': -height  + 'px',
           'width': width + 'px','background-color': null">
      </div>

3、區域圖直接在一個g元素上進行繪製。

  /**
   * @函式名稱:drawBase
   * @param data  座標資料集合
   * @作用:繪製已氣泡展示的資料
   * @date 2018/7/9
   */
  private drawBase(data) {
    const me = this;
    me.initBaseDom();
    data = me.getBaseData(data);
    if (this.chartType === 'heat') {
      this.drawHeatMap(data);
      return;
    }
    const g = me.baseDom;
    const cbg = me.getColor('cbg');
    g
      .append('g')
      .selectAll('circle')
      .data(data)
      .enter()
      .append('circle')
      .attr('cx', function(d, i) {
        const x = d.location[0];
        return x;
      })
      .attr('cy', function(d, i) {
        const y = d.location[1];
        return y;
      })
      .attr('fill', function(d, i) {
        return me.getBaseColor(data[i]);
      }) // assets/img/charts/red.svg
      .attr('r', function(d, i) {
       return me.getBaseR(data[i]);
      })
      .attr('class', function (d) {
        const cl = me.getClassByLevel('base', d.cityLevel, true);
        return 'bubbledata ' + cl;
      })
      .attr('cursor', function(d, i) {
        return me.getCursorByState(d.state);
      })
      .attr('opacity', me.opacity)
      .on('mouseover', function(d, i) {
        me.tip.html(me.getBaseDataTip(d));
        me.tip.show();
      })
      .on('mouseout', function(d, i) {
        me.tip.hide();
      })
      .on('click', function(d, i) {
        me.showInterface(d, i);
      });
    // 繪製動畫
    this.drawDynamicRipple(data);
  }

4、使用svg繪製的熱力圖效果不太好,因此通過引入heatmap.js進行繪製。

/**
   * 繪製熱力圖 
   * @param data 資料集
   */
  drawHeatMap(data: any) {
    if (this.chartType !== 'heat') {
      return;
    }
    // 建立一個heatmap例項物件
// “h337” 是heatmap.js全域性物件的名稱.可以使用它來建立熱點圖例項
// 這裡直接指定熱點圖渲染的div了.heatmap支援自定義的樣式方案,網頁外包接活具體可看官網api
    const id = '#app-d3chart_heatmap_' + this.id;
    const shadColor = this.getColor('shadColor');
    const heatmapInstance = heatmap.h337.create({
      container: this.el.nativeElement.querySelector(id),
      radius: this.getBaseR(null),
      gradient: { // TODO 先用預設顏色
        // enter n keys between 0 and 1 here
        // for gradient color customization
        '0.25': 'rgb(0,72,255)',
        '0.55': 'rgb(0,255,255)',
        '0.85': 'rgb(255,255,0)',
        '1.0': 'rgb(255,0,0)'
      }
    });

    // 因為data是一組資料,web切圖報價所以直接setData
    heatmapInstance.setData({
      max: this.legend.value.maxLevel,
      data: data
    }); // 資料繫結還可以使用
  }

5、參考資料

外掛下載:http://www.yyyweb.com/demo/heatmap/heatmap.rar

官網:http://www.patrick-wied.at/static/heatmapjs/

api:http://www.patrick-wied.at/static/heatmapjs/docs.html

官網例子:http://www.patrick-wied.at/static/heatmapjs/examples.html