/**
* Copyright (c) 2018-present clchart Contributors.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
// 画买卖盘
// 画买卖盘和Tick
import {
_fillRect,
_drawRect,
_drawHline,
_setLineWidth,
_drawTxt,
_getTxtWidth,
_drawBegin,
_drawEnd
} from '../util/cl.draw'
import {
fromTTimeToStr,
formatVolume,
formatPrice,
updateJsonOfDeep,
offsetRect
} from '../util/cl.tool'
import {
initCommonInfo,
checkLayout
} from '../chart/cl.chart.init'
import {
CHART_LAYOUT,
CHART_ORDER
} from '../cl.chart.def'
import getValue from '../data/cl.data.tools'
import {
FIELD_NOW,
FIELD_NOW_IDX,
FIELD_TICK
} from '../data/../cl.data.def'
/**
* Class representing ClChartOrder
* @export
* @class ClChartOrder
*/
export default class ClChartOrder {
/**
* Creates an instance of ClChartOrder.
* @param {Object} father order chart's parent context
*/
constructor (father) {
initCommonInfo(this, father)
this.linkInfo = father.linkInfo
this.static = this.father.dataLayer.static
}
/**
* init order chart
* @param {Object} cfg
* @memberof ClChartOrder
*/
init (cfg) {
this.rectMain = cfg.rectMain || { left: 0, top: 0, width: 200, height: 300 }
this.layout = updateJsonOfDeep(cfg.layout, CHART_LAYOUT)
this.config = updateJsonOfDeep(cfg.config, CHART_ORDER)
this.style = cfg.config.style || 'normal'
// 下面对配置做一定的校验
this.checkConfig()
// 再做一些初始化运算,下面的运算范围是初始化设置后基本不变的数据
this.setPublicRect()
}
/**
* check config
* @memberof ClChartOrder
*/
checkConfig () { // 检查配置有冲突的修正过来
checkLayout(this.layout)
this.txtLen = _getTxtWidth(this.context, '涨', this.layout.digit.font, this.layout.digit.pixel)
this.timeLen = _getTxtWidth(this.context, '15:30', this.layout.digit.font, this.layout.digit.pixel)
this.volLen = _getTxtWidth(this.context, '888888', this.layout.digit.font, this.layout.digit.pixel)
this.closeLen = _getTxtWidth(this.context, '888.88', this.layout.digit.font, this.layout.digit.pixel)
}
/**
* Calculate all rectangular areas
* @memberof ClChartOrder
*/
setPublicRect () {
this.rectChart = offsetRect(this.rectMain, this.layout.margin)
}
/**
* handle click event
* @memberof ClChartOrder
*/
onClick (/* e */) {
if (this.isIndex) return // 如果是指数就啥也不干
if (this.style === 'normal') {
this.style = 'tiny'
} else {
this.style = 'normal'
}
this.father.onPaint(this)
}
/**
* paint order chart
* @memberof ClChartOrder
*/
onPaint () {
this.codeInfo = this.father.getData('INFO')
this.orderData = this.father.getData('NOW')
this.tickData = this.father.getData('TICK')
if (this.orderData === undefined || this.tickData === undefined) return
this.orderData.coinunit = this.static.coinunit
this.tickData.coinunit = this.static.coinunit
this.isIndex = getValue(this.codeInfo, 'type') === 0
_setLineWidth(this.context, this.scale)
this.drawClear() // 清理画图区
this.drawReady() // 数据准备
if (this.isIndex) {
this.drawIndex()
} else {
this.drawOrder()
}
this.drawTick()
}
/**
* clear chart
* @memberof ClChartOrder
*/
drawClear () {
_fillRect(this.context, this.rectMain.left, this.rectMain.top, this.rectMain.width, this.rectMain.height, this.color.back)
}
/**
* set ready for draw
* @memberof ClChartOrder
*/
drawReady () {
if (this.tickData === undefined) {
this.tickData = {
key: 'TICK',
fields: FIELD_TICK,
value: []
}
}
if (this.orderData === undefined) {
this.orderData = {
key: 'NOW',
fields: FIELD_NOW,
value: []
}
}
let yy
if (this.style === 'normal') {
yy = this.rectChart.top + (this.layout.digit.height + this.layout.digit.spaceX) * 10
} else {
yy = this.rectChart.top + (this.layout.digit.height + this.layout.digit.spaceX) * 2
}
if (this.isIndex) {
yy = this.rectChart.top + (this.layout.digit.height + this.layout.digit.spaceX) * 4
this.rectOrder = {
left: this.rectChart.left,
top: this.rectChart.top,
width: this.rectChart.width,
height: yy
}
} else {
this.rectOrder = {
left: this.rectChart.left,
top: this.rectChart.top,
width: this.rectChart.width,
height: yy
}
}
if (this.config.title.display !== 'none') {
this.rectTitle = {
left: this.rectChart.left,
top: yy,
width: this.rectChart.width,
height: this.layout.title.height
}
} else {
this.rectTitle = {
left: 0,
top: 0,
width: 0,
height: 0
}
}
yy += this.rectTitle.height
this.rectTick = {
left: this.rectChart.left,
top: yy,
width: this.rectChart.width,
height: this.rectChart.height - yy - this.layout.digit.height / 2
}
}
/**
* get color by close and before data
* @param {Number} close
* @param {Number} before
* @return {String} color
* @memberof ClChartOrder
*/
getColor (close, before) {
if (close > before) {
return this.color.red
} else if (close < before) {
return this.color.green
} else {
return this.color.white
}
}
/**
* draw index
* @memberof ClChartOrder
*/
drawIndex () {
_drawBegin(this.context, this.color.grid)
_drawRect(this.context, this.rectMain.left, this.rectMain.top, this.rectMain.width, this.rectMain.height)
const offy = this.rectOrder.height / 3
const offx = this.rectOrder.width / 3
let xx, yy, len
let value
yy = this.rectOrder.top + Math.floor((offy - this.layout.digit.height) / 2) // 画最上面的
xx = this.rectOrder.left + (offx - this.txtLen) / 2
_drawTxt(this.context, xx, yy, '涨', this.layout.digit.font, this.layout.digit.pixel, this.color.txt)
xx = this.rectOrder.left + offx + (offx - this.txtLen) / 2
_drawTxt(this.context, xx, yy, '跌', this.layout.digit.font, this.layout.digit.pixel, this.color.txt)
xx = this.rectOrder.left + 2 * offx + (offx - this.txtLen) / 2
_drawTxt(this.context, xx, yy, '平', this.layout.digit.font, this.layout.digit.pixel, this.color.txt)
const inow = {
key: 'NOW',
fields: FIELD_NOW_IDX,
value: this.orderData.value
}
yy = this.rectOrder.top + offy + Math.floor((offy - this.layout.digit.height) / 2) // 画最上面的
value = formatVolume(getValue(inow, 'ups'), 1)
len = _getTxtWidth(this.context, value, this.layout.digit.font, this.layout.digit.pixel)
xx = this.rectOrder.left + (offx - len) / 2
_drawTxt(this.context, xx, yy, value, this.layout.digit.font, this.layout.digit.pixel, this.color.txt)
value = formatVolume(getValue(inow, 'downs'), 1)
len = _getTxtWidth(this.context, value, this.layout.digit.font, this.layout.digit.pixel)
xx = this.rectOrder.left + offx + (offx - len) / 2
_drawTxt(this.context, xx, yy, value, this.layout.digit.font, this.layout.digit.pixel, this.color.txt)
value = formatVolume(getValue(inow, 'mids'), 1)
len = _getTxtWidth(this.context, value, this.layout.digit.font, this.layout.digit.pixel)
xx = this.rectOrder.left + 2 * offx + (offx - len) / 2
_drawTxt(this.context, xx, yy, value, this.layout.digit.font, this.layout.digit.pixel, this.color.txt)
yy = this.rectOrder.top + 2 * offy + Math.floor((offy - this.layout.digit.height) / 2)
value = formatVolume(getValue(inow, 'upvol'), 1)
len = _getTxtWidth(this.context, value, this.layout.digit.font, this.layout.digit.pixel)
xx = this.rectOrder.left + (offx - len) / 2
_drawTxt(this.context, xx, yy, value, this.layout.digit.font, this.layout.digit.pixel, this.color.txt)
value = formatVolume(getValue(inow, 'downvol'), 1)
len = _getTxtWidth(this.context, value, this.layout.digit.font, this.layout.digit.pixel)
xx = this.rectOrder.left + offx + (offx - len) / 2
_drawTxt(this.context, xx, yy, value, this.layout.digit.font, this.layout.digit.pixel, this.color.txt)
if (this.config.title.display !== 'none') {
_drawHline(this.context, this.rectTitle.left, this.rectTitle.left + this.rectTitle.width, this.rectTitle.top)
_drawHline(this.context, this.rectTitle.left, this.rectTitle.left + this.rectTitle.width, this.rectTitle.top + this.rectTitle.height)
const ticklen = _getTxtWidth(this.context, '分时成交', this.layout.title.font, this.layout.digit.pixel)
xx = this.rectTitle.left + (this.rectTitle.width - ticklen) / 2
yy = this.rectTitle.top + 3 * this.scale
_drawTxt(this.context, xx, yy, '分时成交',
this.layout.digit.font, this.layout.digit.pixel, this.color.txt)
}
_drawEnd(this.context)
}
/**
* draw order
* @memberof ClChartOrder
*/
drawOrder () {
const xpos = this.drawGridLine() // 先画线格
if (this.orderData === undefined || this.orderData.value.length < 1) {
return
}
const offx = (this.rectOrder.width - xpos - 2 * this.layout.digit.spaceX - this.closeLen - this.volLen) / 2
let mmpCount = 1
if (this.style === 'normal') {
mmpCount = 5
}
const offy = this.rectOrder.height / (mmpCount * 2)
let xx, yy
let value, clr
yy = this.rectOrder.top + Math.floor((offy - this.layout.digit.height) / 2) // 画最上面的
for (let idx = mmpCount; idx >= 1; idx--) {
xx = this.rectOrder.left + xpos + offx + this.closeLen
if (!this.linkInfo.hideInfo) {
value = getValue(this.orderData, 'sell' + idx)
clr = this.getColor(value, this.static.before)
_drawTxt(this.context, xx, yy, formatPrice(value, this.static.coinunit),
this.layout.digit.font, this.layout.digit.pixel, clr, {
x: 'end'
})
}
xx += offx + this.volLen + this.layout.digit.spaceX
value = getValue(this.orderData, 'sellvol' + idx)
clr = this.color.vol
_drawTxt(this.context, xx, yy, formatVolume(value, this.static.volzoom),
this.layout.digit.font, this.layout.digit.pixel, clr, {
x: 'end'
})
yy += offy
}
for (let idx = 1; idx <= mmpCount; idx++) {
xx = this.rectOrder.left + xpos + offx + this.closeLen
if (!this.linkInfo.hideInfo) {
value = getValue(this.orderData, 'buy' + idx)
clr = this.getColor(value, this.static.before)
_drawTxt(this.context, xx, yy, formatPrice(value, this.static.coinunit),
this.layout.digit.font, this.layout.digit.pixel, clr, {
x: 'end'
})
}
xx += offx + this.volLen + this.layout.digit.spaceX
value = getValue(this.orderData, 'buyvol' + idx)
clr = this.color.vol
_drawTxt(this.context, xx, yy, formatVolume(value, this.static.volzoom),
this.layout.digit.font, this.layout.digit.pixel, clr, {
x: 'end'
})
yy += offy
}
}
/**
* draw tick
* @memberof ClChartOrder
*/
drawTick () {
if (this.tickData === undefined || this.tickData.value.length < 1) return
const maxlines = Math.floor(this.rectTick.height / this.layout.digit.height) - 1 // 屏幕最大能显示多少条记录
const recs = this.tickData.value.length
const beginIndex = recs > maxlines ? recs - maxlines : 0
const offy = this.rectTick.height / maxlines
let xx, yy
let value, clr
let offx = (this.rectTick.width - 4 * this.layout.digit.spaceX - this.timeLen - this.closeLen - this.volLen) / 2
if (this.isIndex) offx = (this.rectTick.width - 3 * this.layout.digit.spaceX - this.timeLen - this.closeLen) / 2
yy = this.rectTick.top + 2 + Math.floor((offy - this.layout.digit.pixel) / 2) // 画最上面的
for (let idx = recs - 1; idx >= beginIndex; idx--) {
// for (let idx = beginIndex; idx < recs; idx++) {
xx = this.rectTick.left + this.layout.digit.spaceX + this.timeLen
value = getValue(this.tickData, 'time', idx)
clr = this.color.txt
let str
if (idx === 0) {
str = fromTTimeToStr(value, 'minute')
} else {
str = fromTTimeToStr(value, 'minute', getValue(this.tickData, 'time', idx - 1))
}
_drawTxt(this.context, xx, yy, str,
this.layout.digit.font, this.layout.digit.pixel, clr, {
x: 'end'
})
if (this.isIndex) {
xx = this.rectTick.left + this.rectTick.width - this.layout.digit.spaceX
value = getValue(this.tickData, 'close', idx)
clr = this.getColor(value, this.static.before)
_drawTxt(this.context, xx, yy, formatPrice(value, this.static.coinunit),
this.layout.digit.font, this.layout.digit.pixel, clr, {
x: 'end'
})
yy += offy
continue
}
xx += offx + this.closeLen + this.layout.digit.spaceX
if (!this.linkInfo.hideInfo) {
value = getValue(this.tickData, 'close', idx)
clr = this.getColor(value, this.static.before)
_drawTxt(this.context, xx, yy, formatPrice(value, this.static.coinunit),
this.layout.digit.font, this.layout.digit.pixel, clr, {
x: 'end'
})
}
xx += offx + this.volLen + this.layout.digit.spaceX
value = getValue(this.tickData, 'decvol', idx)
clr = this.color.vol
_drawTxt(this.context, xx, yy, formatVolume(value, this.static.volzoom),
this.layout.digit.font, this.layout.digit.pixel, clr, {
x: 'end'
})
yy += offy
}
}
/**
* draw grid line
* @return {Number}
* @memberof ClChartOrder
*/
drawGridLine () {
_drawBegin(this.context, this.color.grid)
_drawRect(this.context, this.rectMain.left, this.rectMain.top, this.rectMain.width, this.rectMain.height)
let mmpCount = 1
if (this.style === 'normal') {
mmpCount = 5
}
let len = 0
_drawHline(this.context, this.rectOrder.left, this.rectOrder.left + this.rectOrder.width, this.rectOrder.top + Math.floor(this.rectOrder.height / 2))
let xx, yy, value
const strint = ['①', '②', '③', '④', '⑤']
const offy = this.rectOrder.height / (mmpCount * 2)
len = _getTxtWidth(this.context, '卖①', this.layout.title.font, this.layout.digit.height)
yy = this.rectOrder.top + Math.floor((offy - this.layout.digit.pixel) / 2) // 画最上面的
for (let idx = mmpCount - 1; idx >= 0; idx--) {
xx = this.rectOrder.left + this.layout.digit.spaceX
value = '卖' + strint[idx]
_drawTxt(this.context, xx, yy, value,
this.layout.digit.font, this.layout.digit.pixel, this.color.txt)
yy += offy
}
for (let idx = 0; idx < mmpCount; idx++) {
xx = this.rectOrder.left + this.layout.digit.spaceX
value = '买' + strint[idx]
_drawTxt(this.context, xx, yy, value,
this.layout.digit.font, this.layout.digit.pixel, this.color.txt)
yy += offy
}
if (this.config.title.display !== 'none') {
_drawHline(this.context, this.rectTitle.left, this.rectTitle.left + this.rectTitle.width, this.rectTitle.top)
_drawHline(this.context, this.rectTitle.left, this.rectTitle.left + this.rectTitle.width, this.rectTitle.top + this.rectTitle.height)
if (this.style === 'normal') {
value = '分时成交 △'
} else {
value = '分时成交 ▽'
}
const ticklen = _getTxtWidth(this.context, value, this.layout.title.font, this.layout.digit.pixel)
xx = this.rectTitle.left + (this.rectTitle.width - ticklen) / 2
yy = this.rectTitle.top + 3 * this.scale
_drawTxt(this.context, xx, yy, value,
this.layout.digit.font, this.layout.digit.pixel, this.color.txt)
}
_drawEnd(this.context)
return len
}
}