Boxplot 中文可以称为『箱形图』、『盒须图』、『盒式图』、『盒状图』、『箱线图』,是一种用作显示一组数据分散情况资料的统计图。它能显示出一组数据的最大值、最小值、中位数、下四分位数及上四分位数。
开发难点
二维数组结构
需要将数据转为如下的二维数据结构,增加了后端开发的难度。
source: [ [850, 740, 900, 1070, 930, 850, 950, 980, 980, 880, 1000, 980, 930, 650, 760, 810, 1000, 1000, 960, 960], [960, 940, 960, 940, 880, 800, 850, 880, 900, 840, 830, 790, 810, 880, 880, 830, 800, 790, 760, 800], [880, 880, 880, 860, 720, 720, 620, 860, 970, 950, 880, 910, 850, 870, 840, 840, 850, 840, 840, 840], [890, 810, 810, 820, 800, 770, 760, 740, 750, 760, 910, 920, 890, 860, 880, 720, 840, 850, 850, 780], [890, 840, 780, 810, 760, 810, 790, 810, 820, 850, 870, 870, 810, 740, 810, 940, 950, 800, 810, 870] ]
PHP后端数据API
- 1.先按照名称分组筛选对应的X轴数据;
- 2.按照名称二次循环筛选对应的数据,并以数组的形式输出;
- 3.增加对应的筛选条件,实现搜索查询的功能开发;
/*价格-盒须图*/ public function getBoxplot() { global $db; dbc(); @$cat_name = get_param("cat_name"); @$fromTime = get_param("fromTime"); @$toTime = get_param("toTime"); $sql = "select cat_name FROM " . $db->table('product') . " WHERE 1"; if ($cat_name != "") { $sql .= " AND cat_name = '" . $cat_name . "'"; } if ($fromTime != "") { $sql .= " AND DATE_FORMAT(FROM_UNIXTIME(pro_month),'%Y-%m-%d') >= '" . $fromTime . "'"; } if ($toTime != "") { $sql .= " AND DATE_FORMAT(FROM_UNIXTIME(pro_month),'%Y-%m-%d') <= '" . $toTime . "'"; } $sql .= " GROUP BY cat_name"; $row = $db->queryall($sql); //求中位数; foreach ($row as $k => $v) { $sql_l = "select pro_price from " . $db->table('product'); $sql_l .= " WHERE cat_name = '" . $v['cat_name'] . "'"; $row_l = $db->queryall($sql_l); //循环数组; $data = array(); for ($i = 0; $i < count($row_l); $i++) { $data[] = $row_l[$i]['pro_price']; } //求中位数; $row[$k]["price"] = $data; } //输出数据; die(json_encode_lockdata($row)); }
盒须图封装函数
function getBox(dataName, dataList, id) { var myChart = echarts.init(document.getElementById(id)); var option = { dataset: [ {source: dataList}, { transform: { type: 'boxplot', config: { itemNameFormatter: function (params) { //console.log(params.value); return dataName[params.value]; } } } }, { fromDatasetIndex: 1, fromTransformResult: 1 } ], tooltip: { trigger: 'item', axisPointer: { type: 'shadow' } }, grid: { top: '5%', left: '3%', right: '4%', bottom: '3%', containLabel: true }, xAxis: { type: 'category', boundaryGap: true, splitArea: { show: false }, splitLine: { show: false } }, yAxis: { type: 'value', min: function (value) { return value.min - 200; }, splitArea: { show: true } }, series: [ { name: 'boxplot', type: 'boxplot', datasetIndex: 1, tooltip: { formatter: function (param) { //console.log(param); return [ //'Product: ' + param.name + ' ', 'Max: ' + param.data[5], 'Q3: ' + param.data[4], 'Median: ' + param.data[3], 'Q1: ' + param.data[2], 'Min: ' + param.data[1] ].join('<br/>'); } } } ] }; myChart.setOption(option); window.addEventListener("resize", function () { myChart.resize(); }); }
难点分析
显示X轴名称
{ transform: { type: 'boxplot', config: { itemNameFormatter: function (params) { //console.log(params.value); return dataName[params.value]; } } } }
坐标轴自动计算显示间距
min: function (value) { return value.min - 200; },
鼠标滑过提示框
tooltip: { formatter: function (param) { //console.log(param); return [ //'Product: ' + param.name + ' ', 'Max: ' + param.data[5], 'Q3: ' + param.data[4], 'Median: ' + param.data[3], 'Q1: ' + param.data[2], 'Min: ' + param.data[1] ].join('<br/>'); }
@漏刻有时