基于静态数据

页面结构

chart用于存放图表,controls存放控件

1
2
3
4
5
6
7
8
9
<body>
<div id='visualization'>
<div style="margin-left:100px">Gross Domestic Product (Current US$ in Trillions)</div>
<div id="chart"></div>
<div id="controls">
<p>Select Regions to Include:</p>
</div>
</div>
</body>
1
2
3
4
5
6
7
8
9
10
11
12
#chart {
width: 500px;
height: 333px;
float: left;
}
#controls {
display: inline-block;
margin-bottom: 150px;
}
#controls p {
margin-left: 10px;
}

包含需要的库

1
2
3
<script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/flot/0.7/jquery.flot.min.js"></script>
<script src="jquery.flot.selection.js"></script>

数据组织

  • 原始数据

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    var eas = [[1960,0.155758351823196],[1961,0.154708338465889], ...,[2011,18.80024281251]];
    var ecs = [[1960,0.442123789761523],[1961,0.470625042294723], ...,[2011,22.1459396328311]];
    // data set continue

    var source = [
    { data: eas, show: true, color: "#E41A1C", label: "East Asia & Pacific", name: "East Asia & Pacific" },
    { data: ecs, show: true, color: "#377EB8", label: "Europe & Central Asia", name: "Europe & Central Asia" },
    { data: lcn, show: true, color: "#4DAF4A", label: "Latin America & Caribbean", name: "Latin America & Caribbean" },
    { data: mea, show: true, color: "#984EA3", label: "Middle East & North Africa", name: "Middle East & North Africa" },
    { data: sas, show: true, color: "#FF7F00", label: "South Asia", name: "South Asia" },
    { data: ssf, show: true, color: "#FFFF33", label: "Sub-Saharan Africa", name: "Sub-Saharan Africa" },
    ];
  • 数据筛选

    通过jQuery封装好的$.map()$grep()分别实现数据的转化和过滤

    • GDP折线图使用的数据

      1
      2
      3
      4
      5
      6
      7
      8
      var data = $.map($.grep(source, function(obj) {
      return obj.show;
      }), function(obj) {
      return {
      data: obj.data,
      color: obj.color,
      };
      });
    • 各个地区GDP数据集

      1
      2
      3
      4
      5
      6
      var area_data = $.map(source, function(obj) {
      return {
      label: obj.label,
      data: obj.data
      };
      });

添加复选框控件

  • 通过$.each()遍历地区数组,添加复选框控件

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    $.each(source, function(idx, region) {

    // 创建id为chk-idx的input控件
    var input = $('<input>').attr('type', 'checkbox').attr('id', 'chk-' + idx);

    // 如果show为true,则checked属性设置为true
    if (region.show) {
    $(input).prop('checked', true);
    }

    // 创建用作色块的<span>标签,并添加css样式
    var span = $('<span>').css({
    'background-color': region.color,
    'height': '0.9em',
    'width': '0.9em',
    'margin-right': '0.25em',
    'display': 'inline-block'
    });

    // 将<input>、<span>和地区的名字都放在<label>元素里,最后在将其添加到文档
    // 不用每创建一个标签就向文档中插入,每插入一次浏览器就需要重新计算页面布局
    // 使用局部变量保存,最后在插入,可以极大的提高性能
    var label = $('<label>').append(input).append(span).append(region.name);
    $('#controls').append(label);
    });

    动态创建并绘制图表以后

    1
    var plotObj = $.plot($('#chart'), data);

    Flot-1.1

  • 监视控件的单击

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    $("input[id^='chk-']").click(function(ev) {

    // 跳过chk-这四个字符获取id
    idx = ev.target.id.substr(4);
    // 单击后重新设置show
    source[idx].show = !source[idx].show;

    // 重置数据并重绘图表
    plotObj.setData($.map(
    $.grep(source, function(obj) {
    return obj.show;
    }), function(obj) {
    return {
    data: obj.data,
    color: obj.color
    };
    }));
    plotObj.draw();
    });

    Flot-1.2

