Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
bluefrankey
hqchart
提交
c1641cf0
hqchart
项目概览
bluefrankey
/
hqchart
与 Fork 源项目一致
从无法访问的项目Fork
通知
5
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
hqchart
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
c1641cf0
编写于
7月 08, 2019
作者:
J
jones
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
ver 6207
上级
fe7eba15
变更
7
显示空白变更内容
内联
并排
Showing
7 changed file
with
629 addition
and
3 deletion
+629
-3
umychart_python/umychart_complier_help.py
umychart_python/umychart_complier_help.py
+56
-0
umychart_python/umychart_complier_jsalgorithm.py
umychart_python/umychart_complier_jsalgorithm.py
+156
-2
umychart_python/umychart_complier_pandas_help.py
umychart_python/umychart_complier_pandas_help.py
+70
-0
umychart_python/umychart_complier_testcase.py
umychart_python/umychart_complier_testcase.py
+5
-1
vuehqchart/src/jscommon/umychart.js
vuehqchart/src/jscommon/umychart.js
+114
-0
webhqchart.demo/jscommon/umychart.js
webhqchart.demo/jscommon/umychart.js
+114
-0
webhqchart/umychart.js
webhqchart/umychart.js
+114
-0
未找到文件。
umychart_python/umychart_complier_help.py
浏览文件 @
c1641cf0
...
...
@@ -93,6 +93,62 @@ class JSComplierHelper:
return
result
@
staticmethod
# result 数组长度由外部创建
def
CalculateZIGLine
(
firstData
,
secondData
,
thridData
,
data
,
result
)
:
isUp
=
secondData
.
Up
findData
=
firstData
if
(
isUp
)
:
for
i
in
range
(
firstData
.
ID
+
1
,
thridData
.
ID
)
:
# 查找最高点
subItem
=
data
[
i
]
if
not
JSComplierHelper
.
IsNumber
(
subItem
)
:
continue
if
findData
.
Value
<
subItem
:
findData
=
Variant
()
findData
.
ID
=
i
findData
.
Value
=
subItem
else
:
for
i
in
range
(
firstData
.
ID
+
1
,
thridData
.
ID
)
:
#查找最低点
subItem
=
data
[
i
]
if
not
JSComplierHelper
.
IsNumber
(
subItem
)
:
continue
if
findData
.
Value
>
subItem
:
findData
=
Variant
()
findData
.
ID
=
i
findData
.
Value
=
subItem
secondData
.
Value
=
findData
.
Value
secondData
.
ID
=
findData
.
ID
lineCache
=
Variant
()
lineCache
.
Start
,
lineCache
.
End
=
Variant
(),
Variant
()
lineCache
.
Start
.
ID
=
firstData
.
ID
lineCache
.
Start
.
Value
=
firstData
.
Value
lineCache
.
End
.
ID
=
secondData
.
ID
lineCache
.
End
.
Value
=
secondData
.
Value
lineData
=
JSComplierHelper
.
CalculateDrawLine
(
lineCache
)
#计算2个点的线上 其他点的数值
for
lineItem
in
lineData
:
result
[
lineItem
.
ID
]
=
lineItem
.
Value
if
thridData
.
ID
==
data
.
length
-
1
:
# 最后一组数据
# 最后2个点的数据连成线
lineCache
=
Variant
()
lineCache
.
Start
,
lineCache
.
End
=
Variant
(),
Variant
()
lineCache
.
Start
.
ID
=
secondData
.
ID
lineCache
.
Start
.
Value
=
secondData
.
Value
lineCache
.
End
.
ID
=
thridData
.
ID
lineCache
.
End
.
Value
=
thridData
.
Value
lineData
=
JSComplierHelper
.
CalculateDrawLine
(
lineCache
)
# 计算2个点的线上 其他点的数值
for
lineItem
in
lineData
:
result
[
lineItem
.
ID
]
=
lineItem
.
Value
else
:
firstData
.
ID
=
secondData
.
ID
firstData
.
Value
=
secondData
.
Value
secondData
.
ID
=
thridData
.
ID
secondData
.
Value
=
thridData
.
Value
secondData
.
Up
=
firstData
.
Value
<
secondData
.
Value
class
Variant
:
def
__init__
(
self
)
:
...
...
umychart_python/umychart_complier_jsalgorithm.py
浏览文件 @
c1641cf0
...
...
@@ -2493,6 +2493,160 @@ class JSAlgorithm() :
return
result
# 属于未来函数,之字转向.
# 用法: ZIG(K,N),当价格变化量超过N%时转向,K表示0:开盘价,1:最高价,2:最低价,3:收盘价,其余:数组信息
# 例如: ZIG(3,5)表示收盘价的5%的ZIG转向
def
ZIG
(
self
,
data
,
n
)
:
hisData
=
self
.
SymbolData
.
Data
result
=
[]
if
JSComplierHelper
.
IsNumber
(
data
):
if
data
==
0
:
data
=
hisData
.
GetOpen
()
elif
data
==
1
:
data
=
hisData
.
GetHigh
()
elif
data
==
2
:
data
=
hisData
.
GetLow
()
elif
data
==
3
:
data
=
hisData
.
GetClose
()
else
:
return
[]
bFirstPoint
=
False
bSecondPont
=
False
firstData
,
secondData
,
thridData
=
Variant
(),
Variant
(),
Variant
()
lastData
=
Variant
()
dataLen
=
len
(
data
)
result
=
JSComplierHelper
.
CreateArray
(
dataLen
)
for
i
in
range
(
dataLen
)
:
item
=
data
[
i
]
if
not
JSComplierHelper
.
IsNumber
(
item
)
:
continue
if
bFirstPoint
==
False
:
bFirstPoint
=
True
firstData
.
ID
=
i
# 第1个点
firstData
.
Value
=
item
elif
bFirstPoint
==
True
and
bSecondPont
==
False
:
temp
=
(
item
-
firstData
.
Value
)
/
firstData
.
Value
*
100
if
temp
>
n
:
secondData
.
ID
,
secondData
.
Value
,
secondData
.
Up
=
i
,
item
,
True
lastData
.
ID
,
lastData
.
Value
=
i
,
item
bSecondPont
=
True
elif
temp
<-
n
:
secondData
.
ID
,
secondData
.
Value
,
secondData
.
Up
=
i
,
item
,
False
lastData
.
ID
,
lastData
.
Value
=
i
,
item
bSecondPont
=
True
elif
bFirstPoint
==
True
and
bSecondPont
==
True
:
temp
=
(
item
-
lastData
.
Value
)
/
lastData
.
Value
*
100
if
secondData
.
Up
==
True
:
# 找下跌的点
if
temp
<-
n
:
thridData
.
ID
,
thridData
.
Value
,
thridData
.
Up
=
i
,
item
,
False
JSComplierHelper
.
CalculateZIGLine
(
firstData
,
secondData
,
thridData
,
data
,
result
)
lastData
.
ID
,
lastData
.
Value
=
i
,
item
else
:
if
item
>
lastData
.
Value
:
lastData
.
ID
,
lastData
.
Value
=
i
,
item
else
:
if
temp
>
n
:
thridData
.
ID
,
thridData
.
Value
,
thridData
.
Up
=
i
,
item
,
True
JSComplierHelper
.
CalculateZIGLine
(
firstData
,
secondData
,
thridData
,
data
,
result
)
lastData
.
ID
,
lastData
.
Value
=
i
,
item
else
:
if
item
<
lastData
.
Value
:
lastData
.
ID
,
lastData
.
Value
=
i
,
item
# 计算最后1组数据
thridData
.
ID
=
data
.
length
-
1
,
thridData
.
Value
=
data
[
data
.
length
-
1
],
thridData
.
Up
=
not
secondData
.
Up
JSComplierHelper
.
CalculateZIGLine
(
firstData
,
secondData
,
thridData
,
data
,
result
)
return
result
# 属于未来函数,前M个ZIG转向波谷到当前距离.
# 用法: TROUGHBARS(K,N,M)表示之字转向ZIG(K,N)的前M个波谷到当前的周期数,M必须大于等于1
# 例如: TROUGHBARS(2,5,2)表示%5最低价ZIG转向的前2个波谷到当前的周期数
def
TROUGHBARS
(
self
,
data
,
n
,
n2
)
:
zigData
=
self
.
ZIG
(
data
,
n
)
# 计算ZIG
zigDataLen
=
len
(
zigData
)
dataLen
=
len
(
data
)
result
=
JSComplierHelper
.
CreateArray
(
dataLen
)
for
i
in
range
(
len
(
zigDataLen
))
:
if
JSComplierHelper
.
IsNumber
(
zigData
[
i
])
:
break
trough
=
JSComplierHelper
.
CreateArray
(
dataLen
)
start
=
i
for
i
in
range
(
i
,
zigDataLen
)
:
# 第1个波谷
if
(
i
+
1
<
zigDataLen
and
i
-
1
>=
0
and
zigData
[
i
]
<
zigData
[
i
-
1
]
and
zigData
[
i
]
<
zigData
[
i
+
1
])
:
#波谷
trough
[
0
]
=
i
break
j
=
0
for
i
in
range
(
i
+
1
,
zigDataLen
)
:
if
(
i
+
1
<
zigDataLen
and
i
-
1
>=
0
and
zigData
[
i
]
<
zigData
[
i
-
1
]
and
zigData
[
i
]
<
zigData
[
i
+
1
])
:
# 波谷
# console.log('[TROUGHBARS] i',i,zigData[i]);
j
+=
1
trough
[
j
]
=
i
if
j
+
1
==
n2
:
result
[
i
]
=
i
-
start
elif
j
+
1
>
n2
:
trough
.
pop
(
0
)
# 大于计算的波谷数,去掉第1个波谷
start
=
trough
[
0
]
j
-=
1
result
[
i
]
=
i
-
start
else
:
if
j
+
1
==
n2
:
result
[
i
]
=
i
-
start
return
result
# 属于未来函数,前M个ZIG转向波峰到当前距离.
# 用法:
# PEAKBARS(K,N,M)表示之字转向ZIG(K,N)的前M个波峰到当前的周期数,M必须大于等于1
# 例如: PEAKBARS(0,5,1)表示%5开盘价ZIG转向的上一个波峰到当前的周期数
def
PEAKBARS
(
self
,
data
,
n
,
n2
)
:
zigData
=
self
.
ZIG
(
data
,
n
)
# 计算ZIG
zigDataLen
=
len
(
zigData
)
dataLen
=
len
(
data
)
result
=
JSComplierHelper
.
CreateArray
(
dataLen
)
for
i
in
range
(
len
(
zigDataLen
))
:
if
JSComplierHelper
.
IsNumber
(
zigData
[
i
])
:
break
trough
=
JSComplierHelper
.
CreateArray
(
dataLen
)
start
=
i
for
i
in
range
(
i
,
zigDataLen
)
:
# 第1个波峰
if
(
i
+
1
<
zigDataLen
and
i
-
1
>=
0
and
zigData
[
i
]
>
zigData
[
i
-
1
]
and
zigData
[
i
]
>
zigData
[
i
+
1
])
:
# 波峰
trough
[
0
]
=
i
break
j
=
0
for
i
in
range
(
i
+
1
,
zigDataLen
)
:
if
(
i
+
1
<
zigDataLen
and
i
-
1
>=
0
and
zigData
[
i
]
>
zigData
[
i
-
1
]
and
zigData
[
i
]
>
zigData
[
i
+
1
])
:
# 波峰
# console.log('[TROUGHBARS] i',i,zigData[i]);
j
+=
1
trough
[
j
]
=
i
if
j
+
1
==
n2
:
result
[
i
]
=
i
-
start
elif
j
+
1
>
n2
:
trough
.
pop
(
0
)
# 大于计算的波谷数,去掉第1个波谷
start
=
trough
[
0
]
j
-=
1
result
[
i
]
=
i
-
start
else
:
if
j
+
1
==
n2
:
result
[
i
]
=
i
-
start
return
result
# 函数调用
def
CallFunction
(
self
,
name
,
args
,
node
,
symbolData
=
None
)
:
if
name
==
'MAX'
:
...
...
@@ -2572,9 +2726,9 @@ class JSAlgorithm() :
elif
name
==
'ZIG'
:
return
self
.
ZIG
(
args
[
0
],
args
[
1
])
elif
name
==
'TROUGHBARS'
:
return
self
.
TROUGHBARS
(
args
[
0
],
args
[
1
],
args
[
2
]
)
return
self
.
TROUGHBARS
(
args
[
0
],
args
[
1
],
int
(
args
[
2
])
)
elif
name
==
'PEAKBARS'
:
return
self
.
PEAKBARS
(
args
[
0
],
args
[
1
],
args
[
2
]
)
return
self
.
PEAKBARS
(
args
[
0
],
args
[
1
],
int
(
args
[
2
])
)
elif
name
==
'COST'
:
return
self
.
COST
(
args
[
0
],
node
)
elif
name
==
'WINNER'
:
...
...
umychart_python/umychart_complier_pandas_help.py
0 → 100644
浏览文件 @
c1641cf0
import
pandas
as
pd
import
numpy
as
np
class
JSComplierPandasHelper
:
@
staticmethod
# 把指标结果数据转化为pandas格式的时间序列
def
ToDateTimeSeries
(
data
)
:
result
=
{}
if
data
.
Time
:
# 分钟K线
aryIndex
=
[]
for
i
in
range
(
len
(
data
.
Date
))
:
date
=
data
.
Date
[
i
]
time
=
data
.
Time
[
i
]
year
,
month
,
day
=
int
(
date
/
10000
),
int
(
date
%
10000
/
100
),
int
(
date
%
100
)
hour
,
minute
=
int
(
time
/
100
),
int
(
time
%
100
)
aryIndex
.
append
(
pd
.
Timestamp
(
year
=
year
,
month
=
month
,
day
=
day
,
hour
=
hour
,
minute
=
minute
))
else
:
# 日线K线
aryIndex
=
[]
for
item
in
data
.
Date
:
year
,
month
,
day
=
int
(
item
/
10000
),
int
(
item
%
10000
/
100
),
int
(
item
%
100
)
aryIndex
.
append
(
pd
.
Timestamp
(
year
=
year
,
month
=
month
,
day
=
day
))
for
outItem
in
data
.
OutVar
:
indexName
=
outItem
.
Name
aryValue
=
[]
for
item
in
outItem
.
Data
:
if
item
==
None
:
aryValue
.
append
(
np
.
NaN
)
else
:
aryValue
.
append
(
item
)
result
[
indexName
]
=
pd
.
Series
(
aryValue
,
index
=
pd
.
to_datetime
(
aryIndex
))
print
(
'[JSComplierPandasHelper::ToDateTimeSeries] name='
,
indexName
)
print
(
result
[
indexName
])
return
result
@
staticmethod
# 转化为DataFrame格式
def
ToDataFrame
(
data
)
:
if
data
.
Time
:
# 分钟K线
aryIndex
=
[]
for
i
in
range
(
len
(
data
.
Date
))
:
date
=
data
.
Date
[
i
]
time
=
data
.
Time
[
i
]
year
,
month
,
day
=
int
(
date
/
10000
),
int
(
date
%
10000
/
100
),
int
(
date
%
100
)
hour
,
minute
=
int
(
time
/
100
),
int
(
time
%
100
)
aryIndex
.
append
(
pd
.
Timestamp
(
year
=
year
,
month
=
month
,
day
=
day
,
hour
=
hour
,
minute
=
minute
))
else
:
# 日线K线
aryIndex
=
[]
for
item
in
data
.
Date
:
year
,
month
,
day
=
int
(
item
/
10000
),
int
(
item
%
10000
/
100
),
int
(
item
%
100
)
aryIndex
.
append
(
pd
.
Timestamp
(
year
=
year
,
month
=
month
,
day
=
day
))
df
=
pd
.
DataFrame
(
index
=
pd
.
to_datetime
(
aryIndex
))
for
outItem
in
data
.
OutVar
:
indexName
=
outItem
.
Name
aryValue
=
[]
for
item
in
outItem
.
Data
:
if
item
==
None
:
aryValue
.
append
(
np
.
NaN
)
else
:
aryValue
.
append
(
item
)
df
[
indexName
]
=
aryValue
print
(
'[JSComplierPandasHelper::ToDateTimeSeries] dispaly data
\n
'
,
df
)
return
df
\ No newline at end of file
umychart_python/umychart_complier_testcase.py
浏览文件 @
c1641cf0
...
...
@@ -6,6 +6,7 @@ import webbrowser
from
umychart_complier_jscomplier
import
JSComplier
,
SymbolOption
,
HQ_DATA_TYPE
from
umychart_complier_jscomplier
import
ScriptIndexConsole
,
ScriptIndexItem
,
SymbolOption
,
RequestOption
,
HQ_DATA_TYPE
,
ArgumentItem
from
umychart_webtemplate
import
*
from
umychart_complier_pandas_help
import
JSComplierPandasHelper
class
TestCase
:
def
__init__
(
self
,
code
,
option
=
SymbolOption
())
:
...
...
@@ -279,7 +280,7 @@ def Test_ScriptIndexConsole():
symbol
=
'000001.sz'
,
right
=
1
,
# 复权 0 不复权 1 前复权 2 后复权
period
=
0
,
# 周期 0=日线 1=周线 2=月线 3=年线 4=1分钟 5=5分钟 6=15分钟 7=30分钟 8=60分钟
request
=
RequestOption
(
maxDataCount
=
500
)
request
=
RequestOption
(
maxDataCount
=
500
,
maxMinuteDayCount
=
3
)
)
result
=
indexConsole
.
ExecuteScript
(
option
)
...
...
@@ -287,6 +288,9 @@ def Test_ScriptIndexConsole():
return
print
(
'run successfully.'
)
JSComplierPandasHelper
.
ToDateTimeSeries
(
result
)
# 转化为pandas Series 数据格式
JSComplierPandasHelper
.
ToDataFrame
(
result
)
# 转化为pandas DataFrame 数据格式
jsonData
=
result
.
ToJson
()
varName
=
'jsonData'
# 数据变量名字
...
...
vuehqchart/src/jscommon/umychart.js
浏览文件 @
c1641cf0
...
...
@@ -948,6 +948,12 @@ function JSChart(divElement)
}
}
this.SaveToImage = function (format,colorGB) //format=保存的文件格式, colorGB=背景色
{
if (this.JSChartContainer && typeof (this.JSChartContainer.SaveToImage) == 'function')
return this.JSChartContainer.SaveToImage(format,colorGB);
}
//事件回调
this.AddEventCallback=function(obj)
{
...
...
@@ -2368,6 +2374,114 @@ function JSChartContainer(uielement)
return false;
}
// 保存图片
this.SaveToImage = function (format,colorGB)
{
if (this.UIElement.width<=0 || this.UIElement.height<=0) return null;
if (this.ChartSplashPaint && this.ChartSplashPaint.IsEnableSplash) return null; // 数据加载中不能保存
console.log('[JSChartContainer::SaveToImage]', this.UIElement);
clrBG='rgb(255,255,255)';
if (colorGB) clrBG=colorGB;
this.Canvas.clearRect(0,0,this.UIElement.width,this.UIElement.height);
this.Canvas.fillStyle=clrBG;
this.Canvas.fillRect(0,0,this.UIElement.width,this.UIElement.height); //画一个背景色, 不然是一个黑的背景
var pixelTatio = GetDevicePixelRatio(); //获取设备的分辨率
this.Canvas.lineWidth=pixelTatio; //手机端需要根据分辨率比调整线段宽度
this.Frame.Draw(); //框架
for (var i in this.ChartPaint) //框架内图形
{
var item=this.ChartPaint[i];
if (item.IsDrawFirst)
item.Draw();
}
for(var i in this.ChartPaint)
{
var item=this.ChartPaint[i];
if (!item.IsDrawFirst)
item.Draw();
}
for(var i in this.ChartPaintEx)
{
var item=this.ChartPaintEx[i];
item.Draw();
}
for(var i in this.OverlayChartPaint) //叠加股票
{
var item=this.OverlayChartPaint[i];
item.Draw();
}
for(var i in this.ExtendChartPaint) //固定扩展图形
{
var item=this.ExtendChartPaint[i];
if (!item.IsDynamic && item.IsAnimation==false) item.Draw();
}
if (this.Frame.DrawInsideHorizontal) this.Frame.DrawInsideHorizontal();
this.Frame.DrawLock();
for(var i in this.ExtendChartPaint) //动态扩展图形
{
var item=this.ExtendChartPaint[i];
if (item.IsDynamic && item.DrawAfterTitle===false) item.Draw();
}
if (this.LastPoint.X!=null || this.LastPoint.Y!=null)
{
if (this.ChartCorssCursor) //十字光标不画
{
this.ChartCorssCursor.LastPoint=this.LastPoint;
this.ChartCorssCursor.CursorIndex=this.CursorIndex;
}
}
for(var i in this.TitlePaint)
{
var item=this.TitlePaint[i];
if (!item.IsDynamic) continue;
item.CursorIndex=this.CursorIndex;
item.Draw();
}
for(var i in this.ExtendChartPaint) //动态扩展图形
{
var item=this.ExtendChartPaint[i];
if (item.IsDynamic && item.DrawAfterTitle===true && item.IsAnimation==false) item.Draw();
}
if (this.EnableAnimation)
{
for(var i in this.ExtendChartPaint) //动画
{
var item=this.ExtendChartPaint[i];
if (item.IsAnimation===true) item.Draw();
}
}
for(var i in this.ChartDrawPicture)
{
var item=this.ChartDrawPicture[i];
item.Draw();
}
if (this.CurrentChartDrawPicture && this.CurrentChartDrawPicture.Status!=10)
{
this.CurrentChartDrawPicture.Draw();
}
var dataURL=this.UIElement.toDataURL(format ? format:'image/png', 1.0);
console.log('[JSChartContainer::SaveToImage] data= ', dataURL);
return dataURL;
}
}
function GetDevicePixelRatio()
...
...
webhqchart.demo/jscommon/umychart.js
浏览文件 @
c1641cf0
...
...
@@ -948,6 +948,12 @@ function JSChart(divElement)
}
}
this.SaveToImage = function (format,colorGB) //format=保存的文件格式, colorGB=背景色
{
if (this.JSChartContainer && typeof (this.JSChartContainer.SaveToImage) == 'function')
return this.JSChartContainer.SaveToImage(format,colorGB);
}
//事件回调
this.AddEventCallback=function(obj)
{
...
...
@@ -2368,6 +2374,114 @@ function JSChartContainer(uielement)
return false;
}
// 保存图片
this.SaveToImage = function (format,colorGB)
{
if (this.UIElement.width<=0 || this.UIElement.height<=0) return null;
if (this.ChartSplashPaint && this.ChartSplashPaint.IsEnableSplash) return null; // 数据加载中不能保存
console.log('[JSChartContainer::SaveToImage]', this.UIElement);
clrBG='rgb(255,255,255)';
if (colorGB) clrBG=colorGB;
this.Canvas.clearRect(0,0,this.UIElement.width,this.UIElement.height);
this.Canvas.fillStyle=clrBG;
this.Canvas.fillRect(0,0,this.UIElement.width,this.UIElement.height); //画一个背景色, 不然是一个黑的背景
var pixelTatio = GetDevicePixelRatio(); //获取设备的分辨率
this.Canvas.lineWidth=pixelTatio; //手机端需要根据分辨率比调整线段宽度
this.Frame.Draw(); //框架
for (var i in this.ChartPaint) //框架内图形
{
var item=this.ChartPaint[i];
if (item.IsDrawFirst)
item.Draw();
}
for(var i in this.ChartPaint)
{
var item=this.ChartPaint[i];
if (!item.IsDrawFirst)
item.Draw();
}
for(var i in this.ChartPaintEx)
{
var item=this.ChartPaintEx[i];
item.Draw();
}
for(var i in this.OverlayChartPaint) //叠加股票
{
var item=this.OverlayChartPaint[i];
item.Draw();
}
for(var i in this.ExtendChartPaint) //固定扩展图形
{
var item=this.ExtendChartPaint[i];
if (!item.IsDynamic && item.IsAnimation==false) item.Draw();
}
if (this.Frame.DrawInsideHorizontal) this.Frame.DrawInsideHorizontal();
this.Frame.DrawLock();
for(var i in this.ExtendChartPaint) //动态扩展图形
{
var item=this.ExtendChartPaint[i];
if (item.IsDynamic && item.DrawAfterTitle===false) item.Draw();
}
if (this.LastPoint.X!=null || this.LastPoint.Y!=null)
{
if (this.ChartCorssCursor) //十字光标不画
{
this.ChartCorssCursor.LastPoint=this.LastPoint;
this.ChartCorssCursor.CursorIndex=this.CursorIndex;
}
}
for(var i in this.TitlePaint)
{
var item=this.TitlePaint[i];
if (!item.IsDynamic) continue;
item.CursorIndex=this.CursorIndex;
item.Draw();
}
for(var i in this.ExtendChartPaint) //动态扩展图形
{
var item=this.ExtendChartPaint[i];
if (item.IsDynamic && item.DrawAfterTitle===true && item.IsAnimation==false) item.Draw();
}
if (this.EnableAnimation)
{
for(var i in this.ExtendChartPaint) //动画
{
var item=this.ExtendChartPaint[i];
if (item.IsAnimation===true) item.Draw();
}
}
for(var i in this.ChartDrawPicture)
{
var item=this.ChartDrawPicture[i];
item.Draw();
}
if (this.CurrentChartDrawPicture && this.CurrentChartDrawPicture.Status!=10)
{
this.CurrentChartDrawPicture.Draw();
}
var dataURL=this.UIElement.toDataURL(format ? format:'image/png', 1.0);
console.log('[JSChartContainer::SaveToImage] data= ', dataURL);
return dataURL;
}
}
function GetDevicePixelRatio()
...
...
webhqchart/umychart.js
浏览文件 @
c1641cf0
...
...
@@ -948,6 +948,12 @@ function JSChart(divElement)
}
}
this.SaveToImage = function (format,colorGB) //format=保存的文件格式, colorGB=背景色
{
if (this.JSChartContainer && typeof (this.JSChartContainer.SaveToImage) == 'function')
return this.JSChartContainer.SaveToImage(format,colorGB);
}
//事件回调
this.AddEventCallback=function(obj)
{
...
...
@@ -2368,6 +2374,114 @@ function JSChartContainer(uielement)
return false;
}
// 保存图片
this.SaveToImage = function (format,colorGB)
{
if (this.UIElement.width<=0 || this.UIElement.height<=0) return null;
if (this.ChartSplashPaint && this.ChartSplashPaint.IsEnableSplash) return null; // 数据加载中不能保存
console.log('[JSChartContainer::SaveToImage]', this.UIElement);
clrBG='rgb(255,255,255)';
if (colorGB) clrBG=colorGB;
this.Canvas.clearRect(0,0,this.UIElement.width,this.UIElement.height);
this.Canvas.fillStyle=clrBG;
this.Canvas.fillRect(0,0,this.UIElement.width,this.UIElement.height); //画一个背景色, 不然是一个黑的背景
var pixelTatio = GetDevicePixelRatio(); //获取设备的分辨率
this.Canvas.lineWidth=pixelTatio; //手机端需要根据分辨率比调整线段宽度
this.Frame.Draw(); //框架
for (var i in this.ChartPaint) //框架内图形
{
var item=this.ChartPaint[i];
if (item.IsDrawFirst)
item.Draw();
}
for(var i in this.ChartPaint)
{
var item=this.ChartPaint[i];
if (!item.IsDrawFirst)
item.Draw();
}
for(var i in this.ChartPaintEx)
{
var item=this.ChartPaintEx[i];
item.Draw();
}
for(var i in this.OverlayChartPaint) //叠加股票
{
var item=this.OverlayChartPaint[i];
item.Draw();
}
for(var i in this.ExtendChartPaint) //固定扩展图形
{
var item=this.ExtendChartPaint[i];
if (!item.IsDynamic && item.IsAnimation==false) item.Draw();
}
if (this.Frame.DrawInsideHorizontal) this.Frame.DrawInsideHorizontal();
this.Frame.DrawLock();
for(var i in this.ExtendChartPaint) //动态扩展图形
{
var item=this.ExtendChartPaint[i];
if (item.IsDynamic && item.DrawAfterTitle===false) item.Draw();
}
if (this.LastPoint.X!=null || this.LastPoint.Y!=null)
{
if (this.ChartCorssCursor) //十字光标不画
{
this.ChartCorssCursor.LastPoint=this.LastPoint;
this.ChartCorssCursor.CursorIndex=this.CursorIndex;
}
}
for(var i in this.TitlePaint)
{
var item=this.TitlePaint[i];
if (!item.IsDynamic) continue;
item.CursorIndex=this.CursorIndex;
item.Draw();
}
for(var i in this.ExtendChartPaint) //动态扩展图形
{
var item=this.ExtendChartPaint[i];
if (item.IsDynamic && item.DrawAfterTitle===true && item.IsAnimation==false) item.Draw();
}
if (this.EnableAnimation)
{
for(var i in this.ExtendChartPaint) //动画
{
var item=this.ExtendChartPaint[i];
if (item.IsAnimation===true) item.Draw();
}
}
for(var i in this.ChartDrawPicture)
{
var item=this.ChartDrawPicture[i];
item.Draw();
}
if (this.CurrentChartDrawPicture && this.CurrentChartDrawPicture.Status!=10)
{
this.CurrentChartDrawPicture.Draw();
}
var dataURL=this.UIElement.toDataURL(format ? format:'image/png', 1.0);
console.log('[JSChartContainer::SaveToImage] data= ', dataURL);
return dataURL;
}
}
function GetDevicePixelRatio()
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录