提交 e3e8ade7 编写于 作者: K kener

全系列图表支持标线markLines

上级 61ca31e5
......@@ -72,26 +72,21 @@
<div class="nav-header"><a href="#" onclick="autoResize()" class="icon-resize-full" id ="icon-resize" ></a>option</div>
<textarea id="code" name="code">
option = {
color: ['#ff7f50','#32cd32','#6495ed'],
title : {
text: '全国主要城市空气质量',
subtext: 'data from PM25.in',
sublink: 'http://www.pm25.in',
text: '南航主要航空线路',
x:'center'
},
tooltip : {
trigger: 'item'
trigger: 'item',
formatter: function(v) {
return v[1].replace(':', ' > ');
}
},
legend: {
orient: 'vertical',
x:'left',
data:['air']
},
dataRange: {
min: 0,
max: 500,
text:['高','低'], // 文本,默认为数值文本
calculable : true,
color:['red','blue']
data:['北京','上海','广州']
},
toolbox: {
show : true,
......@@ -107,21 +102,74 @@ option = {
},
series : [
{
name: 'air',
name: '北京',
type: 'map',
mapType: 'china',
roam: true,
hoverable: false,
data:[],
markLine : {
itemStyle : {},
itemStyle : {
normal: {
borderWidth:1
}
},
data : [
{name : '北京', value : 350},
{name : '天津', value : 123},
{name : '上海', value : 103},
{name : '东莞', value : 83},
{name : '东营', value : 13},
{name : '中山', value : 153},
{name : '临汾', value : 303}
[{name:'北京'},{name:'包头'}],
[{name:'北京'},{name:'北海'}],
[{name:'北京'},{name:'广州'}],
[{name:'北京'},{name:'郑州'}],
[{name:'北京'},{name:'长春'}],
[{name:'北京'},{name:'长治'}],
[{name:'北京'},{name:'重庆'}],
[{name:'北京'},{name:'长沙'}],
[{name:'北京'},{name:'成都'}],
[{name:'北京'},{name:'常州'}],
[{name:'北京'},{name:'丹东'}],
[{name:'北京'},{name:'大连'}],
[{name:'北京'},{name:'东营'}],
[{name:'北京'},{name:'延安'}],
[{name:'北京'},{name:'福州'}],
[{name:'北京'},{name:'海口'}],
[{name:'北京'},{name:'呼和浩特'}],
[{name:'北京'},{name:'合肥'}],
[{name:'北京'},{name:'杭州'}],
[{name:'北京'},{name:'哈尔滨'}],
[{name:'北京'},{name:'舟山'}],
[{name:'北京'},{name:'银川'}],
[{name:'北京'},{name:'衢州'}],
[{name:'北京'},{name:'南昌'}],
[{name:'北京'},{name:'昆明'}],
[{name:'北京'},{name:'贵阳'}],
[{name:'北京'},{name:'兰州'}],
[{name:'北京'},{name:'拉萨'}],
[{name:'北京'},{name:'连云港'}],
[{name:'北京'},{name:'临沂'}],
[{name:'北京'},{name:'柳州'}],
[{name:'北京'},{name:'宁波'}],
[{name:'北京'},{name:'南京'}],
[{name:'北京'},{name:'南宁'}],
[{name:'北京'},{name:'南通'}],
[{name:'北京'},{name:'上海'}],
[{name:'北京'},{name:'沈阳'}],
[{name:'北京'},{name:'西安'}],
[{name:'北京'},{name:'汕头'}],
[{name:'北京'},{name:'深圳'}],
[{name:'北京'},{name:'青岛'}],
[{name:'北京'},{name:'济南'}],
[{name:'北京'},{name:'太原'}],
[{name:'北京'},{name:'乌鲁木齐'}],
[{name:'北京'},{name:'潍坊'}],
[{name:'北京'},{name:'威海'}],
[{name:'北京'},{name:'温州'}],
[{name:'北京'},{name:'武汉'}],
[{name:'北京'},{name:'无锡'}],
[{name:'北京'},{name:'厦门'}],
[{name:'北京'},{name:'西宁'}],
[{name:'北京'},{name:'徐州'}],
[{name:'北京'},{name:'烟台'}],
[{name:'北京'},{name:'盐城'}],
[{name:'北京'},{name:'珠海'}]
]
},
geoCoord: {
......@@ -240,6 +288,131 @@ option = {
'青岛': [120.4651,36.3373],
'韶关': [113.7964,24.7028]
}
},
{
name: '上海',
type: 'map',
mapType: 'china',
data:[],
markLine : {
itemStyle : {
normal: {
borderWidth:1
}
},
data : [
[{name:'上海'},{name:'包头'}],
[{name:'上海'},{name:'北海'}],
[{name:'上海'},{name:'广州'}],
[{name:'上海'},{name:'郑州'}],
[{name:'上海'},{name:'长春'}],
[{name:'上海'},{name:'重庆'}],
[{name:'上海'},{name:'长沙'}],
[{name:'上海'},{name:'成都'}],
[{name:'上海'},{name:'丹东'}],
[{name:'上海'},{name:'大连'}],
[{name:'上海'},{name:'福州'}],
[{name:'上海'},{name:'海口'}],
[{name:'上海'},{name:'呼和浩特'}],
[{name:'上海'},{name:'合肥'}],
[{name:'上海'},{name:'哈尔滨'}],
[{name:'上海'},{name:'舟山'}],
[{name:'上海'},{name:'银川'}],
[{name:'上海'},{name:'南昌'}],
[{name:'上海'},{name:'昆明'}],
[{name:'上海'},{name:'贵阳'}],
[{name:'上海'},{name:'兰州'}],
[{name:'上海'},{name:'拉萨'}],
[{name:'上海'},{name:'连云港'}],
[{name:'上海'},{name:'临沂'}],
[{name:'上海'},{name:'柳州'}],
[{name:'上海'},{name:'宁波'}],
[{name:'上海'},{name:'南宁'}],
[{name:'上海'},{name:'北京'}],
[{name:'上海'},{name:'沈阳'}],
[{name:'上海'},{name:'秦皇岛'}],
[{name:'上海'},{name:'西安'}],
[{name:'上海'},{name:'石家庄'}],
[{name:'上海'},{name:'汕头'}],
[{name:'上海'},{name:'深圳'}],
[{name:'上海'},{name:'青岛'}],
[{name:'上海'},{name:'济南'}],
[{name:'上海'},{name:'天津'}],
[{name:'上海'},{name:'太原'}],
[{name:'上海'},{name:'乌鲁木齐'}],
[{name:'上海'},{name:'潍坊'}],
[{name:'上海'},{name:'威海'}],
[{name:'上海'},{name:'温州'}],
[{name:'上海'},{name:'武汉'}],
[{name:'上海'},{name:'厦门'}],
[{name:'上海'},{name:'西宁'}],
[{name:'上海'},{name:'徐州'}],
[{name:'上海'},{name:'烟台'}],
[{name:'上海'},{name:'珠海'}]
]
}
},
{
name: '广州',
type: 'map',
mapType: 'china',
data:[],
markLine : {
itemStyle : {
normal: {
borderWidth:1
}
},
data : [
[{name:'广州'},{name:'北海'}],
[{name:'广州'},{name:'郑州'}],
[{name:'广州'},{name:'长春'}],
[{name:'广州'},{name:'重庆'}],
[{name:'广州'},{name:'长沙'}],
[{name:'广州'},{name:'成都'}],
[{name:'广州'},{name:'常州'}],
[{name:'广州'},{name:'大连'}],
[{name:'广州'},{name:'福州'}],
[{name:'广州'},{name:'海口'}],
[{name:'广州'},{name:'呼和浩特'}],
[{name:'广州'},{name:'合肥'}],
[{name:'广州'},{name:'杭州'}],
[{name:'广州'},{name:'哈尔滨'}],
[{name:'广州'},{name:'舟山'}],
[{name:'广州'},{name:'银川'}],
[{name:'广州'},{name:'南昌'}],
[{name:'广州'},{name:'昆明'}],
[{name:'广州'},{name:'贵阳'}],
[{name:'广州'},{name:'兰州'}],
[{name:'广州'},{name:'拉萨'}],
[{name:'广州'},{name:'连云港'}],
[{name:'广州'},{name:'临沂'}],
[{name:'广州'},{name:'柳州'}],
[{name:'广州'},{name:'宁波'}],
[{name:'广州'},{name:'南京'}],
[{name:'广州'},{name:'南宁'}],
[{name:'广州'},{name:'南通'}],
[{name:'广州'},{name:'北京'}],
[{name:'广州'},{name:'上海'}],
[{name:'广州'},{name:'沈阳'}],
[{name:'广州'},{name:'西安'}],
[{name:'广州'},{name:'石家庄'}],
[{name:'广州'},{name:'汕头'}],
[{name:'广州'},{name:'青岛'}],
[{name:'广州'},{name:'济南'}],
[{name:'广州'},{name:'天津'}],
[{name:'广州'},{name:'太原'}],
[{name:'广州'},{name:'乌鲁木齐'}],
[{name:'广州'},{name:'温州'}],
[{name:'广州'},{name:'武汉'}],
[{name:'广州'},{name:'无锡'}],
[{name:'广州'},{name:'厦门'}],
[{name:'广州'},{name:'西宁'}],
[{name:'广州'},{name:'徐州'}],
[{name:'广州'},{name:'烟台'}],
[{name:'广州'},{name:'盐城'}]
]
}
}
]
};
......
......@@ -538,7 +538,7 @@ define(function(require) {
itemShape,
serie, seriesIndex,
data[i][0], 0,
data[i][0].name + ':' + data[i][1].name
data[i][0].name + ' : ' + data[i][1].name
);
pList.push(itemShape);
}
......@@ -700,7 +700,7 @@ define(function(require) {
self.query(data[0], 'symbolRotate') || mlOption.symbolRotate[0],
self.query(data[1], 'symbolRotate') || mlOption.symbolRotate[1]
];
console.log(symbol, symbolSize, symbolRotate);
//console.log(symbol, symbolSize, symbolRotate);
var queryTarget = [data[0], mlOption];
var normal = self.deepMerge(
......@@ -711,17 +711,22 @@ define(function(require) {
queryTarget,
'itemStyle.emphasis'
);
var nBorderWidth = typeof normal.borderWidth != 'undefined'
? normal.borderWidth
: (normal.lineStyle && normal.lineStyle.width);
var nlineStyle = normal.lineStyle;
var elineStyle = emphasis.lineStyle;
var nBorderWidth = nlineStyle.width;
if (typeof nBorderWidth == 'undefined') {
nBorderWidth = 0;
nBorderWidth = normal.borderWidth;
}
var eBorderWidth = typeof emphasis.borderWidth != 'undefined'
? emphasis.borderWidth
: (emphasis.lineStyle && emphasis.lineStyle.width);
var eBorderWidth = elineStyle.width;
if (typeof eBorderWidth == 'undefined') {
eBorderWidth = nBorderWidth + 2;
if (typeof emphasis.borderWidth != 'undefined') {
eBorderWidth = emphasis.borderWidth;
}
else {
eBorderWidth = nBorderWidth + 2;
}
}
var itemShape = {
......@@ -730,41 +735,61 @@ define(function(require) {
symbol : symbol,
symbolSize : symbolSize,
symbolRotate : symbolRotate,
//data : [data[0].name,data[1].name],
xStart : xStart,
yStart : yStart, // 坐标
xEnd : xEnd,
yEnd : yEnd, // 坐标
brushType : 'both',
lineType : nlineStyle.type,
shadowColor : nlineStyle.shadowColor,
shadowBlur: nlineStyle.shadowBlur,
shadowOffsetX: nlineStyle.shadowOffsetX,
shadowOffsetY: nlineStyle.shadowOffsetY,
color : normal.color || color,
strokeColor : normal.lineStyle.color
strokeColor : nlineStyle.color
|| normal.borderColor
|| color
|| normal.color,
lineWidth: nBorderWidth
lineWidth: nBorderWidth,
symbolBorderColor: normal.borderColor
|| color
|| normal.color,
symbolBorder: normal.borderWidth * 2
},
highlightStyle : {
shadowColor : elineStyle.shadowColor,
shadowBlur: elineStyle.shadowBlur,
shadowOffsetX: elineStyle.shadowOffsetX,
shadowOffsetY: elineStyle.shadowOffsetY,
color : emphasis.color|| normal.color || color,
strokeColor : emphasis.lineStyle.color
|| normal.lineStyle.color
strokeColor : elineStyle.color
|| nlineStyle.color
|| emphasis.borderColor
|| normal.borderColor
|| color
|| emphasis.color
|| normal.color,
lineWidth: eBorderWidth
lineWidth: eBorderWidth,
symbolBorderColor: emphasis.borderColor
|| normal.borderColor
|| color
|| emphasis.color
|| normal.color,
symbolBorder: typeof emphasis.borderWidth == 'undefined'
? (normal.borderWidth * 2 + 2)
: (emphasis.borderWidth * 2)
},
clickable : true
};
// TODO:label
/*
itemShape = self.addLabel(
itemShape,
mlOption, data, name,
orient
mlOption,
data[0],
data[0].name + ' : ' + data[1].name
);
*/
return itemShape;
}
......
......@@ -620,6 +620,7 @@ define(function() {
// mapValueCalculation: 'sum', // 数值合并方式,默认加和,可选为:
// 'sum' | 'average' | 'max' | 'min'
// selectedMode: false, // 选择模式,默认关闭,可选single,multiple
hoverable: true,
// roam : false, // 是否开启缩放及漫游模式
itemStyle: {
normal: {
......@@ -801,18 +802,20 @@ define(function() {
itemStyle: {
normal: {
// color: 各异, // 标线主色,线色,symbol主色
// borderColor: 各异, // 标线symbol边框颜色,优先于color
// borderColor: 随color, // 标线symbol边框颜色,优先于color
borderWidth: 2, // 标线symbol边框线宽,单位px,默认为2
label: {
show: true,
show: false,
// 标签文本格式器,同Tooltip.formatter,不支持回调
// formatter : null,
position: 'inside' // 可选为 'start'|'end'|'left'|'right'|'top'|'bottom'
// textStyle: null // 默认使用全局文本样式,详见TEXTSTYLE
position: 'inside', // 可选为 'start'|'end'|'left'|'right'|'top'|'bottom'
textStyle: { // 默认使用全局文本样式,详见TEXTSTYLE
color: '#333'
}
},
lineStyle: {
// color: 各异, // 标线主色,线色,优先级高于borderColor和color
width: 2,
// color: 随borderColor, // 标线主色,线色,优先级高于borderColor和color
// width: 随borderWidth, // 优先于borderWidth
type: 'solid',
shadowColor : 'rgba(0,0,0,0)', //默认透明
shadowBlur: 5,
......@@ -822,7 +825,7 @@ define(function() {
},
emphasis: {
label: {
show: true
show: false
// 标签文本格式器,同Tooltip.formatter,不支持回调
// formatter : null,
// position: 'inside' // 可选为'left'|'right'|'top'|'bottom'
......
......@@ -14,16 +14,82 @@ define(
}
MarkLine.prototype = {
/**
* 画刷
* @param ctx 画布句柄
* @param e 形状实体
* @param isHighlight 是否为高亮状态
* @param updateCallback 需要异步加载资源的shape可以通过这个callback(e)
* 让painter更新视图,base.brush没用,需要的话重载brush
*/
brush : function(ctx, e, isHighlight) {
var style = e.style || {};
if (isHighlight) {
// 根据style扩展默认高亮样式
style = this.getHighlightStyle(
style,
e.highlightStyle || {}
);
}
ctx.save();
this.setContext(ctx, style);
// 设置transform
if (e.__needTransform) {
ctx.transform.apply(ctx,this.updateTransform(e));
}
ctx.beginPath();
this.buildLinePath(ctx, style);
ctx.stroke();
this.brushSymbol(e, ctx, style, 0);
this.brushSymbol(e, ctx, style, 1);
if (typeof style.text != 'undefined') {
this.drawText(ctx, style, e.style);
}
ctx.restore();
return;
},
/**
* 创建线条路径
* @param {Context2D} ctx Canvas 2D上下文
* @param {Object} style 样式
*/
buildPath : function(ctx, style) {
buildLinePath : function(ctx, style) {
//var symbolSize = style.symbolSize;
var xStart = style.xStart;
var xEnd = style.xEnd;
var yStart = style.yStart;
var yEnd = style.yEnd;
/*
if (xStart > xEnd) {
xStart -= symbolSize[0];
xEnd += symbolSize[1];
}
else {
xStart += symbolSize[0];
xEnd -= symbolSize[1];
}
if (yStart > yEnd) {
yStart -= symbolSize[0];
yEnd += symbolSize[1];
}
else {
yStart += symbolSize[0];
yEnd -= symbolSize[1];
}
*/
if (!style.lineType || style.lineType == 'solid') {
//默认为实线
ctx.moveTo(style.xStart, style.yStart);
ctx.lineTo(style.xEnd, style.yEnd);
ctx.moveTo(xStart, yStart);
ctx.lineTo(xEnd, yEnd);
}
else if (style.lineType == 'dashed'
|| style.lineType == 'dotted'
......@@ -32,13 +98,136 @@ define(
* (style.lineType == 'dashed' ? 5 : 1);
this.dashedLineTo(
ctx,
style.xStart, style.yStart,
style.xEnd, style.yEnd,
xStart, yStart,
xEnd, yEnd,
dashLength
);
}
},
/**
* 标线始末标注
*/
brushSymbol : function(e, ctx, style, idx) {
ctx.save();
ctx.beginPath();
ctx.lineWidth = style.symbolBorder;
ctx.strokeStyle = style.symbolBorderColor;
// symbol
style.iconType = style.symbol[idx].replace('empty', '')
.toLowerCase();
if (style.symbol[idx].match('empty')) {
ctx.fillStyle = 'rgba(0, 0, 0, 0)';
}
// symbolRotate
var x = idx == 0 ? style.xStart : style.xEnd;
var y = idx == 0 ? style.yStart : style.yEnd;
var rotate = typeof style.symbolRotate[idx] != 'undefined'
? (style.symbolRotate[idx] - 0) : 0;
var transform;
if (rotate !== 0) {
transform = matrix.create();
matrix.identity(transform);
if (x || y ) {
matrix.translate(transform, transform, [-x, -y]);
}
matrix.rotate(
transform, transform,
rotate * Math.PI / 180
);
if (x || y ) {
matrix.translate(transform, transform, [x, y]);
}
ctx.transform.apply(ctx, transform);
}
if (style.iconType == 'arrow' && rotate === 0) {
// 箭头自动旋转,手动画
this.buildArrawPath(ctx, style, idx);
}
else {
// symbolSize
var symbolSize = style.symbolSize[idx];
style.x = x - symbolSize;
style.y = y - symbolSize,
style.width = symbolSize * 2;
style.height = symbolSize * 2;
require('zrender/shape').get('icon').buildPath(ctx, style);
}
ctx.closePath();
ctx.stroke();
ctx.fill();
ctx.restore();
},
buildArrawPath : function (ctx, style, idx) {
var symbolSize = style.symbolSize[idx];
var xStart = style.xStart;
var xEnd = style.xEnd;
var yStart = style.yStart;
var yEnd = style.yEnd;
// 原谅我吧,这三角函数实在没想明白,只能这么笨了
var rotate = Math.atan(
Math.abs((yEnd - yStart) / (xStart - xEnd)
));
if (idx == 0) {
if (xEnd > xStart) {
if (yEnd > yStart) {
rotate = Math.PI * 2 - rotate;
}
}
else {
if (yEnd > yStart) {
rotate += Math.PI;
}
else {
rotate = Math.PI - rotate;
}
}
}
else {
if (xStart > xEnd) {
if (yStart > yEnd) {
rotate = Math.PI * 2 - rotate;
}
}
else {
if (yStart > yEnd) {
rotate += Math.PI;
}
else {
rotate = Math.PI - rotate;
}
}
}
var halfRotate = Math.PI / 8; // 夹角
var x = idx == 0 ? xStart : xEnd;
var y = idx == 0 ? yStart : yEnd;
var point= [
[
x + symbolSize * Math.cos(rotate - halfRotate),
y - symbolSize * Math.sin(rotate - halfRotate),
],
[
x + symbolSize * 0.6 * Math.cos(rotate),
y - symbolSize * 0.6 * Math.sin(rotate),
],
[
x + symbolSize * Math.cos(rotate + halfRotate),
y - symbolSize * Math.sin(rotate + halfRotate),
]
];
ctx.moveTo(x, y);
for (var i = 0, l = point.length; i <l; i++) {
ctx.lineTo(point[i][0], point[i][1]);
}
ctx.lineTo(x, y);
},
/**
* 返回矩形区域,用于局部刷新和文字定位
* @param {Object} style
......@@ -56,59 +245,7 @@ define(
},
isCover : function(e, x, y) {
return false;
//对鼠标的坐标也做相同的变换
if(e.__needTransform && e._transform){
var inverseMatrix = [];
matrix.invert(inverseMatrix, e._transform);
var originPos = [x, y];
matrix.mulVector(originPos, inverseMatrix, [x, y, 1]);
if (x == originPos[0] && y == originPos[1]) {
// 避免外部修改导致的__needTransform不准确
if (Math.abs(e.rotation[0]) > 0.0001
|| Math.abs(e.position[0]) > 0.0001
|| Math.abs(e.position[1]) > 0.0001
|| Math.abs(e.scale[0] - 1) > 0.0001
|| Math.abs(e.scale[1] - 1) > 0.0001
) {
e.__needTransform = true;
} else {
e.__needTransform = false;
}
}
x = originPos[0];
y = originPos[1];
}
// 快速预判并保留判断矩形
var rect;
if (e.style.__rect) {
rect = e.style.__rect;
}
else {
rect = this.getRect(e.style);
rect = [
rect.x,
rect.x + rect.width,
rect.y,
rect.y + rect.height
];
e.style.__rect = rect;
}
if (x >= rect[0]
&& x <= rect[1]
&& y >= rect[2]
&& y <= rect[3]
) {
// 矩形内
return true;
}
else {
return false;
}
return require('zrender/shape').get('line').isCover(e,x,y);
}
};
......
......@@ -406,6 +406,15 @@ option = {
data : [
{name : '最高', value : 930, xAxis: '周六', yAxis: 930, symbolSize:14},
]
},
markLine : {
data : [
[
{name : '周最低', value : 620, xAxis: '周一', yAxis: 620},
{name : '周最高', value : 930, xAxis: '周六', yAxis: 930}
]
]
}
}
]
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册