缩放图表

  • 添加一个selection选项,mode表示支持的方向

    1
    2
    3
    var options = {
    selection: { mode: 'xy' }
    };
  • 通过on()函数为时间指派函数

    1
    2
    3
    4
    5
    6
    $('#chart').on('plotselected', function(ev, ranges) {
    plotObj = $.plot($('#chart'), data, $.extend(true, {}, options, {
    xaxis: { min: ranges.xaxis.from, max: ranges.xaxis.to },
    yaxis: { min: ranges.yaxis.from, max: ranges.yaxis.to }
    }));
    });

    Flot-1.3

  • 设置RESET按钮

    1
    2
    3
    4
    <div id="controls">
    <button id="unzoom">RESET ZOOM</button>
    <p>Select Regions to Include:</p>
    </div>
    1
    2
    3
    #controls p, button {
    margin-left: 10px;
    }
    1
    2
    3
    $('#unzoom').click(function() {
    plotObj = $.plot($('#chart'), data, options);
    });

    Flot-1.4

追踪数据的值

页面布局

1
2
3
4
5
<div id="chart-wrapper">
<div id="marker"></div>
<div id="area-chart"></div>
<div id="legends"></div>
</div>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#chart-wrapper {
position: relative;
margin-left: 10px;
}
#marker {
position: absolute;
z-index: 1;
display: none;
width: 1px;
border-left: 1px solid black;
}
#area-chart, #legends {
float: left;
}

数据组织

1
2
3
4
5
6
var area_data = $.map(source, function(obj) {
return {
label: obj.label,
data: obj.data
};
});

绘制图表

  • 创建新的div,设置样式,插入到area_data

    1
    2
    3
    4
    5
    6
    7
    8
    $.each(area_data, function(idx, region) {
    var div = $('<div>').css({
    width: '600px',
    height: '50px'
    });
    region.div = div;
    $('#area-chart').append(div);
    });
  • 设置好每个图表的div以后,分别设置网格线和坐标轴,以及标注

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    $.plot(div, [region.data], {
    series: {
    lines: { fill: true, lineWidth: 1 },
    shadowSize: 0
    },
    xaxis: { show: true, labelHeight: 0, min: 1960, max: 2011,
    tickFormatter: function() { return ''; } },
    yaxis: { show: false, min: 0, max: 60 },
    grid: { show: true, margin: 0, borderWidth: 0,
    borderColor: null, margin: 0, labelMargin: 0,
    axisMargin: 0, minBorderMargin: 0, hoverable: true, autoHighlight: false }
    });
    1
    2
    3
    4
    5
    6
    7
    8
    var legend = $('<p>').text(region.label).css({
    'height': '17px',
    'margin-bottom': "0",
    'margin-left': "10px",
    'margin-top': "0",
    'padding-top': "33px"
    });
    $("#legends").append(legend);
  • 为图表x轴添加标注,通过创建虚拟的图表并定位在原图表下面

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    var xaxis_label = [];
    for (var year = 1960; year < 2012; year++) {
    xaxis_label.push([year, 0]);
    }

    var div = $('<div>').css({
    width: '600px',
    height: '15px'
    });

    $('#area-chart').append(div);

    var xaxisPlot = $.plot(div, [xaxis_label], {
    xaxis: { show: true, labelHeight: 12, min: 1960, max: 2011 },
    yaxis: { show: false, min: 100, max: 200 },
    grid: { show: true, margin: 0, borderWidth: 0, margin: 0,
    labelMargin: 0, axisMargin: 0, minBorderMargin: 0, }
    });

    Flot-1.5

添加交互

  • plot()函数的grid选项的hoverable属性设置为true,鼠标在图标区移动时,Flot将在鼠标移动到图表区域触发plothover事件

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    $('#area-chart').on('plothover', function(ev, pos) {
    var year = Math.round(pos.x);
    var left = xaxisPlot.pointOffset(pos).left;
    var height = $('#area-chart').height();
    $('#marker').css({
    'top': 0,
    'left': left,
    'width': '1px',
    'height': height
    }).show();

    $.each(area_data, function(idx, region) {

    // 为每个图表设置文本值
    matched = $.grep(region.data, function(pt) { return pt[0] === year; });
    if (matched.length > 0) {
    region.value.text(year + ": " + matched[0][1].toFixed(2) + "%");
    } else {
    region.value.text("");
    }
    region.value.css("left", (left+4)+"px").show();
    });
    }).on('mouseout', function(ev) {
    if (ev.relatedTarget.id !== 'marker') {
    $('#marker').hide();
    $.each(area_data, function(idx, region) {
    region.value.hide();
    })
    }
    });

    // 若将鼠标沿着marker移出图表,将marker隐藏
    $("#marker").on("mouseout", function(ev) {
    $("#marker").hide();
    $.each(area_data, function(idx, region) {
    region.value.hide();
    });
    });

    Flot-1.6

完整代码

与图表进行交互

通过AJAX获取数据

与图表进行交互

Flot-2