forked from opentiny/tiny-vue
This reverts commit b03de5c569
.
This commit is contained in:
parent
b03de5c569
commit
77969c4b1c
|
@ -10,10 +10,10 @@ export default {
|
|||
TinyBoxplot: ChartBoxplot
|
||||
},
|
||||
data() {
|
||||
const sourceData0 = this.makeData()
|
||||
const sourceData1 = this.makeData()
|
||||
const sourceData2 = this.makeData()
|
||||
return {
|
||||
sourceData0: makeData(),
|
||||
sourceData1: makeData(),
|
||||
sourceData2: makeData(),
|
||||
options: {
|
||||
padding: [50, 30, 55, 20],
|
||||
xAxis: {
|
||||
|
|
|
@ -4,6 +4,4 @@ title: Chart 图表
|
|||
|
||||
# Chart 图表
|
||||
|
||||
**【预告】**: Chart 图表组件预计从 `@opentiny/vue@3.22.0` 版本中移除,后续从 `@opentiny/vue-huicharts` 单独引入。
|
||||
|
||||
Chart 图表组件基于 `hui-charts` 封装,集成自适应、性能提升、数据状态、无障碍能力、刻度优化等特性。
|
||||
<div>基于 hui-charts 封装,一个纯 Javascript 的图表库。</div>
|
||||
|
|
|
@ -4,6 +4,4 @@ title: Chart 图表
|
|||
|
||||
# Chart 图表
|
||||
|
||||
**【预告】**: Chart 图表组件预计从 `@opentiny/vue@3.22.0` 版本中移除,后续从 `@opentiny/vue-huicharts` 单独引入。
|
||||
|
||||
Chart 图表组件基于 `hui-charts` 封装,集成自适应、性能提升、数据状态、无障碍能力、刻度优化等特性。
|
||||
<div>基于 hui-charts 封装,一个纯 Javascript 的图表库。</div>
|
||||
|
|
|
@ -4,6 +4,4 @@ title: Chart 图表
|
|||
|
||||
# Chart 图表
|
||||
|
||||
**【预告】**: Chart 图表组件预计从 `@opentiny/vue@3.22.0` 版本中移除,后续从 `@opentiny/vue-huicharts` 单独引入。
|
||||
|
||||
Chart 图表组件基于 `hui-charts` 封装,集成自适应、性能提升、数据状态、无障碍能力、刻度优化等特性。
|
||||
<div>基于 hui-charts 封装,一个纯 Javascript 的图表库。</div>
|
||||
|
|
|
@ -4,6 +4,4 @@ title: Chart 图表
|
|||
|
||||
# Chart 图表
|
||||
|
||||
**【预告】**: Chart 图表组件预计从 `@opentiny/vue@3.22.0` 版本中移除,后续从 `@opentiny/vue-huicharts` 单独引入。
|
||||
|
||||
Chart 图表组件基于 `hui-charts` 封装,集成自适应、性能提升、数据状态、无障碍能力、刻度优化等特性。
|
||||
<div>基于 hui-charts 封装,一个纯 Javascript 的图表库。</div>
|
||||
|
|
|
@ -4,6 +4,4 @@ title: Chart 图表
|
|||
|
||||
# Chart 图表
|
||||
|
||||
**【预告】**: Chart 图表组件预计从 `@opentiny/vue@3.22.0` 版本中移除,后续从 `@opentiny/vue-huicharts` 单独引入。
|
||||
|
||||
Chart 图表组件基于 `hui-charts` 封装,集成自适应、性能提升、数据状态、无障碍能力、刻度优化等特性。
|
||||
<div>基于 hui-charts 封装,一个纯 Javascript 的图表库。</div>
|
||||
|
|
|
@ -4,6 +4,4 @@ title: Chart 图表
|
|||
|
||||
# Chart 图表
|
||||
|
||||
**【预告】**: Chart 图表组件预计从 `@opentiny/vue@3.22.0` 版本中移除,后续从 `@opentiny/vue-huicharts` 单独引入。
|
||||
|
||||
Chart 图表组件基于 `hui-charts` 封装,集成自适应、性能提升、数据状态、无障碍能力、刻度优化等特性。
|
||||
<div>基于 hui-charts 封装,一个纯 Javascript 的图表库。</div>
|
||||
|
|
|
@ -4,6 +4,4 @@ title: Chart 图表
|
|||
|
||||
# Chart 图表
|
||||
|
||||
**【预告】**: Chart 图表组件预计从 `@opentiny/vue@3.22.0` 版本中移除,后续从 `@opentiny/vue-huicharts` 单独引入。
|
||||
|
||||
Chart 图表组件基于 `hui-charts` 封装,集成自适应、性能提升、数据状态、无障碍能力、刻度优化等特性。
|
||||
<div>基于 hui-charts 封装,一个纯 Javascript 的图表库。</div>
|
||||
|
|
|
@ -4,6 +4,4 @@ title: Chart 图表
|
|||
|
||||
# Chart 图表
|
||||
|
||||
**【预告】**: Chart 图表组件预计从 `@opentiny/vue@3.22.0` 版本中移除,后续从 `@opentiny/vue-huicharts` 单独引入。
|
||||
|
||||
Chart 图表组件基于 `hui-charts` 封装,集成自适应、性能提升、数据状态、无障碍能力、刻度优化等特性。
|
||||
<div>基于 hui-charts 封装,一个纯 Javascript 的图表库。</div>
|
||||
|
|
|
@ -4,6 +4,4 @@ title: Chart 图表
|
|||
|
||||
# Chart 图表
|
||||
|
||||
**【预告】**: Chart 图表组件预计从 `@opentiny/vue@3.22.0` 版本中移除,后续从 `@opentiny/vue-huicharts` 单独引入。
|
||||
|
||||
Chart 图表组件基于 `hui-charts` 封装,集成自适应、性能提升、数据状态、无障碍能力、刻度优化等特性。
|
||||
<div>基于 hui-charts 封装,一个纯 Javascript 的图表库。</div>
|
||||
|
|
|
@ -4,6 +4,4 @@ title: Chart 图表
|
|||
|
||||
# Chart 图表
|
||||
|
||||
**【预告】**: Chart 图表组件预计从 `@opentiny/vue@3.22.0` 版本中移除,后续从 `@opentiny/vue-huicharts` 单独引入。
|
||||
|
||||
Chart 图表组件基于 `hui-charts` 封装,集成自适应、性能提升、数据状态、无障碍能力、刻度优化等特性。
|
||||
<div>基于 hui-charts 封装,一个纯 Javascript 的图表库。</div>
|
||||
|
|
|
@ -4,6 +4,4 @@ title: Chart 图表
|
|||
|
||||
# Chart 图表
|
||||
|
||||
**【预告】**: Chart 图表组件预计从 `@opentiny/vue@3.22.0` 版本中移除,后续从 `@opentiny/vue-huicharts` 单独引入。
|
||||
|
||||
Chart 图表组件基于 `hui-charts` 封装,集成自适应、性能提升、数据状态、无障碍能力、刻度优化等特性。
|
||||
<div>基于 hui-charts 封装,一个纯 Javascript 的图表库。</div>
|
||||
|
|
|
@ -4,6 +4,4 @@ title: Chart 图表
|
|||
|
||||
# Chart 图表
|
||||
|
||||
**【预告】**: Chart 图表组件预计从 `@opentiny/vue@3.22.0` 版本中移除,后续从 `@opentiny/vue-huicharts` 单独引入。
|
||||
|
||||
Chart 图表组件基于 `hui-charts` 封装,集成自适应、性能提升、数据状态、无障碍能力、刻度优化等特性。
|
||||
<div>基于 hui-charts 封装,一个纯 Javascript 的图表库。</div>
|
||||
|
|
|
@ -4,6 +4,4 @@ title: Chart 图表
|
|||
|
||||
# Chart 图表
|
||||
|
||||
**【预告】**: Chart 图表组件预计从 `@opentiny/vue@3.22.0` 版本中移除,后续从 `@opentiny/vue-huicharts` 单独引入。
|
||||
|
||||
Chart 图表组件基于 `hui-charts` 封装,集成自适应、性能提升、数据状态、无障碍能力、刻度优化等特性。
|
||||
<div>基于 hui-charts 封装,一个纯 Javascript 的图表库。</div>
|
||||
|
|
|
@ -4,6 +4,4 @@ title: Chart 图表
|
|||
|
||||
# Chart 图表
|
||||
|
||||
**【预告】**: Chart 图表组件预计从 `@opentiny/vue@3.22.0` 版本中移除,后续从 `@opentiny/vue-huicharts` 单独引入。
|
||||
|
||||
Chart 图表组件基于 `hui-charts` 封装,集成自适应、性能提升、数据状态、无障碍能力、刻度优化等特性。
|
||||
<div>基于 hui-charts 封装,一个纯 Javascript 的图表库。</div>
|
||||
|
|
|
@ -4,6 +4,4 @@ title: Chart 图表
|
|||
|
||||
# Chart 图表
|
||||
|
||||
**【预告】**: Chart 图表组件预计从 `@opentiny/vue@3.22.0` 版本中移除,后续从 `@opentiny/vue-huicharts` 单独引入。
|
||||
|
||||
Chart 图表组件基于 `hui-charts` 封装,集成自适应、性能提升、数据状态、无障碍能力、刻度优化等特性。
|
||||
<div>基于 hui-charts 封装,一个纯 Javascript 的图表库。</div>
|
||||
|
|
|
@ -4,6 +4,4 @@ title: Chart 图表
|
|||
|
||||
# Chart 图表
|
||||
|
||||
**【预告】**: Chart 图表组件预计从 `@opentiny/vue@3.22.0` 版本中移除,后续从 `@opentiny/vue-huicharts` 单独引入。
|
||||
|
||||
Chart 图表组件基于 `hui-charts` 封装,集成自适应、性能提升、数据状态、无障碍能力、刻度优化等特性。
|
||||
<div>基于 hui-charts 封装,一个纯 Javascript 的图表库。</div>
|
||||
|
|
|
@ -4,6 +4,4 @@ title: Chart 图表
|
|||
|
||||
# Chart 图表
|
||||
|
||||
**【预告】**: Chart 图表组件预计从 `@opentiny/vue@3.22.0` 版本中移除,后续从 `@opentiny/vue-huicharts` 单独引入。
|
||||
|
||||
Chart 图表组件基于 `hui-charts` 封装,集成自适应、性能提升、数据状态、无障碍能力、刻度优化等特性。
|
||||
<div>基于 hui-charts 封装,一个纯 Javascript 的图表库。</div>
|
||||
|
|
|
@ -4,6 +4,4 @@ title: Chart 图表
|
|||
|
||||
# Chart 图表
|
||||
|
||||
**【预告】**: Chart 图表组件预计从 `@opentiny/vue@3.22.0` 版本中移除,后续从 `@opentiny/vue-huicharts` 单独引入。
|
||||
|
||||
Chart 图表组件基于 `hui-charts` 封装,集成自适应、性能提升、数据状态、无障碍能力、刻度优化等特性。
|
||||
<div>基于 hui-charts 封装,一个纯 Javascript 的图表库。</div>
|
||||
|
|
|
@ -4,6 +4,4 @@ title: Chart 图表
|
|||
|
||||
# Chart 图表
|
||||
|
||||
**【预告】**: Chart 图表组件预计从 `@opentiny/vue@3.22.0` 版本中移除,后续从 `@opentiny/vue-huicharts` 单独引入。
|
||||
|
||||
Chart 图表组件基于 `hui-charts` 封装,集成自适应、性能提升、数据状态、无障碍能力、刻度优化等特性。
|
||||
<div>基于 hui-charts 封装,一个纯 Javascript 的图表库。</div>
|
||||
|
|
|
@ -4,6 +4,4 @@ title: Chart 图表
|
|||
|
||||
# Chart 图表
|
||||
|
||||
**【预告】**: Chart 图表组件预计从 `@opentiny/vue@3.22.0` 版本中移除,后续从 `@opentiny/vue-huicharts` 单独引入。
|
||||
|
||||
Chart 图表组件基于 `hui-charts` 封装,集成自适应、性能提升、数据状态、无障碍能力、刻度优化等特性。
|
||||
<div>基于 hui-charts 封装,一个纯 Javascript 的图表库。</div>
|
||||
|
|
|
@ -4,6 +4,4 @@ title: Chart 图表
|
|||
|
||||
# Chart 图表
|
||||
|
||||
**【预告】**: Chart 图表组件预计从 `@opentiny/vue@3.22.0` 版本中移除,后续从 `@opentiny/vue-huicharts` 单独引入。
|
||||
|
||||
Chart 图表组件基于 `hui-charts` 封装,集成自适应、性能提升、数据状态、无障碍能力、刻度优化等特性。
|
||||
<div>基于 hui-charts 封装,一个纯 Javascript 的图表库。</div>
|
||||
|
|
|
@ -4,6 +4,4 @@ title: Chart 图表
|
|||
|
||||
# Chart 图表
|
||||
|
||||
**【预告】**: Chart 图表组件预计从 `@opentiny/vue@3.22.0` 版本中移除,后续从 `@opentiny/vue-huicharts` 单独引入。
|
||||
|
||||
Chart 图表组件基于 `hui-charts` 封装,集成自适应、性能提升、数据状态、无障碍能力、刻度优化等特性。
|
||||
<div>基于 hui-charts 封装,一个纯 Javascript 的图表库。</div>
|
||||
|
|
|
@ -4,6 +4,4 @@ title: Chart 图表
|
|||
|
||||
# Chart 图表
|
||||
|
||||
**【预告】**: Chart 图表组件预计从 `@opentiny/vue@3.22.0` 版本中移除,后续从 `@opentiny/vue-huicharts` 单独引入。
|
||||
|
||||
Chart 图表组件基于 `hui-charts` 封装,集成自适应、性能提升、数据状态、无障碍能力、刻度优化等特性。
|
||||
<div>基于 hui-charts 封装,一个纯 Javascript 的图表库。</div>
|
||||
|
|
|
@ -4,6 +4,4 @@ title: Chart 图表
|
|||
|
||||
# Chart 图表
|
||||
|
||||
**【预告】**: Chart 图表组件预计从 `@opentiny/vue@3.22.0` 版本中移除,后续从 `@opentiny/vue-huicharts` 单独引入。
|
||||
|
||||
Chart 图表组件基于 `hui-charts` 封装,集成自适应、性能提升、数据状态、无障碍能力、刻度优化等特性。
|
||||
<div>基于 hui-charts 封装,一个纯 Javascript 的图表库。</div>
|
||||
|
|
|
@ -4,6 +4,4 @@ title: Chart 图表
|
|||
|
||||
# Chart 图表
|
||||
|
||||
**【预告】**: Chart 图表组件预计从 `@opentiny/vue@3.22.0` 版本中移除,后续从 `@opentiny/vue-huicharts` 单独引入。
|
||||
|
||||
Chart 图表组件基于 `hui-charts` 封装,集成自适应、性能提升、数据状态、无障碍能力、刻度优化等特性。
|
||||
<div>基于 hui-charts 封装,一个纯 Javascript 的图表库。</div>
|
||||
|
|
|
@ -4,6 +4,4 @@ title: Chart 图表
|
|||
|
||||
# Chart 图表
|
||||
|
||||
**【预告】**: Chart 图表组件预计从 `@opentiny/vue@3.22.0` 版本中移除,后续从 `@opentiny/vue-huicharts` 单独引入。
|
||||
|
||||
Chart 图表组件基于 `hui-charts` 封装,集成自适应、性能提升、数据状态、无障碍能力、刻度优化等特性。
|
||||
<div>基于 hui-charts 封装,一个纯 Javascript 的图表库。</div>
|
||||
|
|
|
@ -4,6 +4,4 @@ title: Chart 图表
|
|||
|
||||
# Chart 图表
|
||||
|
||||
**【预告】**: Chart 图表组件预计从 `@opentiny/vue@3.22.0` 版本中移除,后续从 `@opentiny/vue-huicharts` 单独引入。
|
||||
|
||||
Chart 图表组件基于 `hui-charts` 封装,集成自适应、性能提升、数据状态、无障碍能力、刻度优化等特性。
|
||||
<div>基于 hui-charts 封装,一个纯 Javascript 的图表库。</div>
|
||||
|
|
|
@ -4,6 +4,4 @@ title: Chart 图表
|
|||
|
||||
# Chart 图表
|
||||
|
||||
**【预告】**: Chart 图表组件预计从 `@opentiny/vue@3.22.0` 版本中移除,后续从 `@opentiny/vue-huicharts` 单独引入。
|
||||
|
||||
Chart 图表组件基于 `hui-charts` 封装,集成自适应、性能提升、数据状态、无障碍能力、刻度优化等特性。
|
||||
<div>基于 hui-charts 封装,一个纯 Javascript 的图表库。</div>
|
||||
|
|
|
@ -4,6 +4,4 @@ title: Chart 图表
|
|||
|
||||
# Chart 图表
|
||||
|
||||
**【预告】**: Chart 图表组件预计从 `@opentiny/vue@3.22.0` 版本中移除,后续从 `@opentiny/vue-huicharts` 单独引入。
|
||||
|
||||
Chart 图表组件基于 `hui-charts` 封装,集成自适应、性能提升、数据状态、无障碍能力、刻度优化等特性。
|
||||
<div>基于 hui-charts 封装,一个纯 Javascript 的图表库。</div>
|
||||
|
|
|
@ -4,6 +4,4 @@ title: Chart 图表
|
|||
|
||||
# Chart 图表
|
||||
|
||||
**【预告】**: Chart 图表组件预计从 `@opentiny/vue@3.22.0` 版本中移除,后续从 `@opentiny/vue-huicharts` 单独引入。
|
||||
|
||||
Chart 图表组件基于 `hui-charts` 封装,集成自适应、性能提升、数据状态、无障碍能力、刻度优化等特性。
|
||||
<div>基于 hui-charts 封装,一个纯 Javascript 的图表库。</div>
|
||||
|
|
|
@ -4,6 +4,4 @@ title: Chart 图表
|
|||
|
||||
# Chart 图表
|
||||
|
||||
**【预告】**: Chart 图表组件预计从 `@opentiny/vue@3.22.0` 版本中移除,后续从 `@opentiny/vue-huicharts` 单独引入。
|
||||
|
||||
Chart 图表组件基于 `hui-charts` 封装,集成自适应、性能提升、数据状态、无障碍能力、刻度优化等特性。
|
||||
<div>基于 hui-charts 封装,一个纯 Javascript 的图表库。</div>
|
||||
|
|
|
@ -4,6 +4,4 @@ title: Chart 图表
|
|||
|
||||
# Chart 图表
|
||||
|
||||
**【预告】**: Chart 图表组件预计从 `@opentiny/vue@3.22.0` 版本中移除,后续从 `@opentiny/vue-huicharts` 单独引入。
|
||||
|
||||
Chart 图表组件基于 `hui-charts` 封装,集成自适应、性能提升、数据状态、无障碍能力、刻度优化等特性。
|
||||
<div>基于 hui-charts 封装,一个纯 Javascript 的图表库。</div>
|
||||
|
|
|
@ -4,6 +4,4 @@ title: Chart 图表
|
|||
|
||||
# Chart 图表
|
||||
|
||||
**【预告】**: Chart 图表组件预计从 `@opentiny/vue@3.22.0` 版本中移除,后续从 `@opentiny/vue-huicharts` 单独引入。
|
||||
|
||||
Chart 图表组件基于 `hui-charts` 封装,集成自适应、性能提升、数据状态、无障碍能力、刻度优化等特性。
|
||||
<div>基于 hui-charts 封装,一个纯 Javascript 的图表库。</div>
|
||||
|
|
|
@ -4,6 +4,4 @@ title: Chart 图表
|
|||
|
||||
# Chart 图表
|
||||
|
||||
**【预告】**: Chart 图表组件预计从 `@opentiny/vue@3.22.0` 版本中移除,后续从 `@opentiny/vue-huicharts` 单独引入。
|
||||
|
||||
Chart 图表组件基于 `hui-charts` 封装,集成自适应、性能提升、数据状态、无障碍能力、刻度优化等特性。
|
||||
<div>基于 hui-charts 封装,一个纯 Javascript 的图表库。</div>
|
||||
|
|
|
@ -4,6 +4,4 @@ title: Chart 图表
|
|||
|
||||
# Chart 图表
|
||||
|
||||
**【预告】**: Chart 图表组件预计从 `@opentiny/vue@3.22.0` 版本中移除,后续从 `@opentiny/vue-huicharts` 单独引入。
|
||||
|
||||
Chart 图表组件基于 `hui-charts` 封装,集成自适应、性能提升、数据状态、无障碍能力、刻度优化等特性。
|
||||
<div>基于 hui-charts 封装,一个纯 Javascript 的图表库。</div>
|
||||
|
|
|
@ -4,6 +4,4 @@ title: Chart 图表
|
|||
|
||||
# Chart 图表
|
||||
|
||||
**【预告】**: Chart 图表组件预计从 `@opentiny/vue@3.22.0` 版本中移除,后续从 `@opentiny/vue-huicharts` 单独引入。
|
||||
|
||||
Chart 图表组件基于 `hui-charts` 封装,集成自适应、性能提升、数据状态、无障碍能力、刻度优化等特性。
|
||||
<div>基于 hui-charts 封装,一个纯 Javascript 的图表库。</div>
|
||||
|
|
|
@ -4,6 +4,4 @@ title: Chart 图表
|
|||
|
||||
# Chart 图表
|
||||
|
||||
**【预告】**: Chart 图表组件预计从 `@opentiny/vue@3.22.0` 版本中移除,后续从 `@opentiny/vue-huicharts` 单独引入。
|
||||
|
||||
Chart 图表组件基于 `hui-charts` 封装,集成自适应、性能提升、数据状态、无障碍能力、刻度优化等特性。
|
||||
<div>基于 hui-charts 封装,一个纯 Javascript 的图表库。</div>
|
||||
|
|
|
@ -4,6 +4,4 @@ title: Chart 图表
|
|||
|
||||
# Chart 图表
|
||||
|
||||
**【预告】**: Chart 图表组件预计从 `@opentiny/vue@3.22.0` 版本中移除,后续从 `@opentiny/vue-huicharts` 单独引入。
|
||||
|
||||
Chart 图表组件基于 `hui-charts` 封装,集成自适应、性能提升、数据状态、无障碍能力、刻度优化等特性。
|
||||
<div>基于 hui-charts 封装,一个纯 Javascript 的图表库。</div>
|
||||
|
|
|
@ -4,6 +4,4 @@ title: Chart 图表
|
|||
|
||||
# Chart 图表
|
||||
|
||||
**【预告】**: Chart 图表组件预计从 `@opentiny/vue@3.22.0` 版本中移除,后续从 `@opentiny/vue-huicharts` 单独引入。
|
||||
|
||||
Chart 图表组件基于 `hui-charts` 封装,集成自适应、性能提升、数据状态、无障碍能力、刻度优化等特性。
|
||||
<div>基于 hui-charts 封装,一个纯 Javascript 的图表库。</div>
|
||||
|
|
|
@ -4,6 +4,4 @@ title: Chart 图表
|
|||
|
||||
# Chart 图表
|
||||
|
||||
**【预告】**: Chart 图表组件预计从 `@opentiny/vue@3.22.0` 版本中移除,后续从 `@opentiny/vue-huicharts` 单独引入。
|
||||
|
||||
Chart 图表组件基于 `hui-charts` 封装,集成自适应、性能提升、数据状态、无障碍能力、刻度优化等特性。
|
||||
<div>基于 hui-charts 封装,一个纯 Javascript 的图表库。</div>
|
||||
|
|
|
@ -4,6 +4,4 @@ title: Chart 图表
|
|||
|
||||
# Chart 图表
|
||||
|
||||
**【预告】**: Chart 图表组件预计从 `@opentiny/vue@3.22.0` 版本中移除,后续从 `@opentiny/vue-huicharts` 单独引入。
|
||||
|
||||
Chart 图表组件基于 `hui-charts` 封装,集成自适应、性能提升、数据状态、无障碍能力、刻度优化等特性。
|
||||
<div>基于 hui-charts 封装,一个纯 Javascript 的图表库。</div>
|
||||
|
|
|
@ -4,6 +4,4 @@ title: Chart 图表
|
|||
|
||||
# Chart 图表
|
||||
|
||||
**【预告】**: Chart 图表组件预计从 `@opentiny/vue@3.22.0` 版本中移除,后续从 `@opentiny/vue-huicharts` 单独引入。
|
||||
|
||||
Chart 图表组件基于 `hui-charts` 封装,集成自适应、性能提升、数据状态、无障碍能力、刻度优化等特性。
|
||||
<div>基于 hui-charts 封装,一个纯 Javascript 的图表库。</div>
|
||||
|
|
|
@ -4,6 +4,4 @@ title: Chart 图表
|
|||
|
||||
# Chart 图表
|
||||
|
||||
**【预告】**: Chart 图表组件预计从 `@opentiny/vue@3.22.0` 版本中移除,后续从 `@opentiny/vue-huicharts` 单独引入。
|
||||
|
||||
Chart 图表组件基于 `hui-charts` 封装,集成自适应、性能提升、数据状态、无障碍能力、刻度优化等特性。
|
||||
<div>基于 hui-charts 封装,一个纯 Javascript 的图表库。</div>
|
||||
|
|
|
@ -4,6 +4,4 @@ title: Chart 图表
|
|||
|
||||
# Chart 图表
|
||||
|
||||
**【预告】**: Chart 图表组件预计从 `@opentiny/vue@3.22.0` 版本中移除,后续从 `@opentiny/vue-huicharts` 单独引入。
|
||||
|
||||
Chart 图表组件基于 `hui-charts` 封装,集成自适应、性能提升、数据状态、无障碍能力、刻度优化等特性。
|
||||
<div>基于 hui-charts 封装,一个纯 Javascript 的图表库。</div>
|
||||
|
|
|
@ -4,6 +4,4 @@ title: Chart 图表
|
|||
|
||||
# Chart 图表
|
||||
|
||||
**【预告】**: Chart 图表组件预计从 `@opentiny/vue@3.22.0` 版本中移除,后续从 `@opentiny/vue-huicharts` 单独引入。
|
||||
|
||||
Chart 图表组件基于 `hui-charts` 封装,集成自适应、性能提升、数据状态、无障碍能力、刻度优化等特性。
|
||||
<div>基于 hui-charts 封装,一个纯 Javascript 的图表库。</div>
|
||||
|
|
|
@ -4,6 +4,4 @@ title: Chart 图表
|
|||
|
||||
# Chart 图表
|
||||
|
||||
**【预告】**: Chart 图表组件预计从 `@opentiny/vue@3.22.0` 版本中移除,后续从 `@opentiny/vue-huicharts` 单独引入。
|
||||
|
||||
Chart 图表组件基于 `hui-charts` 封装,集成自适应、性能提升、数据状态、无障碍能力、刻度优化等特性。
|
||||
<div>基于 hui-charts 封装,一个纯 Javascript 的图表库。</div>
|
||||
|
|
|
@ -4,6 +4,4 @@ title: Chart 图表
|
|||
|
||||
# Chart 图表
|
||||
|
||||
**【预告】**: Chart 图表组件预计从 `@opentiny/vue@3.22.0` 版本中移除,后续从 `@opentiny/vue-huicharts` 单独引入。
|
||||
|
||||
Chart 图表组件基于 `hui-charts` 封装,集成自适应、性能提升、数据状态、无障碍能力、刻度优化等特性。
|
||||
<div>基于 hui-charts 封装,一个纯 Javascript 的图表库。</div>
|
||||
|
|
|
@ -4,6 +4,4 @@ title: Chart 图表
|
|||
|
||||
# Chart 图表
|
||||
|
||||
**【预告】**: Chart 图表组件预计从 `@opentiny/vue@3.22.0` 版本中移除,后续从 `@opentiny/vue-huicharts` 单独引入。
|
||||
|
||||
Chart 图表组件基于 `hui-charts` 封装,集成自适应、性能提升、数据状态、无障碍能力、刻度优化等特性。
|
||||
<div>基于 hui-charts 封装,一个纯 Javascript 的图表库。</div>
|
||||
|
|
|
@ -4,6 +4,4 @@ title: Chart 图表
|
|||
|
||||
# Chart 图表
|
||||
|
||||
**【预告】**: Chart 图表组件预计从 `@opentiny/vue@3.22.0` 版本中移除,后续从 `@opentiny/vue-huicharts` 单独引入。
|
||||
|
||||
Chart 图表组件基于 `hui-charts` 封装,集成自适应、性能提升、数据状态、无障碍能力、刻度优化等特性。
|
||||
<div>基于 hui-charts 封装,一个纯 Javascript 的图表库。</div>
|
||||
|
|
|
@ -4,6 +4,4 @@ title: Chart 图表
|
|||
|
||||
# Chart 图表
|
||||
|
||||
**【预告】**: Chart 图表组件预计从 `@opentiny/vue@3.22.0` 版本中移除,后续从 `@opentiny/vue-huicharts` 单独引入。
|
||||
|
||||
Chart 图表组件基于 `hui-charts` 封装,集成自适应、性能提升、数据状态、无障碍能力、刻度优化等特性。
|
||||
<div>基于 hui-charts 封装,一个纯 Javascript 的图表库。</div>
|
||||
|
|
|
@ -4,6 +4,4 @@ title: Chart 图表
|
|||
|
||||
# Chart 图表
|
||||
|
||||
**【预告】**: Chart 图表组件预计从 `@opentiny/vue@3.22.0` 版本中移除,后续从 `@opentiny/vue-huicharts` 单独引入。
|
||||
|
||||
Chart 图表组件基于 `hui-charts` 封装,集成自适应、性能提升、数据状态、无障碍能力、刻度优化等特性。
|
||||
<div>基于 hui-charts 封装,一个纯 Javascript 的图表库。</div>
|
||||
|
|
|
@ -4,6 +4,4 @@ title: Chart 图表
|
|||
|
||||
# Chart 图表
|
||||
|
||||
**【预告】**: Chart 图表组件预计从 `@opentiny/vue@3.22.0` 版本中移除,后续从 `@opentiny/vue-huicharts` 单独引入。
|
||||
|
||||
Chart 图表组件基于 `hui-charts` 封装,集成自适应、性能提升、数据状态、无障碍能力、刻度优化等特性。
|
||||
<div>基于 hui-charts 封装,一个纯 Javascript 的图表库。</div>
|
||||
|
|
|
@ -4,6 +4,4 @@ title: Chart 图表
|
|||
|
||||
# Chart 图表
|
||||
|
||||
**【预告】**: Chart 图表组件预计从 `@opentiny/vue@3.22.0` 版本中移除,后续从 `@opentiny/vue-huicharts` 单独引入。
|
||||
|
||||
Chart 图表组件基于 `hui-charts` 封装,集成自适应、性能提升、数据状态、无障碍能力、刻度优化等特性。
|
||||
<div>基于 hui-charts 封装,一个纯 Javascript 的图表库。</div>
|
||||
|
|
|
@ -80,15 +80,9 @@
|
|||
"type": "component",
|
||||
"exclude": false,
|
||||
"mode": [
|
||||
"mobile-first",
|
||||
"pc"
|
||||
]
|
||||
},
|
||||
"AnchorMobileFirst": {
|
||||
"path": "vue/src/anchor/src/mobile-first.vue",
|
||||
"type": "template",
|
||||
"exclude": false
|
||||
},
|
||||
"AnchorPc": {
|
||||
"path": "vue/src/anchor/src/pc.vue",
|
||||
"type": "template",
|
||||
|
@ -1470,11 +1464,6 @@
|
|||
"type": "template",
|
||||
"exclude": false
|
||||
},
|
||||
"Hooks": {
|
||||
"path": "vue-hooks/index.ts",
|
||||
"type": "module",
|
||||
"exclude": false
|
||||
},
|
||||
"Hrapprover": {
|
||||
"path": "vue/src/hrapprover/index.ts",
|
||||
"type": "component",
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"name": "@opentiny/vue-huicharts-amap",
|
||||
"name": "@opentiny/vue-autonavi-map",
|
||||
"version": "3.18.0",
|
||||
"description": "",
|
||||
"main": "lib/index.js",
|
||||
|
@ -15,7 +15,7 @@
|
|||
"//postversion": "pnpm build"
|
||||
},
|
||||
"dependencies": {
|
||||
"@opentiny/vue-huicharts-core": "workspace:~",
|
||||
"@opentiny/vue-chart-core": "workspace:~",
|
||||
"@opentiny/vue-common": "workspace:~"
|
||||
},
|
||||
"license": "MIT"
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
import Core from '@opentiny/vue-huicharts-core'
|
||||
import Core from '@opentiny/vue-chart-core'
|
||||
|
||||
import registerAmap from './amap'
|
||||
import { $prefix } from '@opentiny/vue-common'
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"name": "@opentiny/vue-huicharts-bmap",
|
||||
"name": "@opentiny/vue-baidu-map",
|
||||
"version": "3.18.0",
|
||||
"description": "",
|
||||
"main": "lib/index.js",
|
||||
|
@ -15,7 +15,7 @@
|
|||
"//postversion": "pnpm build"
|
||||
},
|
||||
"dependencies": {
|
||||
"@opentiny/vue-huicharts-core": "workspace:~",
|
||||
"@opentiny/vue-chart-core": "workspace:~",
|
||||
"@opentiny/vue-common": "workspace:~"
|
||||
},
|
||||
"license": "MIT"
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
<script>
|
||||
import 'echarts/extension/bmap/bmap'
|
||||
import Core from '@opentiny/vue-huicharts-core'
|
||||
import Core from '@opentiny/vue-chart-core'
|
||||
import { $prefix } from '@opentiny/vue-common'
|
||||
|
||||
export default {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"name": "@opentiny/vue-huicharts-bar",
|
||||
"name": "@opentiny/vue-chart-bar",
|
||||
"version": "3.18.0",
|
||||
"description": "",
|
||||
"main": "lib/index.js",
|
||||
|
@ -12,7 +12,7 @@
|
|||
"//postversion": "pnpm build"
|
||||
},
|
||||
"dependencies": {
|
||||
"@opentiny/vue-huicharts-core": "workspace:~",
|
||||
"@opentiny/vue-chart-core": "workspace:~",
|
||||
"@opentiny/vue-common": "workspace:~"
|
||||
},
|
||||
"license": "MIT"
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
<script>
|
||||
import { histogram } from './histogram'
|
||||
import Core from '@opentiny/vue-huicharts-core'
|
||||
import Core from '@opentiny/vue-chart-core'
|
||||
import { $prefix } from '@opentiny/vue-common'
|
||||
|
||||
export default {
|
||||
|
|
|
@ -1,13 +1,4 @@
|
|||
import {
|
||||
getFormatted,
|
||||
cloneDeep,
|
||||
getStackMap,
|
||||
get,
|
||||
set,
|
||||
isNull,
|
||||
getRows,
|
||||
getTooltip
|
||||
} from '@opentiny/vue-huicharts-core'
|
||||
import { getFormatted, cloneDeep, getStackMap, get, set, isNull, getRows, getTooltip } from '@opentiny/vue-chart-core'
|
||||
|
||||
const VALUE_AXIS_OPACITY = 0.5
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"name": "@opentiny/vue-huicharts-boxplot",
|
||||
"name": "@opentiny/vue-chart-boxplot",
|
||||
"version": "3.18.0",
|
||||
"description": "",
|
||||
"main": "lib/index.js",
|
||||
|
@ -12,7 +12,7 @@
|
|||
"//postversion": "pnpm build"
|
||||
},
|
||||
"dependencies": {
|
||||
"@opentiny/vue-huicharts-core": "workspace:~",
|
||||
"@opentiny/vue-chart-core": "workspace:~",
|
||||
"@opentiny/vue-common": "workspace:~"
|
||||
},
|
||||
"license": "MIT"
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { getFormatted, itemPoint, itemLabel, itemContent, htmlHandler } from '@opentiny/vue-huicharts-core'
|
||||
import { getFormatted, itemPoint, itemLabel, itemContent, htmlHandler } from '@opentiny/vue-chart-core'
|
||||
|
||||
const getXAxis = (args) => {
|
||||
const { columns, xAxisName, axisVisible, xAxisType } = args
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
import Core from '@opentiny/vue-huicharts-core'
|
||||
import Core from '@opentiny/vue-chart-core'
|
||||
import { prepareBoxplotData } from 'echarts/extension/dataTool'
|
||||
import { boxplot } from './boxplot'
|
||||
import { $prefix } from '@opentiny/vue-common'
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"name": "@opentiny/vue-huicharts-candle",
|
||||
"name": "@opentiny/vue-chart-candle",
|
||||
"version": "3.18.0",
|
||||
"description": "",
|
||||
"main": "lib/index.js",
|
||||
|
@ -12,7 +12,7 @@
|
|||
"//postversion": "pnpm build"
|
||||
},
|
||||
"dependencies": {
|
||||
"@opentiny/vue-huicharts-core": "workspace:~",
|
||||
"@opentiny/vue-chart-core": "workspace:~",
|
||||
"@opentiny/vue-locale": "workspace:~",
|
||||
"@opentiny/vue-common": "workspace:~"
|
||||
},
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
* dataType 数据展示格式 string 可选值: KMB, normal, percent
|
||||
*/
|
||||
|
||||
import { getFormatted, itemPoint, itemLabel, itemContent } from '@opentiny/vue-huicharts-core'
|
||||
import { getFormatted, itemPoint, itemLabel, itemContent } from '@opentiny/vue-chart-core'
|
||||
|
||||
const isNull = (x) => x === null || x === undefined
|
||||
let defaultKName = ''
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
import Core from '@opentiny/vue-huicharts-core'
|
||||
import Core from '@opentiny/vue-chart-core'
|
||||
import { t } from '@opentiny/vue-locale'
|
||||
import { candle } from './candle'
|
||||
import { $prefix } from '@opentiny/vue-common'
|
||||
|
|
|
@ -0,0 +1,63 @@
|
|||
/* eslint-disable new-cap */
|
||||
/* eslint-disable no-unused-expressions */
|
||||
import core from './core'
|
||||
import Register from './register'
|
||||
import Theme from './feature/token'
|
||||
import { isFunction } from './util/type'
|
||||
import axistip from './feature/axistip'
|
||||
import { mergeExtend } from './util/merge'
|
||||
import readScreen from './feature/readScreen'
|
||||
import mediaScreen from './feature/mediaScreen'
|
||||
|
||||
// 图表核心对象,通过 Register 全量引入图表给 HuiCharts 渲染,打包容量较大
|
||||
export default class HuiCharts extends core {
|
||||
constructor() {
|
||||
super()
|
||||
// 图表名称
|
||||
this.chartName
|
||||
}
|
||||
|
||||
// 传入简化后的icharts-option
|
||||
setSimpleOption(chartName, iChartOption, plugins = {}, isInit = true) {
|
||||
if (isInit) {
|
||||
Theme.setDefaultTheme(iChartOption.theme)
|
||||
this.mediaScreenObserver && this.mediaScreenObserver.setInitOption(iChartOption)
|
||||
}
|
||||
if (iChartOption.readScreen) {
|
||||
readScreen(this.dom, iChartOption.readScreen)
|
||||
}
|
||||
if (isFunction(chartName)) {
|
||||
this.redirectSelfChart(chartName, iChartOption, plugins)
|
||||
return
|
||||
}
|
||||
this.plugins = plugins
|
||||
this.chartName = chartName
|
||||
this.iChartOption = iChartOption
|
||||
const ChartClass = this.getChartClass(chartName)
|
||||
this.ichartsIns = new ChartClass(iChartOption, this.echartsIns, this.plugins)
|
||||
this.eChartOption = this.ichartsIns.getOption()
|
||||
this.iChartOption.axistip && axistip(this.dom, this.echartsIns, this.eChartOption)
|
||||
mergeExtend(this.iChartOption, this.eChartOption)
|
||||
}
|
||||
|
||||
// 获取图表类
|
||||
getChartClass(name) {
|
||||
return Register.getRegisteredComp(name)
|
||||
}
|
||||
|
||||
// 开启响应式布局(类媒体查询效果)
|
||||
mediaScreen(dom, screenOption) {
|
||||
this.mediaScreenObserver = new mediaScreen(dom, screenOption, (option) => {
|
||||
this.setSimpleOption(this.chartName, option, this.plugins, false)
|
||||
this.render()
|
||||
})
|
||||
}
|
||||
|
||||
// 图表刷新,包括刷新配置和数据
|
||||
refresh(iChartOption) {
|
||||
this.iChartOption = iChartOption
|
||||
this.setSimpleOption(this.chartName, iChartOption, this.plugins)
|
||||
this.render()
|
||||
this.mediaScreenObserver && this.mediaScreenObserver.refresh()
|
||||
}
|
||||
}
|
|
@ -0,0 +1,147 @@
|
|||
import BaseChart from '../BaseChart'
|
||||
import * as echarts from 'echarts/lib/echarts'
|
||||
|
||||
// 常规的调用方法
|
||||
// integrateChart.init(chartRef.current);
|
||||
// integrateChart.setSimpleOption(AutonaviMapChart, option, {});
|
||||
// integrateChart.render();
|
||||
let amapPromise = null
|
||||
|
||||
export default class AutonaviMapChart extends BaseChart {
|
||||
constructor() {
|
||||
super()
|
||||
// 图表echarts实例
|
||||
this.echartsIns = null
|
||||
// 图表icharts实例
|
||||
this.ichartsIns = null
|
||||
|
||||
// 图表echarts配置项
|
||||
this.eChartOption = null
|
||||
// 图表icharts配置项
|
||||
this.iChartOption = null
|
||||
|
||||
// 图表渲染容器
|
||||
this.dom = null
|
||||
// 图表配置项
|
||||
this.option = null
|
||||
}
|
||||
|
||||
getAmap(option) {
|
||||
if (!amapPromise) {
|
||||
const key = option.key
|
||||
const url = option.url
|
||||
const version = option.version || option.ver || option.v
|
||||
amapPromise = new Promise((resolve) => {
|
||||
const cbName = 'amap' + Date.now()
|
||||
let script = document.createElement('script')
|
||||
window[cbName] = resolve
|
||||
let src = `${url}?v=${version}&key=${key}`
|
||||
if (option.plugin) {
|
||||
src += `&plugin=${option.plugin}`
|
||||
}
|
||||
script.src = `${src}&callback=${cbName}`
|
||||
script.onload = () => resolve()
|
||||
document.body.appendChild(script)
|
||||
})
|
||||
}
|
||||
return amapPromise
|
||||
}
|
||||
|
||||
// 初始化图表渲染容器
|
||||
init(dom) {
|
||||
this.uninstall()
|
||||
this.dom = dom
|
||||
this.echartsIns = echarts.init(this.dom)
|
||||
}
|
||||
|
||||
// 初始化图表渲染配置
|
||||
setSimpleOption(chartName, option) {
|
||||
this.option = option
|
||||
this.getAmap(this.option).then(() => {
|
||||
this.echartsIns.setOption(this.option)
|
||||
this.setResizeObserver()
|
||||
})
|
||||
}
|
||||
|
||||
// 图表渲染回调
|
||||
render() {
|
||||
this.initDom() // 渲染dom
|
||||
this.renderCallBack && this.renderCallBack(this)
|
||||
}
|
||||
|
||||
// 图表渲染完成时回调
|
||||
onRenderReady(callback) {
|
||||
this.renderCallBack = callback
|
||||
}
|
||||
|
||||
// 渲染dom
|
||||
initDom() {}
|
||||
|
||||
// 监听容器变化
|
||||
setResizeObserver() {
|
||||
if (this.resizeObserver) {
|
||||
this.resizeObserver.disconnect()
|
||||
this.resizeObserver = null
|
||||
}
|
||||
this.resizeObserver = new ResizeObserver((entries) => {
|
||||
this.resizeDom()
|
||||
})
|
||||
this.resizeObserver.observe(this.dom)
|
||||
}
|
||||
|
||||
resizeDom() {
|
||||
this.echartsIns && this.echartsIns.resize && this.echartsIns.resize()
|
||||
}
|
||||
|
||||
// 图表刷新,刷新配置项
|
||||
refresh(option) {
|
||||
this.iChartOption = option
|
||||
this.setSimpleOption('AutonaviMapChart', this.iChartOption)
|
||||
this.resizeDom()
|
||||
}
|
||||
|
||||
// 图表刷新,仅刷新数据
|
||||
refreshData(data) {
|
||||
this.iChartOption.series[0].data = data
|
||||
this.refresh(this.iChartOption)
|
||||
}
|
||||
|
||||
// 刷新图表自适应宽度
|
||||
setResize() {
|
||||
this.resizeDom()
|
||||
}
|
||||
|
||||
// 销毁图表
|
||||
uninstall() {
|
||||
if (this.resizeObserver) {
|
||||
this.resizeObserver.disconnect()
|
||||
this.resizeObserver = null
|
||||
}
|
||||
// 销毁ECharts实例
|
||||
if (this.echartsIns && !this.echartsIns.isDisposed()) {
|
||||
this.echartsIns.dispose()
|
||||
}
|
||||
this.echartsIns = null
|
||||
this.dom = null
|
||||
}
|
||||
|
||||
// 获取到ECharts实例
|
||||
getEchartsInstance() {
|
||||
return this.echartsIns
|
||||
}
|
||||
|
||||
// 获取到ECharts配置项
|
||||
getEchartsOption() {
|
||||
return this.echartsIns.getOption()
|
||||
}
|
||||
|
||||
// 获取 ECharts 高德地图组件
|
||||
getAmapComponent() {
|
||||
return this.echartsIns.getModel().getComponent('amap')
|
||||
}
|
||||
|
||||
// 获取高德地图实例
|
||||
getAmapInstance() {
|
||||
return this.getAmapComponent().getAMap()
|
||||
}
|
||||
}
|
|
@ -0,0 +1,138 @@
|
|||
import BaseChart from '../BaseChart'
|
||||
import * as echarts from 'echarts'
|
||||
import 'echarts/extension/bmap/bmap'
|
||||
|
||||
export default class BaiduMapChart extends BaseChart {
|
||||
constructor() {
|
||||
super()
|
||||
// 图表echarts实例
|
||||
this.echartsIns = null
|
||||
// 图表渲染容器
|
||||
this.dom = null
|
||||
// 图表配置项
|
||||
this.option = null
|
||||
// 图表所需数据
|
||||
this.data = null
|
||||
// 图表容器的宽高变化监听器
|
||||
this.resizeObserver = null
|
||||
}
|
||||
|
||||
// 初始化图表渲染容器
|
||||
init(dom) {
|
||||
this.uninstall()
|
||||
this.dom = dom
|
||||
}
|
||||
|
||||
// 初始化图表渲染配置
|
||||
setSimpleOption(chartName, option) {
|
||||
this.option = option
|
||||
}
|
||||
|
||||
// 判断某个script是否存在
|
||||
isScriptExist(src) {
|
||||
let scripts = document.getElementsByTagName('script')
|
||||
for (let i = 0; i < scripts.length; i++) {
|
||||
if (scripts[i].src && scripts[i].src === src) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
loadMap({ key, version, url }) {
|
||||
return new Promise((resolve) => {
|
||||
let cbName = 'bmap' + Date.now()
|
||||
let script = document.createElement('script')
|
||||
let ver = version || '2.0'
|
||||
|
||||
window[cbName] = resolve
|
||||
script.src = [`${url}?v=${ver}`, `ak=${key}`, `callback=${cbName}`].join('&')
|
||||
document.body.appendChild(script)
|
||||
})
|
||||
}
|
||||
|
||||
// 加载百度api,并渲染图表
|
||||
render() {
|
||||
let url = this.option.url
|
||||
let ver = this.option.v || '2.0'
|
||||
let key = this.option.key
|
||||
let src = [`${url}?${ver}`, `ak=${key}`].join('&')
|
||||
let bmap = this.option.bmap
|
||||
let scriptExists = this.isScriptExist(src)
|
||||
// 判断是否重复加载script
|
||||
if (scriptExists) {
|
||||
this.renderInit()
|
||||
} else {
|
||||
this.loadMap({ key, version: ver, url }).then(() => {
|
||||
this.renderInit()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// 渲染图表
|
||||
renderInit() {
|
||||
this.echartsIns = echarts.init(this.dom)
|
||||
// 渲染
|
||||
this.setOption(this.option)
|
||||
this.setResizeObserver()
|
||||
// 图表渲染完成时回调
|
||||
this.renderCallBack && this.renderCallBack(this.echartsIns)
|
||||
}
|
||||
|
||||
// 第一次渲染: 调用echarts原生的setOption
|
||||
setOption(option) {
|
||||
this.echartsIns.setOption(option)
|
||||
}
|
||||
|
||||
// 图表渲染完成时回调
|
||||
onRenderReady(callback) {
|
||||
this.renderCallBack = callback
|
||||
}
|
||||
|
||||
// 监听容器变化
|
||||
setResizeObserver() {
|
||||
this.resizeObserver = new ResizeObserver((entries) => {
|
||||
this.resizeDom()
|
||||
})
|
||||
this.resizeObserver.observe(this.dom)
|
||||
}
|
||||
|
||||
resizeDom() {
|
||||
this.echartsIns && this.echartsIns.resize && this.echartsIns.resize()
|
||||
}
|
||||
|
||||
// 图表刷新,包括刷新配置和数据
|
||||
refresh(iChartOption) {
|
||||
this.iChartOption = iChartOption
|
||||
this.setSimpleOption(this.chartName, iChartOption)
|
||||
this.render()
|
||||
}
|
||||
|
||||
// 图表刷新,仅刷新数据
|
||||
refreshData(data) {
|
||||
this.iChartOption.series[0].data = data
|
||||
this.refresh(this.iChartOption)
|
||||
}
|
||||
|
||||
// 刷新图表自适应宽度
|
||||
setResize() {
|
||||
this.resizeDom()
|
||||
}
|
||||
|
||||
// 销毁图表
|
||||
uninstall() {
|
||||
// 卸载window resize监听功能
|
||||
window.removeEventListener('resize', this.throttleResize)
|
||||
// 卸载container容器变化监听
|
||||
if (this.resizeObserver) {
|
||||
this.resizeObserver.disconnect()
|
||||
this.resizeObserver = null
|
||||
}
|
||||
// 销毁ECharts实例
|
||||
if (this.echartsIns && !this.echartsIns.isDisposed()) {
|
||||
this.echartsIns.dispose()
|
||||
}
|
||||
this.echartsIns = null
|
||||
this.dom = null
|
||||
}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
import Theme from '../../feature/token'
|
||||
import proxy from '../../util/proxy'
|
||||
|
||||
function getChartToken() {
|
||||
const {
|
||||
itemStyle: { borderWidth, borderColor, borderRadius, color },
|
||||
label: { color: colorLabel, fontSize },
|
||||
barWidth
|
||||
} = Theme.config.BarChart
|
||||
|
||||
const {
|
||||
colorState: { colorError }
|
||||
} = Theme.config
|
||||
|
||||
return {
|
||||
borderWidth,
|
||||
borderColor,
|
||||
borderRadius,
|
||||
color,
|
||||
labelColor: colorLabel,
|
||||
fontSize,
|
||||
barWidth,
|
||||
colorError
|
||||
}
|
||||
}
|
||||
|
||||
const chartToken = proxy(getChartToken)
|
||||
|
||||
export default chartToken
|
|
@ -0,0 +1,84 @@
|
|||
import defendXSS from '../../util/defendXSS'
|
||||
import chartToken from './chartToken'
|
||||
|
||||
/**
|
||||
* 给堆叠图的柱子中间加上空白缝隙, 处理柱子圆角的递进关系
|
||||
*/
|
||||
export function setStack(baseOption, iChartOption, legendData, seriesData) {
|
||||
const type = iChartOption.type
|
||||
if (type && type === 'stack') {
|
||||
// 添加堆叠图空白缝隙
|
||||
baseOption.series.forEach((item) => {
|
||||
item.itemStyle.borderWidth = chartToken.borderWidth
|
||||
item.itemStyle.borderColor = chartToken.borderColor
|
||||
})
|
||||
// 柱子圆角,上层数值为空时,圆角递进到下层
|
||||
const direction = iChartOption.direction
|
||||
iChartOption.data.forEach((item, i) => {
|
||||
for (let j = legendData.length - 1; j >= 0; j--) {
|
||||
const name = legendData[j]
|
||||
if (item[name]) {
|
||||
seriesData[name][i] = {
|
||||
value: seriesData[name][i],
|
||||
itemStyle: {
|
||||
borderRadius:
|
||||
direction === 'horizontal'
|
||||
? [0, chartToken.borderRadius, chartToken.borderRadius, 0]
|
||||
: [chartToken.borderRadius, chartToken.borderRadius, 0, 0]
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 将所有y轴的label都转为正数
|
||||
* 内置好转为正数的tooltip
|
||||
*/
|
||||
export function setDoubleSides(baseOption, iChartOption) {
|
||||
const type = iChartOption.type
|
||||
if (type && type === 'double-sides') {
|
||||
const yAxis = baseOption.yAxis
|
||||
yAxis.forEach((item) => {
|
||||
item.axisLabel.formatter = (value) => {
|
||||
return Math.abs(value)
|
||||
}
|
||||
})
|
||||
if (!baseOption.tooltip.formatter) {
|
||||
baseOption.tooltip.formatter = (params, ticket, callback) => {
|
||||
let html = ''
|
||||
params.forEach((item, index) => {
|
||||
if (index === 0) {
|
||||
html += `<div style="margin-bottom:4px;">${defendXSS(item.name)}</div>`
|
||||
}
|
||||
html += `<div>
|
||||
<span style="display:inline-block;width:10px;height:10px;border-radius:5px;background-color:${defendXSS(
|
||||
item.color
|
||||
)};"></span>
|
||||
<span style="margin-left:5px;color:#000000">
|
||||
<span style="display:inline-block; margin-right:8px;min-width:48px;">${defendXSS(
|
||||
item.seriesName
|
||||
)}</span>
|
||||
<span style="font-weight:bold">${defendXSS(item.value ? Math.abs(item.value) : '-')}</span>
|
||||
</span>
|
||||
</div>`
|
||||
})
|
||||
return html
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置柱状图的方向
|
||||
*/
|
||||
export function setDirection(baseOption, direction) {
|
||||
if (direction && direction === 'horizontal') {
|
||||
const temp = baseOption.xAxis
|
||||
baseOption.xAxis = baseOption.yAxis
|
||||
baseOption.yAxis = temp
|
||||
}
|
||||
}
|
|
@ -0,0 +1,619 @@
|
|||
import merge from '../../util/merge'
|
||||
import defendXSS from '../../util/defendXSS'
|
||||
import { getColor } from '../../util/color'
|
||||
import cloneDeep from '../../util/cloneDeep'
|
||||
import { isArray, isNumber } from '../../util/type'
|
||||
import { getMarkLineDefault } from '../../option/config/mark'
|
||||
import chartToken from './chartToken'
|
||||
|
||||
export const seriesInit = () => {
|
||||
return {
|
||||
label: {
|
||||
show: false,
|
||||
color: chartToken.labelColor,
|
||||
fontSize: chartToken.fontSize
|
||||
},
|
||||
// 数据
|
||||
data: [],
|
||||
// 柱形
|
||||
type: 'bar',
|
||||
// 柱条宽度
|
||||
barWidth: chartToken.barWidth,
|
||||
// 柱间距离
|
||||
barGap: '60%',
|
||||
// 阈值线
|
||||
markLine: null,
|
||||
// 峰值标志
|
||||
markPoint: null,
|
||||
// 柱形的每个样式配置项
|
||||
itemStyle: {
|
||||
borderRadius: [chartToken.borderRadius, chartToken.borderRadius, 0, 0]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function handleWaterFall(type, seriesUnit) {
|
||||
if (type && type === 'water-fall') {
|
||||
// 调整堆叠柱子圆角
|
||||
seriesUnit.itemStyle.borderRadius = [
|
||||
chartToken.borderRadius,
|
||||
chartToken.borderRadius,
|
||||
chartToken.borderRadius,
|
||||
chartToken.borderRadius
|
||||
]
|
||||
// 瀑布图最有有一个总体数据
|
||||
seriesUnit.data.push(
|
||||
seriesUnit.data.reduce(function (prev, curr) {
|
||||
const n = Number(curr) || 0
|
||||
return prev + n
|
||||
}, 0)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
function handleRange(type, seriesUnit) {
|
||||
if (type && type === 'range') {
|
||||
// 调整堆叠柱子圆角
|
||||
seriesUnit.itemStyle.borderRadius = [
|
||||
chartToken.borderRadius,
|
||||
chartToken.borderRadius,
|
||||
chartToken.borderRadius,
|
||||
chartToken.borderRadius
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 组装echarts所需要的series
|
||||
* @param {图表数据} seriesData
|
||||
* @param {图例数据} legendData
|
||||
* @param {是否面积图} isArea
|
||||
* @param {是否曲线} isSmooth
|
||||
* @param {是否阶梯线} isStep
|
||||
* @param {阈值线} markLine
|
||||
* @param {阈值箭头} markPoint
|
||||
* @param {颜色集合} colors
|
||||
* @returns
|
||||
*/
|
||||
export function setSeries(seriesData, legendData, iChartOption) {
|
||||
// 柱状图类型
|
||||
const type = iChartOption.type
|
||||
// 柱状图方向
|
||||
const direction = iChartOption.direction
|
||||
// 覆盖用户传入的itemStyle
|
||||
const seriesInit_ = handleItemStyle(direction, iChartOption.itemStyle)
|
||||
// 拼装series
|
||||
const series = []
|
||||
legendData.forEach((legend, index) => {
|
||||
const seriesUnit = cloneDeep(seriesInit_)
|
||||
// 数值显示
|
||||
handleLabel(seriesUnit, iChartOption, index)
|
||||
// 聚焦效果
|
||||
handleFocus(seriesUnit, iChartOption)
|
||||
// 数据 / 数据名称
|
||||
seriesUnit.name = legend
|
||||
// 如果设置了 barMinHeight,那么就把数据里面的0设置成null
|
||||
if (iChartOption.itemStyle && iChartOption.itemStyle.barMinHeight) {
|
||||
seriesUnit.data = seriesData[legend].map((item) => {
|
||||
return item === 0 ? undefined : item
|
||||
})
|
||||
} else {
|
||||
seriesUnit.data = seriesData[legend]
|
||||
}
|
||||
// 阈值线
|
||||
handleMarkLine(seriesUnit, iChartOption, direction)
|
||||
// 堆叠图
|
||||
handleStack(type, seriesUnit, index, legendData, iChartOption)
|
||||
// 双向图
|
||||
handleBothSides(type, seriesUnit, direction, index, legendData)
|
||||
// 数据均为正数的双向图
|
||||
handleDoubleSides(type, seriesUnit, index, legendData)
|
||||
// 瀑布图
|
||||
handleWaterFall(type, seriesUnit)
|
||||
// 区间图
|
||||
handleRange(type, seriesUnit)
|
||||
// 包含图
|
||||
handleContain(type, seriesUnit)
|
||||
series.push(seriesUnit)
|
||||
})
|
||||
// 配置多个series的y轴index
|
||||
handleYaxis(series, iChartOption.yAxis)
|
||||
return series
|
||||
}
|
||||
|
||||
function handleItemStyle(direction, itemStyle) {
|
||||
const seriesInit_ = cloneDeep(seriesInit())
|
||||
if (direction && direction === 'horizontal') {
|
||||
seriesInit_.itemStyle.borderRadius = [0, chartToken.borderRadius, chartToken.borderRadius, 0]
|
||||
}
|
||||
if (itemStyle?.barMinHeight) {
|
||||
seriesInit_.barMinHeight = itemStyle.barMinHeight
|
||||
}
|
||||
if (itemStyle?.barWidth) {
|
||||
seriesInit_.barWidth = itemStyle.barWidth
|
||||
}
|
||||
if (itemStyle?.barGap) {
|
||||
seriesInit_.barGap = itemStyle.barGap
|
||||
}
|
||||
if (itemStyle?.color) {
|
||||
seriesInit_.itemStyle.color = itemStyle.color
|
||||
}
|
||||
merge(seriesInit_.itemStyle, itemStyle)
|
||||
return seriesInit_
|
||||
}
|
||||
|
||||
function handleLabel(seriesUnit, iChartOption, index) {
|
||||
const label = iChartOption.label
|
||||
let labelOption
|
||||
if (label && isArray(label)) {
|
||||
labelOption = label[index]
|
||||
} else {
|
||||
labelOption = label
|
||||
}
|
||||
if (labelOption && labelOption.show) {
|
||||
merge(seriesUnit.label, labelOption)
|
||||
seriesUnit.label.show = true
|
||||
seriesUnit.label.offset = labelOption.offset || [0, 0]
|
||||
seriesUnit.label.position = labelOption.position || 'inside'
|
||||
seriesUnit.label.formatter = labelOption.formatter
|
||||
}
|
||||
}
|
||||
|
||||
function handleMarkLine(seriesUnit, iChartOption, direction) {
|
||||
const name = seriesUnit.name
|
||||
const markLine = iChartOption.markLine
|
||||
const isTopMarkLine = markLine && markLine.top && !(markLine.topUse && !markLine.topUse.includes(name))
|
||||
const isBottomMarkLine = markLine && markLine.bottom && !(markLine.bottomUse && !markLine.bottomUse.includes(name))
|
||||
if (isTopMarkLine || isBottomMarkLine) {
|
||||
seriesUnit.markLine = cloneDeep(getMarkLineDefault())
|
||||
merge(seriesUnit.markLine, markLine)
|
||||
seriesUnit.markLine.lineStyle.color = markLine.color || chartToken.colorError
|
||||
}
|
||||
if (isTopMarkLine) {
|
||||
if (direction && direction === 'horizontal') {
|
||||
seriesUnit.markLine.data.push({ xAxis: markLine.top })
|
||||
} else {
|
||||
seriesUnit.markLine.data.push({ yAxis: markLine.top })
|
||||
}
|
||||
}
|
||||
if (isBottomMarkLine) {
|
||||
if (direction && direction === 'horizontal') {
|
||||
seriesUnit.markLine.data.push({ xAxis: markLine.bottom })
|
||||
} else {
|
||||
seriesUnit.markLine.data.push({ yAxis: markLine.bottom })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function handleFocus(seriesUnit, iChartOption) {
|
||||
if (iChartOption.focus) {
|
||||
seriesUnit.emphasis = {
|
||||
focus: 'series',
|
||||
blurScope: 'global'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function handleStack(type, seriesUnit, index, legendData, iChartOption) {
|
||||
if (type && type === 'stack') {
|
||||
const stack = iChartOption.stack
|
||||
if (stack) {
|
||||
for (const name in stack) {
|
||||
if (Object.hasOwnProperty.call(stack, name)) {
|
||||
const stackArray = stack[name]
|
||||
const seriesName = seriesUnit.name
|
||||
const stackIndex = stackArray.indexOf(seriesName)
|
||||
if (stackIndex !== -1) {
|
||||
seriesUnit.stack = name
|
||||
if (stackIndex + 1 < stackArray.length) {
|
||||
delete seriesUnit.itemStyle.borderRadius
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
} else {
|
||||
seriesUnit.stack = 'stack'
|
||||
if (index !== legendData.length - 1) {
|
||||
delete seriesUnit.itemStyle.borderRadius
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function handleBothSides(type, seriesUnit, direction, index, legendData) {
|
||||
if (type && (type === 'both-sides' || type === 'double-sides')) {
|
||||
seriesUnit.stack = 'stack'
|
||||
// 调整堆叠柱子圆角
|
||||
if (direction && direction === 'horizontal') {
|
||||
if (index === 0) {
|
||||
seriesUnit.itemStyle.borderRadius = [0, chartToken.borderRadius, chartToken.borderRadius, 0]
|
||||
}
|
||||
if (index === legendData.length - 1) {
|
||||
seriesUnit.itemStyle.borderRadius = [chartToken.borderRadius, 0, 0, chartToken.borderRadius]
|
||||
}
|
||||
} else {
|
||||
if (index === 0) {
|
||||
seriesUnit.itemStyle.borderRadius = [chartToken.borderRadius, chartToken.borderRadius, 0, 0]
|
||||
}
|
||||
if (index === legendData.length - 1) {
|
||||
seriesUnit.itemStyle.borderRadius = [0, 0, chartToken.borderRadius, chartToken.borderRadius]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function handleDoubleSides(type, seriesUnit, index, legendData) {
|
||||
if (type && type === 'double-sides') {
|
||||
if (index === legendData.length - 1) {
|
||||
seriesUnit.data = seriesUnit.data.map((item) => {
|
||||
if (isNumber(item)) {
|
||||
return -1 * item
|
||||
} else {
|
||||
return item
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function handleContain(type, seriesUnit) {
|
||||
if (type && type === 'contain') {
|
||||
seriesUnit.barGap = '-100%'
|
||||
}
|
||||
}
|
||||
|
||||
function handleColorStops(percent, originColor, markLineColor) {
|
||||
const colorStops = [
|
||||
{
|
||||
offset: 0,
|
||||
color: markLineColor || chartToken.colorError
|
||||
},
|
||||
{
|
||||
offset: percent,
|
||||
color: markLineColor || chartToken.colorError
|
||||
},
|
||||
{
|
||||
offset: percent + 0.001,
|
||||
color: originColor
|
||||
},
|
||||
{
|
||||
offset: 1,
|
||||
color: originColor
|
||||
}
|
||||
]
|
||||
return colorStops
|
||||
}
|
||||
|
||||
function handleTopObj(d, direction, percent, originColor, markLineColor) {
|
||||
const topObj = {
|
||||
value: d,
|
||||
itemStyle: {
|
||||
color: {
|
||||
type: 'linear',
|
||||
x: direction === 'horizontal' ? 1 : 0,
|
||||
y: direction === 'horizontal' ? 0 : 0,
|
||||
x2: direction === 'horizontal' ? 0 : 0,
|
||||
y2: direction === 'horizontal' ? 0 : 1,
|
||||
colorStops: handleColorStops(percent, originColor, markLineColor)
|
||||
}
|
||||
}
|
||||
}
|
||||
return topObj
|
||||
}
|
||||
|
||||
function handleBottomObj(d, direction, percent, originColor, markLineColor) {
|
||||
const bottomObj = {
|
||||
value: d,
|
||||
itemStyle: {
|
||||
color: {
|
||||
type: 'linear',
|
||||
x: direction === 'horizontal' ? 0 : 0,
|
||||
y: direction === 'horizontal' ? 0 : 1,
|
||||
x2: direction === 'horizontal' ? 1 : 0,
|
||||
y2: direction === 'horizontal' ? 0 : 0,
|
||||
colorStops: handleColorStops(percent, originColor, markLineColor)
|
||||
}
|
||||
}
|
||||
}
|
||||
return bottomObj
|
||||
}
|
||||
const colorStopsOrigin = [
|
||||
{ offset: 0, color: chartToken.colorError },
|
||||
{ offset: 1, color: chartToken.colorError }
|
||||
]
|
||||
|
||||
function handleColorStopsTop(originColor, bottomPercent) {
|
||||
const colorStops = [
|
||||
{ offset: 0, color: originColor },
|
||||
{ offset: bottomPercent, color: originColor },
|
||||
{ offset: bottomPercent + 0.0001, color: chartToken.colorError },
|
||||
{ offset: 1, color: chartToken.colorError }
|
||||
]
|
||||
return colorStops
|
||||
}
|
||||
|
||||
function handleColorStopsBottom(originColor, topPercent) {
|
||||
const colorStops = [
|
||||
{ offset: 0, color: chartToken.colorError },
|
||||
{ offset: topPercent, color: chartToken.colorError },
|
||||
{ offset: topPercent + 0.0001, color: originColor },
|
||||
{ offset: 1, color: originColor }
|
||||
]
|
||||
return colorStops
|
||||
}
|
||||
|
||||
function handleColorStopsOther(originColor, topPercent, bottomPercent) {
|
||||
const colorStops = [
|
||||
{ offset: 0, color: chartToken.colorError },
|
||||
{ offset: topPercent, color: chartToken.colorError },
|
||||
{ offset: topPercent + 0.0001, color: originColor },
|
||||
{ offset: bottomPercent, color: originColor },
|
||||
{ offset: bottomPercent + 0.0001, color: chartToken.colorError },
|
||||
{ offset: 1, color: chartToken.colorError }
|
||||
]
|
||||
return colorStops
|
||||
}
|
||||
|
||||
function handleResObj(d, direction, colorStops) {
|
||||
const resObj = {
|
||||
value: d,
|
||||
itemStyle: {
|
||||
color: {
|
||||
type: 'linear',
|
||||
x: direction === 'horizontal' ? 1 : 0,
|
||||
y: direction === 'horizontal' ? 0 : 0,
|
||||
x2: direction === 'horizontal' ? 0 : 0,
|
||||
y2: direction === 'horizontal' ? 0 : 1,
|
||||
colorStops
|
||||
}
|
||||
}
|
||||
}
|
||||
return resObj
|
||||
}
|
||||
|
||||
function handleSeries(iChartOption, baseOption, exclude, colors, direction) {
|
||||
// 顶部阈值
|
||||
let top = iChartOption.markLine.top
|
||||
// 底部阈值
|
||||
let bottom = iChartOption.markLine.bottom
|
||||
const usefullSeries = baseOption.series.filter((item) => {
|
||||
return !exclude.includes(item.name)
|
||||
})
|
||||
usefullSeries.forEach((item, index) => {
|
||||
if (!exclude.includes(item.name)) {
|
||||
const barData = item.data
|
||||
const placeHolderData = baseOption.series[index * 2].data
|
||||
item.data = barData.map((d, i) => {
|
||||
const pd = placeHolderData[i]
|
||||
if (top === undefined) {
|
||||
top = pd + d + 1
|
||||
}
|
||||
if (bottom === undefined) {
|
||||
bottom = pd - 1
|
||||
}
|
||||
const originColor = getColor(colors, index)
|
||||
let topPercent = 0
|
||||
let bottomPercent = 1
|
||||
topPercent = (d + pd - top) / d
|
||||
topPercent < 0 && (topPercent = 0)
|
||||
topPercent > 1 && (topPercent = 1)
|
||||
bottomPercent = (d + pd - bottom) / d
|
||||
bottomPercent < 0 && (bottomPercent = 0)
|
||||
bottomPercent > 1 && (bottomPercent = 1)
|
||||
let colorStops = []
|
||||
if (topPercent === 1 || bottomPercent === 0) {
|
||||
// 纯红
|
||||
colorStops = colorStopsOrigin
|
||||
} else if (topPercent === 0 && bottomPercent === 1) {
|
||||
// 原色
|
||||
return d
|
||||
} else if (topPercent === 0) {
|
||||
colorStops = handleColorStopsTop(originColor, bottomPercent)
|
||||
} else if (bottomPercent === 1) {
|
||||
colorStops = handleColorStopsBottom(originColor, topPercent)
|
||||
} else {
|
||||
colorStops = handleColorStopsOther(originColor, topPercent, bottomPercent)
|
||||
}
|
||||
const resObj = handleResObj(d, direction, colorStops)
|
||||
return resObj
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 针对阈值线以上显示红色区域的需求,图表需要进行特殊处理
|
||||
export function setMarkLine(baseOption, iChartOption) {
|
||||
const type = iChartOption.type
|
||||
const colors = baseOption.color
|
||||
const direction = iChartOption.direction
|
||||
const exclude = ['Placeholder']
|
||||
if (iChartOption.markLine && type !== 'water-fall' && type !== 'range') {
|
||||
// 顶部阈值
|
||||
const top = iChartOption.markLine.top
|
||||
const topUse = iChartOption.markLine.topUse
|
||||
// 底部阈值
|
||||
const bottom = iChartOption.markLine.bottom
|
||||
const bottomUse = iChartOption.markLine.bottomUse
|
||||
// 用户自定义阈值线颜色
|
||||
const markLineColor = iChartOption.markLine.color
|
||||
const usefullSeries = baseOption.series.filter((item) => {
|
||||
return !exclude.includes(item.name)
|
||||
})
|
||||
usefullSeries.forEach((item, index) => {
|
||||
if (!exclude.includes(item.name)) {
|
||||
const barData = item.data
|
||||
item.data = barData.map((d) => {
|
||||
const originColor = getColor(colors, index)
|
||||
// 如果该柱形高度超过阈值,侧改变其颜色
|
||||
if (top && d >= 0 && top >= 0 && d > top) {
|
||||
if (topUse && !topUse.includes(item.name)) {
|
||||
return d
|
||||
}
|
||||
const percent = (d - top) / (d - 0)
|
||||
const topObj = handleTopObj(d, direction, percent, originColor, markLineColor)
|
||||
return topObj
|
||||
// 如果该柱形高度低于阈值,侧改变其颜色
|
||||
} else if (bottom && d <= 0 && bottom <= 0 && d < bottom) {
|
||||
if (bottomUse && !bottomUse.includes(item.name)) {
|
||||
return d
|
||||
}
|
||||
const percent = (bottom - d) / (0 - d)
|
||||
const bottomObj = handleBottomObj(d, direction, percent, originColor, markLineColor)
|
||||
return bottomObj
|
||||
} else {
|
||||
return d
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
//
|
||||
if (iChartOption.markLine && type === 'range') {
|
||||
handleSeries(iChartOption, baseOption, exclude, colors, direction)
|
||||
}
|
||||
}
|
||||
|
||||
function placeFun(index, placeholderData) {
|
||||
const a = {
|
||||
name: 'Placeholder',
|
||||
type: 'bar',
|
||||
stack: `stack${index}`,
|
||||
itemStyle: {
|
||||
borderColor: chartToken.borderColor,
|
||||
color: chartToken.color
|
||||
},
|
||||
emphasis: {
|
||||
itemStyle: {
|
||||
borderColor: chartToken.borderColor,
|
||||
color: chartToken.color
|
||||
}
|
||||
},
|
||||
data: placeholderData
|
||||
}
|
||||
return a
|
||||
}
|
||||
|
||||
// 针对区间图表需求,图表需要进行特殊处理
|
||||
export function setRange(baseOption, iChartOption) {
|
||||
const type = iChartOption.type
|
||||
if (type && type === 'range') {
|
||||
const tempArray = []
|
||||
baseOption.series.forEach((item, index) => {
|
||||
const barData = item.data
|
||||
const barRealData = []
|
||||
const placeholderData = []
|
||||
const placeholder = placeFun(index, placeholderData)
|
||||
barData.forEach((d) => {
|
||||
placeholderData.push(d[0])
|
||||
barRealData.push(d[1] - d[0])
|
||||
})
|
||||
item.stack = `stack${index}`
|
||||
item.data = barRealData
|
||||
tempArray.push(placeholder)
|
||||
tempArray.push(item)
|
||||
})
|
||||
baseOption.series = tempArray
|
||||
}
|
||||
}
|
||||
|
||||
// 针对瀑布图表需求,图表需要进行特殊处理
|
||||
export function setWaterFall(baseOption, iChartOption) {
|
||||
const type = iChartOption.type
|
||||
const totalName = iChartOption.totalName || 'Total'
|
||||
const totalPosition = iChartOption.totalPosition || 'end'
|
||||
if (type && type === 'water-fall') {
|
||||
const tempArray = []
|
||||
baseOption.series.forEach((item, index) => {
|
||||
const barData = item.data
|
||||
const placeholderData = [0]
|
||||
const placeholder = placeFun(index, placeholderData)
|
||||
if (totalPosition === 'end') {
|
||||
barData.forEach((d, i) => {
|
||||
if (i < barData.length - 1) {
|
||||
placeholderData.push((Number(d) || 0) + placeholderData[i])
|
||||
}
|
||||
})
|
||||
placeholderData[placeholderData.length - 1] = 0
|
||||
} else {
|
||||
barData.unshift(barData.pop())
|
||||
placeholderData[0] = barData[0]
|
||||
barData.forEach((d, i) => {
|
||||
if (i > 0) {
|
||||
placeholderData.push(placeholderData[i - 1] - (Number(d) || 0))
|
||||
}
|
||||
})
|
||||
placeholderData[0] = 0
|
||||
}
|
||||
item.stack = `stack${index}`
|
||||
tempArray.push(placeholder)
|
||||
tempArray.push(item)
|
||||
})
|
||||
if (totalPosition === 'end') {
|
||||
baseOption.xAxis[0].data.push(totalName)
|
||||
} else {
|
||||
baseOption.xAxis[0].data.unshift(totalName)
|
||||
}
|
||||
baseOption.series = tempArray
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 为了实现一些特殊的样式,增加了一些series,如柱状图中的PlaceHolder series
|
||||
* 因此在 tooltip 中应该被屏蔽这些series
|
||||
* 因此对 tooltip.formatter 进行二次封装
|
||||
*/
|
||||
export function setLimitFormatter(baseOption, iChartOption, seriesData) {
|
||||
const type = iChartOption.type
|
||||
const toolTipFormatter = baseOption.tooltip.formatter
|
||||
const exclude = ['Placeholder']
|
||||
const colors = baseOption.color
|
||||
baseOption.tooltip.formatter = (params, ticket, callback) => {
|
||||
const newParams = params.filter((item) => {
|
||||
return !exclude.includes(item.seriesName)
|
||||
})
|
||||
if (toolTipFormatter) {
|
||||
return toolTipFormatter(newParams, ticket, callback)
|
||||
}
|
||||
let htmlString = ''
|
||||
newParams.forEach((item, index) => {
|
||||
if (index === 0) {
|
||||
htmlString += `<div style="margin-bottom:4px;">${defendXSS(item.name)}</div>`
|
||||
}
|
||||
const itemColor = typeof item.color === 'string' ? item.color : getColor(colors, index)
|
||||
htmlString += `
|
||||
<div>
|
||||
<span style="display:inline-block;width:10px;height:10px;border-radius:5px;background-color:${defendXSS(
|
||||
itemColor
|
||||
)};">
|
||||
</span>
|
||||
<span style="margin-left:5px;">
|
||||
<span style="display:inline-block;margin-right:8px;min-width:60px;">${defendXSS(
|
||||
item.seriesName
|
||||
)}</span>
|
||||
<span style="font-weight:bold">
|
||||
${defendXSS(
|
||||
type === 'range'
|
||||
? `${`${`[${params[index * 2].value}`}-${params[index * 2].value + item.value}`}]`
|
||||
: item.value || seriesData[item.seriesName][item.dataIndex]
|
||||
)}
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
`
|
||||
})
|
||||
return htmlString
|
||||
}
|
||||
}
|
||||
|
||||
function handleYaxis(series, yAxis) {
|
||||
if (Array.isArray(yAxis)) {
|
||||
yAxis.forEach((y, index) => {
|
||||
series.forEach((s, indexs) => {
|
||||
if (y.dataName && y.dataName.includes(s.name)) {
|
||||
series[indexs].yAxisIndex = index
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
import min from '../../util/sort/min'
|
||||
import max from '../../util/sort/max'
|
||||
import { getColor } from '../../util/color'
|
||||
import chartToken from './chartToken'
|
||||
|
||||
export function setVisualMap(legendData, seriesData, markLine, colors) {
|
||||
const visualMap = []
|
||||
if (markLine) {
|
||||
const topValue = markLine.top
|
||||
const bottomValue = markLine.bottom
|
||||
legendData.forEach((legendName, index) => {
|
||||
const data = seriesData[legendName]
|
||||
const minData = min(data)
|
||||
const maxData = max(data)
|
||||
const bottom = bottomValue || minData - 1
|
||||
const top = topValue || maxData + 1
|
||||
// 根据数据大小映射颜色
|
||||
visualMap.push({
|
||||
show: false,
|
||||
type: 'piecewise',
|
||||
dimension: 1,
|
||||
seriesIndex: index,
|
||||
pieces: [
|
||||
{
|
||||
gt: bottom,
|
||||
lt: top,
|
||||
color: getColor(colors, index)
|
||||
}
|
||||
],
|
||||
outOfRange: {
|
||||
color: chartToken.colorError
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
return visualMap
|
||||
}
|
|
@ -0,0 +1,110 @@
|
|||
import LineChart from '../LineChart'
|
||||
import init from '../../option/init'
|
||||
import { event } from '../../util/event'
|
||||
import cloneDeep from '../../util/cloneDeep'
|
||||
import BaseOption from '../../option/base'
|
||||
import { mergeVisualMap, mergeSeries } from '../../util/merge'
|
||||
import RectCoordSys from '../../option/RectSys'
|
||||
import { setStack, setDirection, setDoubleSides } from './handleOptipn'
|
||||
import { xkey, xdata, ldata, ydata } from '../../option/RectSys'
|
||||
|
||||
import { setSeries, setRange, setMarkLine, setWaterFall, setLimitFormatter } from './handleSeries'
|
||||
|
||||
class BarChart {
|
||||
constructor(iChartOption, chartInstance) {
|
||||
this.baseOption = {}
|
||||
this.baseOption = cloneDeep(BaseOption)
|
||||
this.chartInstance = chartInstance
|
||||
// 组装 iChartOption, 补全默认值
|
||||
this.iChartOption = init(iChartOption)
|
||||
// 根据 iChartOption 组装 baseOption
|
||||
this.updateOption()
|
||||
}
|
||||
|
||||
updateOption() {
|
||||
const iChartOption = this.iChartOption
|
||||
// 装载除series之外的其他配置
|
||||
RectCoordSys(this.baseOption, this.iChartOption, 'BarChart')
|
||||
// x轴key值
|
||||
const xAxisKey = xkey(iChartOption)
|
||||
// x轴数据
|
||||
const xAxisData = xdata(iChartOption.data, xAxisKey)
|
||||
// 图例数据
|
||||
const legendData = ldata(iChartOption.data, xAxisKey)
|
||||
// 连线的数据
|
||||
const seriesData = ydata(iChartOption.data, legendData)
|
||||
// 赋值数据
|
||||
this.baseOption.legend.data = iChartOption.legend.data || legendData
|
||||
this.baseOption.xAxis.forEach((item) => {
|
||||
item.data = xAxisData
|
||||
})
|
||||
this.baseOption.series = setSeries(seriesData, legendData, iChartOption)
|
||||
// 给堆叠图的柱子中间加上空白缝隙,并覆盖图例的点击事件
|
||||
setStack(this.baseOption, iChartOption, legendData, seriesData)
|
||||
// 针对数据均为正数的双向柱状图进行一些特殊处理
|
||||
setDoubleSides(this.baseOption, iChartOption)
|
||||
// 针对瀑布图表需求,图表需要进行特殊处理
|
||||
setWaterFall(this.baseOption, iChartOption)
|
||||
// 针对区间图表需求,图表需要进行特殊处理
|
||||
setRange(this.baseOption, iChartOption)
|
||||
// 针对阈值线变色,图表需要进行特殊处理
|
||||
setMarkLine(this.baseOption, iChartOption)
|
||||
// 设置柱状图的方向
|
||||
setDirection(this.baseOption, iChartOption.direction)
|
||||
// 对 tooltip.formatter 进行二次封装
|
||||
setLimitFormatter(this.baseOption, iChartOption, seriesData)
|
||||
// 配置图表事件
|
||||
if (iChartOption.event) {
|
||||
event(this.chartInstance, iChartOption.event)
|
||||
}
|
||||
// 是否关闭hover态的效果,默认为false
|
||||
if (iChartOption.silent) {
|
||||
this.baseOption.tooltip = {}
|
||||
}
|
||||
// 合并用户自定义series
|
||||
mergeSeries(iChartOption, this.baseOption)
|
||||
// 合并用户自定义visualMap
|
||||
mergeVisualMap(iChartOption, this.baseOption)
|
||||
}
|
||||
|
||||
// 根据渲染出的结果,二次计算option
|
||||
updateOptionAgain(YAxiMax, YAxiMin) {
|
||||
const baseOption = this.baseOption
|
||||
const iChartOption = this.iChartOption
|
||||
const lineDataName = iChartOption.lineDataName
|
||||
// 折柱混合
|
||||
if (lineDataName && lineDataName.length > 0) {
|
||||
const lineChartBaseOpt = new LineChart(iChartOption, {}, this.chartInstance)
|
||||
const lineBaseOption = lineChartBaseOpt.getOption()
|
||||
const lineSeries = lineBaseOption.series
|
||||
const barSeries = baseOption.series
|
||||
lineDataName.forEach((lineName) => {
|
||||
let bar = null
|
||||
let line = null
|
||||
for (let i = 0; i < lineSeries.length; i++) {
|
||||
if (lineSeries[i].name === lineName) {
|
||||
line = lineSeries[i]
|
||||
break
|
||||
}
|
||||
}
|
||||
for (let i = 0; i < barSeries.length; i++) {
|
||||
if (barSeries[i].name === lineName) {
|
||||
bar = barSeries[i]
|
||||
break
|
||||
}
|
||||
}
|
||||
for (const key in line) {
|
||||
bar[key] = line[key]
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
getOption() {
|
||||
return this.baseOption
|
||||
}
|
||||
|
||||
setOption() {}
|
||||
}
|
||||
|
||||
export default BarChart
|
|
@ -0,0 +1,113 @@
|
|||
import { insertStateDom, removeStateDom } from '../../util/init/insert'
|
||||
export default class BaseChart {
|
||||
// 图表渲染容器
|
||||
dom
|
||||
// 图表渲染配置
|
||||
option
|
||||
|
||||
constructor() {
|
||||
// 必须实现 init 方法,初始化图表渲染容器
|
||||
if (this.init === undefined) {
|
||||
throw new Error('This chart has not overwrite "init" callback!')
|
||||
}
|
||||
// 必须实现 setSimpleOption 方法,初始化图表渲染配置
|
||||
if (this.setSimpleOption === undefined) {
|
||||
throw new Error('This chart has not overwrite "setSimpleOption" callback!')
|
||||
}
|
||||
// 必须实现 render 方法,调用时开始渲染图表
|
||||
if (this.render === undefined) {
|
||||
throw new Error('This chart has not overwrite "render" callback!')
|
||||
}
|
||||
// 必须实现 onRenderReady 方法
|
||||
if (this.onRenderReady === undefined) {
|
||||
throw new Error('This chart has not overwrite "onRenderReady" callback!')
|
||||
}
|
||||
// 必须实现 refresh 方法,传入新的option,刷新图表
|
||||
if (this.refresh === undefined) {
|
||||
throw new Error('This chart has not overwrite "refresh" callback!')
|
||||
}
|
||||
// 必须实现 refreshData 方法,传入新的data,刷新图表
|
||||
if (this.refreshData === undefined) {
|
||||
throw new Error('This chart has not overwrite "refreshData" callback!')
|
||||
}
|
||||
// 必须实现 setResize 方法,该方法一般手动调用,实现图表自适应宽度
|
||||
if (this.setResize === undefined) {
|
||||
throw new Error('This chart has not overwrite "setResize" callback!')
|
||||
}
|
||||
// 必须实现 uninstall 方法,清空图表容器,卸载所有监听事件
|
||||
if (this.uninstall === undefined) {
|
||||
throw new Error('This chart has not overwrite "uninstall" callback!')
|
||||
}
|
||||
}
|
||||
|
||||
// 加载状态
|
||||
showLoading(option) {
|
||||
insertStateDom(this.dom, 'loading', option)
|
||||
}
|
||||
|
||||
hideLoading() {
|
||||
removeStateDom(this.dom, 'loading')
|
||||
}
|
||||
|
||||
closeLoading() {
|
||||
removeStateDom(this.dom, 'loading')
|
||||
}
|
||||
|
||||
// 错误状态
|
||||
showError(option) {
|
||||
insertStateDom(this.dom, 'error', option)
|
||||
}
|
||||
|
||||
closeError() {
|
||||
removeStateDom(this.dom, 'error')
|
||||
}
|
||||
|
||||
// 空数据状态
|
||||
showEmpty(option) {
|
||||
insertStateDom(this.dom, 'empty', option)
|
||||
}
|
||||
|
||||
closeEmpty() {
|
||||
removeStateDom(this.dom, 'empty')
|
||||
}
|
||||
|
||||
// 阶段空数据状态
|
||||
showStageEmpty(option) {
|
||||
insertStateDom(this.dom, 'stage_empty', option)
|
||||
}
|
||||
|
||||
closeStageEmpty() {
|
||||
removeStateDom(this.dom, 'stage_empty')
|
||||
}
|
||||
|
||||
// 自定义数据状态
|
||||
showState(option) {
|
||||
insertStateDom(this.dom, 'custom', option)
|
||||
}
|
||||
|
||||
closeState() {
|
||||
removeStateDom(this.dom, 'custom')
|
||||
}
|
||||
|
||||
// 传入自定义DOM
|
||||
showCustomDom(callback) {
|
||||
if (this.dom.getElementsByClassName('huicharts-custom-dom').length > 0) return
|
||||
if (getComputedStyle(this.dom).position === ('static' || '')) {
|
||||
this.dom.style.position = 'relative'
|
||||
}
|
||||
let customContainer = document.createElement('div')
|
||||
customContainer.className = 'huicharts-custom-dom'
|
||||
customContainer.setAttribute(
|
||||
'style',
|
||||
'position:absolute;width:100%;height:100%;top:0px;left:0px;display:flex;justify-content:center;align-items:center'
|
||||
)
|
||||
this.dom.appendChild(customContainer)
|
||||
callback(customContainer)
|
||||
}
|
||||
|
||||
// 删除自定义DOM
|
||||
closeCustomDom() {
|
||||
let customContainer = this.dom.getElementsByClassName('huicharts-custom-dom')
|
||||
this.dom.removeChild(customContainer[0])
|
||||
}
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
import Theme from '../../feature/token'
|
||||
import proxy from '../../util/proxy'
|
||||
|
||||
function getChartToken() {
|
||||
const {
|
||||
itemStyle: { color: colorBgPrimary }
|
||||
} = Theme.config.BoxplotChart
|
||||
|
||||
return {
|
||||
itemColor: colorBgPrimary
|
||||
}
|
||||
}
|
||||
|
||||
const chartToken = proxy(getChartToken)
|
||||
|
||||
export default chartToken
|
|
@ -0,0 +1,52 @@
|
|||
import defendXSS from '../../util/defendXSS'
|
||||
|
||||
/**
|
||||
* 设置图的方向
|
||||
*/
|
||||
export function setDirection(baseOption, direction) {
|
||||
if (direction && direction === 'horizontal') {
|
||||
const temp = baseOption.xAxis
|
||||
baseOption.xAxis = baseOption.yAxis
|
||||
baseOption.yAxis = temp
|
||||
}
|
||||
}
|
||||
|
||||
function tooltipFormatter(params) {
|
||||
const { data, color, seriesType } = params
|
||||
const labels = ['下限', '下四分位数', '中位数', '上四分位数', '上限']
|
||||
let htmlString = ''
|
||||
if (seriesType === 'boxplot') {
|
||||
const arr = []
|
||||
labels.forEach((item, index) => {
|
||||
htmlString = `<div>
|
||||
<span style="display:inline-block;width:10px;height:10px;
|
||||
margin-right:4px;border-radius:5px;border-style: solid;border-width:1px;
|
||||
border-color:${defendXSS(color)};background-color:${defendXSS(color)};"></span>
|
||||
<span style="display:inline-block;width:90px">${defendXSS(item)}:</span><span>${defendXSS(
|
||||
data[index + 1]
|
||||
)}</span>
|
||||
</div>`
|
||||
arr.push(htmlString)
|
||||
})
|
||||
htmlString = arr.join('<br/>')
|
||||
} else {
|
||||
htmlString = `<div>
|
||||
<span style="display:inline-block;width:10px;height:10px;
|
||||
margin-right:4px;border-radius:5px;border-style: solid;border-width:1px;
|
||||
border-color:${defendXSS(color)};background-color:${defendXSS(color)};"></span>
|
||||
<span style="display:inline-block;width:90px">离散点:</span><span>${defendXSS(
|
||||
data[1]
|
||||
)}</span>
|
||||
</div>`
|
||||
}
|
||||
return htmlString
|
||||
}
|
||||
|
||||
/**
|
||||
* 配置默认的鼠标悬浮提示框
|
||||
*/
|
||||
export function setTooltip(baseOpt) {
|
||||
if (!baseOpt.tooltip.formatter) {
|
||||
baseOpt.tooltip.formatter = tooltipFormatter
|
||||
}
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
import cloneDeep from '../../util/cloneDeep'
|
||||
import chartToken from './chartToken'
|
||||
|
||||
const datasetInit = [
|
||||
{
|
||||
source: []
|
||||
},
|
||||
{
|
||||
transform: {
|
||||
type: 'boxplot'
|
||||
}
|
||||
},
|
||||
{
|
||||
fromDatasetIndex: 1,
|
||||
fromTransformResult: 1
|
||||
}
|
||||
]
|
||||
|
||||
const seriesInit = [
|
||||
{
|
||||
name: 'boxplot',
|
||||
type: 'boxplot',
|
||||
datasetIndex: 1,
|
||||
itemStyle: {
|
||||
color: ''
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'outlier',
|
||||
type: 'scatter',
|
||||
datasetIndex: 2
|
||||
}
|
||||
]
|
||||
|
||||
/**
|
||||
* 组装echarts所需要的dataset
|
||||
* @param {传入数据} data
|
||||
* @returns
|
||||
*/
|
||||
export function setDataset(data) {
|
||||
const dataset = cloneDeep(datasetInit)
|
||||
dataset[0].source = data
|
||||
return dataset
|
||||
}
|
||||
|
||||
export function setSeries() {
|
||||
const series = cloneDeep(seriesInit)
|
||||
series[0].itemStyle.color = chartToken.itemColor
|
||||
return series
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
import init from '../../option/init'
|
||||
import { event } from '../../util/event'
|
||||
import { setDataset, setSeries } from './handleSeries'
|
||||
import { setDirection, setTooltip } from './handleOption'
|
||||
import RectCoordSys from '../../option/RectSys'
|
||||
import chartToken from './chartToken'
|
||||
|
||||
const CHART_NAME = 'BoxplotChart'
|
||||
export default class BoxplotChart {
|
||||
constructor(iChartOption, chartInstance) {
|
||||
this.baseOption = {}
|
||||
this.iChartOption = {}
|
||||
this.iChartOption = init(iChartOption)
|
||||
this.updateOption(chartInstance)
|
||||
}
|
||||
|
||||
updateOption(chartInstance) {
|
||||
const iChartOption = this.iChartOption
|
||||
// 装载除series之外的其他配置
|
||||
RectCoordSys(this.baseOption, this.iChartOption, CHART_NAME)
|
||||
// 箱形图data必须设为undefined
|
||||
this.baseOption.xAxis[0].data = undefined
|
||||
// 提示框trigger设为item
|
||||
this.baseOption.tooltip.trigger = 'item'
|
||||
// 配置默认dataset
|
||||
if (iChartOption.data && !iChartOption.dataset) {
|
||||
this.baseOption.dataset = setDataset(iChartOption.data)
|
||||
this.baseOption.series = setSeries()
|
||||
}
|
||||
// 自定义dataset和series
|
||||
if (iChartOption.dataset && iChartOption.series) {
|
||||
this.baseOption.dataset = iChartOption.dataset
|
||||
this.baseOption.series = iChartOption.series
|
||||
this.baseOption.series.forEach((item) => {
|
||||
item.itemStyle = {}
|
||||
item.itemStyle.color = chartToken.itemColor
|
||||
})
|
||||
}
|
||||
// 横向
|
||||
setDirection(this.baseOption, iChartOption.direction)
|
||||
// 提示框
|
||||
setTooltip(this.baseOption)
|
||||
// 配置图表事件
|
||||
if (iChartOption.event) {
|
||||
event(chartInstance, iChartOption.event)
|
||||
}
|
||||
}
|
||||
|
||||
getOption() {
|
||||
return this.baseOption
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
import Theme from '../../feature/token'
|
||||
import proxy from '../../util/proxy'
|
||||
|
||||
function getChartToken() {
|
||||
const {
|
||||
emphasis: {
|
||||
label: { color: colorLabel }
|
||||
}
|
||||
} = Theme.config.BubbleChart
|
||||
|
||||
return {
|
||||
emphasisLabelColor: colorLabel,
|
||||
labelColor: colorLabel
|
||||
}
|
||||
}
|
||||
|
||||
const chartToken = proxy(getChartToken)
|
||||
|
||||
export default chartToken
|
|
@ -0,0 +1,22 @@
|
|||
/**
|
||||
* 从数据中拿出legend-data
|
||||
*/
|
||||
export function getLegendData(data) {
|
||||
return Object.keys(data)
|
||||
}
|
||||
|
||||
/**
|
||||
* 从数据中拿出x轴的坐标数据
|
||||
*/
|
||||
export function getXAxisData(data) {
|
||||
const xAxisData = []
|
||||
const dataValues = Object.values(data)
|
||||
dataValues.forEach((item) => {
|
||||
item.forEach((val) => {
|
||||
if (!xAxisData.includes(val[0])) {
|
||||
xAxisData.push(val[0])
|
||||
}
|
||||
})
|
||||
})
|
||||
return xAxisData
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
import { changeRgbaOpacity } from '../../util/color'
|
||||
import defendXSS from '../../util/defendXSS'
|
||||
|
||||
function tooltipFormatter(params) {
|
||||
const seriesName = params.seriesName
|
||||
const color = params.color
|
||||
const data = params.data
|
||||
const [x, y, radius, name] = data
|
||||
let htmlString = `<div style="margin-bottom:4px;">
|
||||
${defendXSS(seriesName)}
|
||||
</div>`
|
||||
htmlString += `<div style="margin-bottom:4px;">
|
||||
<span style="display:inline-block;width:10px;height:10px;
|
||||
margin-right:8px;border-radius:5px;border-style: solid;border-width:1px;
|
||||
border-color:${defendXSS(changeRgbaOpacity(color, 1))};background-color:${defendXSS(
|
||||
color
|
||||
)};"></span>
|
||||
<span>${defendXSS(name)}</span>
|
||||
</div>`
|
||||
htmlString += `
|
||||
<div>
|
||||
<span style="display:inline-block;margin-right:8px;min-width:60px;">x维度</span>
|
||||
<span>${defendXSS(x)}</span>
|
||||
</div>
|
||||
`
|
||||
htmlString += `
|
||||
<div>
|
||||
<span style="display:inline-block;margin-right:8px;min-width:60px;">y维度</span>
|
||||
<span>${defendXSS(y)}</span>
|
||||
</div>
|
||||
`
|
||||
htmlString += `
|
||||
<div>
|
||||
<span style="display:inline-block;margin-right:8px;min-width:60px;">半径维度</span>
|
||||
<span>${defendXSS(radius)}</span>
|
||||
</div>
|
||||
`
|
||||
return htmlString
|
||||
}
|
||||
|
||||
/**
|
||||
* 配置默认的鼠标悬浮提示框
|
||||
*/
|
||||
export function setTooltip(baseOpt, iChartOption) {
|
||||
baseOpt.tooltip.trigger = 'item'
|
||||
if (iChartOption.trigger === 'axis') {
|
||||
baseOpt.tooltip.trigger = 'axis'
|
||||
baseOpt.tooltip.axisPointer.type = 'shadow'
|
||||
}
|
||||
if (!baseOpt.tooltip.formatter) {
|
||||
baseOpt.tooltip.formatter = tooltipFormatter
|
||||
}
|
||||
}
|
|
@ -0,0 +1,72 @@
|
|||
import { getColor, codeToRGB } from '../../util/color'
|
||||
import cloneDeep from '../../util/cloneDeep'
|
||||
import { getMarkLineDefault } from '../../option/config/mark'
|
||||
import chartToken from './chartToken'
|
||||
import merge from '../../util/merge'
|
||||
|
||||
export const seriesInit = {
|
||||
// 数据
|
||||
data: [],
|
||||
// 气泡图
|
||||
type: 'scatter',
|
||||
// 鼠标hover时显示label,并且其他legend变成灰色
|
||||
emphasis: {
|
||||
label: {
|
||||
show: true,
|
||||
color: '#ffffff',
|
||||
fontSize: 14,
|
||||
formatter(param) {
|
||||
return param.data[3]
|
||||
},
|
||||
position: 'top'
|
||||
}
|
||||
},
|
||||
// 气泡样式
|
||||
itemStyle: {}
|
||||
}
|
||||
|
||||
export function setSeries({ legendData, data, markLine, color, iChartOption }) {
|
||||
// 更改hover时显示的label颜色
|
||||
seriesInit.emphasis.label.color = chartToken.emphasisLabelColor
|
||||
const series = []
|
||||
legendData.forEach((legend, index) => {
|
||||
const seriesUnit = cloneDeep(seriesInit)
|
||||
const itemBorderColor = getColor(color, index)
|
||||
// 设置图元透明度
|
||||
const itemColor = codeToRGB(itemBorderColor, iChartOption.symbolOpacity || 0.2)
|
||||
// 阈值线
|
||||
if (markLine) {
|
||||
seriesUnit.markLine = cloneDeep(getMarkLineDefault())
|
||||
if (markLine.y) {
|
||||
seriesUnit.markLine.data.push({ yAxis: markLine.y })
|
||||
}
|
||||
if (markLine.x) {
|
||||
seriesUnit.markLine.data.push({ xAxis: markLine.x })
|
||||
}
|
||||
}
|
||||
// 数据 / 数据名称
|
||||
seriesUnit.name = legend
|
||||
seriesUnit.data = data[legend]
|
||||
seriesUnit.itemStyle = {
|
||||
color: itemColor,
|
||||
borderColor: itemBorderColor,
|
||||
borderWidth: 1
|
||||
}
|
||||
series.push(seriesUnit)
|
||||
})
|
||||
return series
|
||||
}
|
||||
|
||||
// 添加seires属性
|
||||
export function handleSeriesExtra(baseOpt, iChartOption) {
|
||||
const { symbol, symbolRotate, symbolOffset, cursor, label, itemStyle, emphasis } = iChartOption
|
||||
baseOpt.series.forEach((item) => {
|
||||
item.symbol = symbol
|
||||
item.symbolRotate = symbolRotate
|
||||
item.symbolOffset = symbolOffset
|
||||
item.cursor = cursor
|
||||
item.label = label
|
||||
merge(item.itemStyle, itemStyle)
|
||||
merge(item.emphasis, emphasis)
|
||||
})
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
import * as echarts from 'echarts'
|
||||
import chartToken from './chartToken'
|
||||
|
||||
/**
|
||||
* 针对趋势线需求,图表需要进行特殊处理
|
||||
*/
|
||||
export function handleTrendLine(option, iChartOption, plugins) {
|
||||
const ecStat = plugins.ecStat
|
||||
if (iChartOption.trendLineConfig) {
|
||||
if (ecStat) {
|
||||
echarts.registerTransform(ecStat.transform.regression)
|
||||
// 集合数据
|
||||
option.dataset.push({
|
||||
transform: {
|
||||
type: 'ecStat:regression',
|
||||
config: iChartOption.trendLineConfig
|
||||
}
|
||||
})
|
||||
// 趋势线
|
||||
option.series.push({
|
||||
name: 'trendline',
|
||||
type: 'line',
|
||||
smooth: true,
|
||||
datasetIndex: 1,
|
||||
symbolSize: 0.1,
|
||||
symbol: 'circle',
|
||||
label: {
|
||||
show: true,
|
||||
fontSize: 14,
|
||||
color: chartToken.labelColor
|
||||
},
|
||||
labelLayout: {
|
||||
dx: -20
|
||||
},
|
||||
encode: {
|
||||
label: 2,
|
||||
tooltip: 1
|
||||
},
|
||||
silent: true
|
||||
})
|
||||
} else {
|
||||
throw new Error('您必须安装echarts-stat才可以使用趋势线功能')
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
import min from '../../util/sort/min'
|
||||
import max from '../../util/sort/max'
|
||||
|
||||
export function setVisualMap(baseOption, iChartOption, legendData) {
|
||||
const visualMap = []
|
||||
const bubbleSize = iChartOption.bubbleSize || [10, 70]
|
||||
const radius = baseOption.dataset[0].source.map((item) => {
|
||||
return item[2]
|
||||
})
|
||||
const minValue = min(radius)
|
||||
const maxValue = max(radius)
|
||||
const seriesIndex = new Array(legendData.length).fill(0).map((item, index) => {
|
||||
return index
|
||||
})
|
||||
visualMap.push({
|
||||
show: false,
|
||||
dimension: 2,
|
||||
min: minValue,
|
||||
max: maxValue,
|
||||
seriesIndex,
|
||||
inRange: {
|
||||
symbolSize: bubbleSize
|
||||
}
|
||||
})
|
||||
return visualMap
|
||||
}
|
||||
|
||||
// 设置数据集
|
||||
export function setDataset(baseOption, iChartOption) {
|
||||
let source = []
|
||||
Object.keys(iChartOption.data).forEach((key) => {
|
||||
source = source.concat(iChartOption.data[key])
|
||||
})
|
||||
return [
|
||||
{
|
||||
source
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,86 @@
|
|||
import init from '../../option/init'
|
||||
import BaseOption from '../../option/base'
|
||||
import cloneDeep from '../../util/cloneDeep'
|
||||
import { getLegendData, getXAxisData } from './handleData'
|
||||
import { setSeries, handleSeriesExtra } from './handleSeries'
|
||||
import { setTooltip } from './handleOptipn'
|
||||
import { handleTrendLine } from './handleTrendLine'
|
||||
import { setDataset, setVisualMap } from './handleVisualMap'
|
||||
import RectCoordSys from '../../option/RectSys'
|
||||
import { event } from '../../util/event'
|
||||
import { mergeSeries, mergeVisualMap } from '../../util/merge'
|
||||
|
||||
class BubbleChart {
|
||||
constructor(iChartOption, chartInstance, plugins) {
|
||||
this.baseOption = {}
|
||||
this.baseOption = cloneDeep(BaseOption)
|
||||
this.iChartOption = {}
|
||||
this.chartInstance = chartInstance
|
||||
// 组装 iChartOption, 补全默认值
|
||||
this.iChartOption = init(iChartOption)
|
||||
// 根据 iChartOption 组装 baseOption
|
||||
this.updateOption(plugins)
|
||||
}
|
||||
|
||||
updateOption(plugins) {
|
||||
const iChartOption = this.iChartOption
|
||||
// 装载除series之外的其他配置
|
||||
RectCoordSys(this.baseOption, this.iChartOption, 'BubbleChart')
|
||||
// 增加气泡图的默认悬浮提示框
|
||||
setTooltip(this.baseOption, iChartOption)
|
||||
// 组装基础数据
|
||||
const legendData = getLegendData(iChartOption.data)
|
||||
// 设置x轴类型,是目录型,还是数值型
|
||||
const { xAxisType } = iChartOption
|
||||
if (
|
||||
legendData &&
|
||||
legendData[0] &&
|
||||
iChartOption.data[legendData[0]] &&
|
||||
iChartOption.data[legendData[0]][0] &&
|
||||
iChartOption.data[legendData[0]][0][0] &&
|
||||
typeof iChartOption.data[legendData[0]][0][0] === 'string'
|
||||
) {
|
||||
this.baseOption.xAxis.forEach((item) => {
|
||||
item.type = xAxisType || 'category'
|
||||
item.data = getXAxisData(iChartOption.data)
|
||||
})
|
||||
} else {
|
||||
this.baseOption.xAxis.forEach((item) => {
|
||||
item.type = xAxisType || 'value'
|
||||
})
|
||||
}
|
||||
// 赋值数据
|
||||
this.baseOption.legend.data = this.baseOption.legend.data || legendData
|
||||
this.baseOption.series = setSeries({
|
||||
legendData,
|
||||
data: iChartOption.data,
|
||||
markLine: iChartOption.markLine,
|
||||
color: this.baseOption.color,
|
||||
iChartOption
|
||||
})
|
||||
// 添加dataset
|
||||
this.baseOption.dataset = setDataset(this.baseOption, iChartOption)
|
||||
// 设置VisualMap,通过数值映射气泡大小
|
||||
this.baseOption.visualMap = setVisualMap(this.baseOption, iChartOption, legendData)
|
||||
// 针对趋势线的需求,图表需要进行特殊处理
|
||||
handleTrendLine(this.baseOption, iChartOption, plugins)
|
||||
// 添加seires属性
|
||||
handleSeriesExtra(this.baseOption, iChartOption)
|
||||
// 配置图表事件
|
||||
if (iChartOption.event) {
|
||||
event(this.chartInstance, iChartOption.event)
|
||||
}
|
||||
// 合并用户自定义series
|
||||
mergeSeries(iChartOption, this.baseOption)
|
||||
// 合并用户自定义visualMap
|
||||
mergeVisualMap(iChartOption, this.baseOption)
|
||||
}
|
||||
|
||||
getOption() {
|
||||
return this.baseOption
|
||||
}
|
||||
|
||||
setOption() {}
|
||||
}
|
||||
|
||||
export default BubbleChart
|
|
@ -0,0 +1,33 @@
|
|||
// 显示volume需要的grid
|
||||
const VOLUMEGRID = [
|
||||
{
|
||||
left: '5%',
|
||||
right: '5%',
|
||||
height: '50%',
|
||||
top: '2%',
|
||||
containLabel: false
|
||||
},
|
||||
{
|
||||
left: '5%',
|
||||
right: '5%',
|
||||
top: '63%',
|
||||
height: '25%',
|
||||
containLabel: false
|
||||
}
|
||||
]
|
||||
|
||||
const BASICSERIES = [
|
||||
{
|
||||
name: '日K',
|
||||
type: 'candlestick',
|
||||
data: undefined,
|
||||
itemStyle: {
|
||||
color: undefined,
|
||||
color0: undefined,
|
||||
borderColor: undefined,
|
||||
borderColor0: undefined
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
export { BASICSERIES, VOLUMEGRID }
|
|
@ -0,0 +1,21 @@
|
|||
import Theme from '../../feature/token'
|
||||
import proxy from '../../util/proxy'
|
||||
|
||||
function getChartToken() {
|
||||
const {
|
||||
axisPointer: {
|
||||
label: { color: colorTextSecondary }
|
||||
}
|
||||
} = Theme.config.CandlestickChart
|
||||
|
||||
const { colorState } = Theme.config
|
||||
|
||||
return {
|
||||
axisPointerLabelColor: colorTextSecondary,
|
||||
colorState
|
||||
}
|
||||
}
|
||||
|
||||
const chartToken = proxy(getChartToken)
|
||||
|
||||
export default chartToken
|
|
@ -0,0 +1,119 @@
|
|||
import { isArray } from '../../util/type'
|
||||
import cloneDeep from '../../util/cloneDeep'
|
||||
import { VOLUMEGRID } from './BaseOption'
|
||||
import merge from '../../util/merge'
|
||||
import chartToken from './chartToken'
|
||||
import { xkey } from '../../option/RectSys'
|
||||
|
||||
function handleData(iChartOpt) {
|
||||
const { data } = iChartOpt
|
||||
const xAxisDataName = xkey(iChartOpt)
|
||||
if (data && data.length !== 0) {
|
||||
const time = []
|
||||
const total = []
|
||||
data.forEach((item) => {
|
||||
time.push(item[xAxisDataName])
|
||||
const totalItem = [item.open, item.close, item.lowest, item.highest]
|
||||
if (item.volume) {
|
||||
totalItem.push(item.volume)
|
||||
}
|
||||
total.push(totalItem)
|
||||
})
|
||||
return {
|
||||
time,
|
||||
total
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
function handleAxis(baseOpt, data, volume) {
|
||||
const { xAxis } = baseOpt
|
||||
if (isArray(xAxis)) {
|
||||
const len = xAxis.length
|
||||
if (volume && len === 1) {
|
||||
const secXaxis = cloneDeep(xAxis[0])
|
||||
xAxis.push(secXaxis)
|
||||
}
|
||||
xAxis.forEach((x, xIndex) => {
|
||||
x.data = data.time
|
||||
x.boundaryGap = false
|
||||
x.axisLine.onZero = false
|
||||
if (xIndex === 1) {
|
||||
x.axisLabel.show = false
|
||||
x.axisTick.show = false
|
||||
x.gridIndex = 1
|
||||
}
|
||||
})
|
||||
} else {
|
||||
xAxis.data = data.time
|
||||
xAxis.boundaryGap = false
|
||||
xAxis.axisLine.onZero = false
|
||||
}
|
||||
|
||||
const { yAxis } = baseOpt
|
||||
const lenY = yAxis.length
|
||||
if (volume && lenY === 1) {
|
||||
const secYaxis = cloneDeep(yAxis[0])
|
||||
yAxis.push(secYaxis)
|
||||
}
|
||||
yAxis.forEach((y, yIndex) => {
|
||||
y.scale = true
|
||||
if (yIndex === 1) {
|
||||
y.axisLabel.show = false
|
||||
y.splitLine.show = false
|
||||
y.gridIndex = 1
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function handleDataZoom(baseOpt, iChartOpt) {
|
||||
const { dataZoom } = iChartOpt
|
||||
baseOpt.dataZoom[0].show = true
|
||||
baseOpt.dataZoom[0].xAxisIndex = [0, 1]
|
||||
baseOpt.dataZoom[0].bottom = '6%'
|
||||
if (dataZoom) {
|
||||
merge(baseOpt.dataZoom[0], dataZoom)
|
||||
}
|
||||
}
|
||||
|
||||
function handleLegend(baseOpt, iChartOpt) {
|
||||
const { legend } = iChartOpt
|
||||
if (legend) {
|
||||
merge(baseOpt.legend, legend)
|
||||
}
|
||||
}
|
||||
|
||||
function handleTooltip(baseOpt, iChartOpt) {
|
||||
const inerTooltip = { ...baseOpt.tooltip }
|
||||
delete inerTooltip.axisPointer
|
||||
inerTooltip.axisPointer = { type: 'cross' }
|
||||
baseOpt.tooltip = inerTooltip
|
||||
if (iChartOpt.tooltip) {
|
||||
merge(baseOpt.tooltip, iChartOpt.tooltip)
|
||||
}
|
||||
}
|
||||
|
||||
function handleGrid(baseOpt, iChartOpt) {
|
||||
const { volume, grid } = iChartOpt
|
||||
// 用户没有自定义grid,并且需要去显示volume,使用默认值
|
||||
if (!grid && volume) {
|
||||
baseOpt.grid = cloneDeep(VOLUMEGRID)
|
||||
}
|
||||
}
|
||||
|
||||
function handleAxisPointer(baseOpt) {
|
||||
const axisPointer = {
|
||||
link: [
|
||||
{
|
||||
xAxisIndex: 'all'
|
||||
}
|
||||
],
|
||||
label: {
|
||||
color: chartToken.axisPointerLabelColor
|
||||
}
|
||||
}
|
||||
baseOpt.axisPointer = axisPointer
|
||||
}
|
||||
|
||||
export { handleData, handleAxis, handleDataZoom, handleLegend, handleTooltip, handleGrid, handleAxisPointer }
|
|
@ -0,0 +1,110 @@
|
|||
import cloneDeep from '../../util/cloneDeep'
|
||||
import { BASICSERIES } from './BaseOption'
|
||||
import LineChart from '../LineChart'
|
||||
import BarChart from '../BarChart'
|
||||
import { xkey } from '../../option/RectSys'
|
||||
import chartToken from './chartToken'
|
||||
|
||||
function handleSeries(baseOpt, iChartOpt, data, chartInstance) {
|
||||
const { upColor, downColor } = iChartOpt
|
||||
const { colorState } = chartToken
|
||||
const upStateColor = upColor || colorState.colorError
|
||||
const downStateColor = downColor || colorState.colorSuccess
|
||||
const baseSeries = cloneDeep(BASICSERIES)
|
||||
baseSeries[0].data = data.total
|
||||
baseSeries[0].itemStyle.color = upStateColor
|
||||
baseSeries[0].itemStyle.color0 = downStateColor
|
||||
baseSeries[0].itemStyle.borderColor = upStateColor
|
||||
baseSeries[0].itemStyle.borderColor0 = downStateColor
|
||||
baseOpt.series = baseSeries
|
||||
|
||||
handleMaAndVolSeries(baseOpt, iChartOpt, data, { upStateColor, downStateColor }, chartInstance)
|
||||
}
|
||||
|
||||
// 用于计算相关的平均值
|
||||
function calculateMA(dayCount, data) {
|
||||
const result = []
|
||||
for (let i = 0, len = data.length; i < len; i++) {
|
||||
if (i < dayCount) {
|
||||
result.push('')
|
||||
continue
|
||||
}
|
||||
let sum = 0
|
||||
for (let j = 0; j < dayCount; j++) {
|
||||
sum += +data[i - j][1]
|
||||
}
|
||||
result.push(Number((sum / dayCount).toFixed(2)))
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
function getLineChartData(data, total, ma, xAxisKey) {
|
||||
const maData = {}
|
||||
ma.forEach((item) => {
|
||||
const data = calculateMA(item, total)
|
||||
maData[`MA${item}`] = data
|
||||
})
|
||||
const lineData = data.map((obj, index) => {
|
||||
const newObj = {
|
||||
[xAxisKey]: obj[xAxisKey]
|
||||
}
|
||||
for (const i in maData) {
|
||||
newObj[i] = maData[i][index]
|
||||
}
|
||||
return newObj
|
||||
})
|
||||
return lineData
|
||||
}
|
||||
|
||||
function getBarChartData(data, xAxisKey) {
|
||||
const barData = data.map((obj) => {
|
||||
const newObj = {
|
||||
[xAxisKey]: obj[xAxisKey],
|
||||
volume: obj.volume
|
||||
}
|
||||
return newObj
|
||||
})
|
||||
return barData
|
||||
}
|
||||
|
||||
function handleMaSeries(baseOpt, iChartOpt, data, total, inerMa, xAxisKey, chartInstance) {
|
||||
const lineChartData = getLineChartData(data, total, inerMa, xAxisKey)
|
||||
const newIchartOption = { ...iChartOpt, data: lineChartData }
|
||||
const lineChart = new LineChart(newIchartOption, {}, chartInstance)
|
||||
const lineBaseOption = lineChart.getOption()
|
||||
const lineSeries = lineBaseOption.series
|
||||
for (let i = 0; i < lineSeries.length; i++) {
|
||||
baseOpt.series.push(lineSeries[i])
|
||||
}
|
||||
}
|
||||
|
||||
function handleVol(baseOpt, iChartOpt, data, xAxisKey, { upStateColor, downStateColor }, total, chartInstance) {
|
||||
const barChartData = getBarChartData(data, xAxisKey)
|
||||
const newIchartOption = { ...iChartOpt, data: barChartData }
|
||||
const barChart = new BarChart(newIchartOption, {}, chartInstance)
|
||||
// 获取生成的相应的barchart配置
|
||||
const barBaseOption = barChart.getOption()
|
||||
const barSeries = barBaseOption.series[0]
|
||||
barSeries.itemStyle.color = (params) => {
|
||||
const { dataIndex } = params
|
||||
const curTimeData = total[dataIndex]
|
||||
return curTimeData[0] > curTimeData[1] ? downStateColor : upStateColor
|
||||
}
|
||||
barSeries.xAxisIndex = 1
|
||||
barSeries.yAxisIndex = 1
|
||||
baseOpt.series.push(barSeries)
|
||||
}
|
||||
|
||||
function handleMaAndVolSeries(baseOpt, iChartOpt, inerData, { upStateColor, downStateColor }, chartInstance) {
|
||||
const { MA, volume, data } = iChartOpt
|
||||
const { total } = inerData
|
||||
const xAxisKey = xkey(iChartOpt)
|
||||
if (MA && MA.length !== 0) {
|
||||
handleMaSeries(baseOpt, iChartOpt, data, total, MA, xAxisKey, chartInstance)
|
||||
}
|
||||
if (volume) {
|
||||
handleVol(baseOpt, iChartOpt, data, xAxisKey, { upStateColor, downStateColor }, total, chartInstance)
|
||||
}
|
||||
}
|
||||
|
||||
export { handleSeries, handleMaSeries }
|
|
@ -0,0 +1,55 @@
|
|||
import init from '../../option/init'
|
||||
import { event } from '../../util/event'
|
||||
import RectCoordSys from '../../option/RectSys'
|
||||
import {
|
||||
handleData,
|
||||
handleAxis,
|
||||
handleDataZoom,
|
||||
handleTooltip,
|
||||
handleLegend,
|
||||
handleGrid,
|
||||
handleAxisPointer
|
||||
} from './hanleOption'
|
||||
import { handleSeries } from './hanleSeries'
|
||||
import { mergeSeries } from '../../util/merge'
|
||||
|
||||
class CandlestickChart {
|
||||
constructor(iChartOption, chartInstance) {
|
||||
this.baseOption = {}
|
||||
this.iChartOption = {}
|
||||
this.chartInstance = chartInstance
|
||||
// 组装 iChartOption, 补全默认值
|
||||
this.iChartOption = init(iChartOption)
|
||||
// 根据 iChartOption 组装 baseOption
|
||||
this.updateOption()
|
||||
}
|
||||
|
||||
updateOption() {
|
||||
const iChartOption = this.iChartOption
|
||||
const volume = this.iChartOption.volume
|
||||
const data = handleData(iChartOption)
|
||||
if (!data) return
|
||||
handleSeries(this.baseOption, iChartOption, data, this.chartInstance)
|
||||
RectCoordSys(this.baseOption, iChartOption)
|
||||
// 装载除series之外的其他配置
|
||||
handleGrid(this.baseOption, iChartOption)
|
||||
// 平均线和成交量,在这部分对ma和vol的图表进行处理
|
||||
handleAxis(this.baseOption, data, volume)
|
||||
handleTooltip(this.baseOption, iChartOption)
|
||||
handleDataZoom(this.baseOption, iChartOption)
|
||||
handleLegend(this.baseOption, iChartOption)
|
||||
handleAxisPointer(this.baseOption)
|
||||
event(this.chartInstance, iChartOption.event)
|
||||
mergeSeries(iChartOption, this.baseOption)
|
||||
}
|
||||
|
||||
getOption() {
|
||||
return this.baseOption
|
||||
}
|
||||
|
||||
setOption(option) {
|
||||
this.baseOption = option
|
||||
}
|
||||
}
|
||||
|
||||
export default CandlestickChart
|
|
@ -0,0 +1,18 @@
|
|||
import Theme from '../../feature/token'
|
||||
import proxy from '../../util/proxy'
|
||||
|
||||
function getChartToken() {
|
||||
const {
|
||||
itemStyle: { borderColor: colorBorder },
|
||||
label: { color: colorLabel }
|
||||
} = Theme.config.FunnelChart
|
||||
|
||||
return {
|
||||
labelColor: colorLabel,
|
||||
borderColor: colorBorder
|
||||
}
|
||||
}
|
||||
|
||||
const chartToken = proxy(getChartToken)
|
||||
|
||||
export default chartToken
|
|
@ -0,0 +1,37 @@
|
|||
import cloneDeep from '../../util/cloneDeep'
|
||||
|
||||
// 设置legend顺序
|
||||
export function setLegend(baseOption) {
|
||||
let dataUnit = cloneDeep(baseOption.series[0].data)
|
||||
let data = []
|
||||
let sort = []
|
||||
if (dataUnit !== undefined) {
|
||||
data = dataUnit
|
||||
sort = baseOption.series[0].sort
|
||||
}
|
||||
let legendData = sortData(sort, data)
|
||||
return legendData
|
||||
}
|
||||
|
||||
function sortData(sort, data) {
|
||||
let legendName = []
|
||||
// 升序
|
||||
if (sort === 'ascending') {
|
||||
const sortedData = [...data].sort((a, b) => {
|
||||
return a.value - b.value
|
||||
})
|
||||
sortedData.forEach((item) => {
|
||||
legendName.push(item.name)
|
||||
})
|
||||
}
|
||||
// 降序
|
||||
else {
|
||||
const sortedData = [...data].sort((a, b) => {
|
||||
return b.value - a.value
|
||||
})
|
||||
sortedData.forEach((item) => {
|
||||
legendName.push(item.name)
|
||||
})
|
||||
}
|
||||
return legendName
|
||||
}
|
|
@ -0,0 +1,141 @@
|
|||
import cloneDeep from '../../util/cloneDeep'
|
||||
import chartToken from './chartToken'
|
||||
|
||||
export const seriesInit = {
|
||||
type: 'funnel',
|
||||
width: '80%',
|
||||
min: 0,
|
||||
max: 100,
|
||||
minSize: '0%',
|
||||
maxSize: '100%',
|
||||
left: 'center',
|
||||
top: 60,
|
||||
bottom: 60,
|
||||
funnelAlign: 'center',
|
||||
orient: 'vertical',
|
||||
sort: 'descending',
|
||||
gap: 10,
|
||||
itemStyle: {
|
||||
borderColor: '',
|
||||
borderWidth: 1
|
||||
},
|
||||
label: {},
|
||||
data: []
|
||||
}
|
||||
|
||||
const SIZE_NAME = ['width', 'height', 'min', 'max', 'minSize', 'maxSize']
|
||||
const POSITION_NAME = ['left', 'right', 'top', 'bottom', 'funnelAlign', 'orient']
|
||||
|
||||
/**
|
||||
* 组装echarts所需要的series
|
||||
* @param {传入数据} iChartOption
|
||||
* @returns
|
||||
*/
|
||||
export function setSeries(iChartOption) {
|
||||
const { data, sort, size, position, gap } = iChartOption
|
||||
let series = []
|
||||
const selfSeries = iChartOption.series
|
||||
// 处理series里多个数据的优先级配置方法
|
||||
if (selfSeries !== undefined && selfSeries.length !== 0) {
|
||||
selfSeries.forEach((seriesItem) => {
|
||||
const seriesUnit = seriesItem
|
||||
// 处理size的优先级
|
||||
for (let index = 0; index < SIZE_NAME.length; index++) {
|
||||
const name = SIZE_NAME[index]
|
||||
if (seriesUnit[name] === undefined) {
|
||||
if (iChartOption.size && iChartOption.size[name]) {
|
||||
// 下面说明一级属性的赋值给series
|
||||
seriesUnit[name] = iChartOption.size[name]
|
||||
} else {
|
||||
// series的不存在size,把初始化的赋值给series
|
||||
seriesUnit[name] = seriesInit[name]
|
||||
}
|
||||
}
|
||||
}
|
||||
// 处理position的优先级
|
||||
for (let index = 0; index < POSITION_NAME.length; index++) {
|
||||
const name = POSITION_NAME[index]
|
||||
if (seriesUnit[name] === undefined) {
|
||||
if (iChartOption.position && iChartOption.position[name]) {
|
||||
// 下面说明一级属性的赋值给series
|
||||
seriesUnit[name] = iChartOption.position[name]
|
||||
} else {
|
||||
// series的不存在position,把初始化的赋值给series
|
||||
seriesUnit[name] = seriesInit[name]
|
||||
}
|
||||
}
|
||||
}
|
||||
// 处理label
|
||||
const defaultLabel = {
|
||||
show: true,
|
||||
color: chartToken.labelColor
|
||||
}
|
||||
seriesUnit.label = Object.assign(defaultLabel, seriesUnit.label)
|
||||
// 处理gap、sort的优先级
|
||||
const config = ['gap', 'sort']
|
||||
for (let index = 0; index < config.length; index++) {
|
||||
const name = config[index]
|
||||
if (seriesUnit[name] === undefined) {
|
||||
if (iChartOption && iChartOption[name]) {
|
||||
// 把一级属性值赋给series
|
||||
seriesUnit[name] = iChartOption[name]
|
||||
} else {
|
||||
// 把初始化的赋值给series
|
||||
seriesUnit[name] = seriesInit[name]
|
||||
}
|
||||
}
|
||||
}
|
||||
// 处理图形边框颜色
|
||||
const defaultItemStyle = {
|
||||
borderColor: chartToken.borderColor,
|
||||
borderWidth: 1
|
||||
}
|
||||
seriesUnit.itemStyle = Object.assign(defaultItemStyle, seriesUnit.itemStyle)
|
||||
})
|
||||
series = selfSeries
|
||||
} else {
|
||||
// 处理单个数据的默认配置
|
||||
const seriesUnit = cloneDeep(seriesInit)
|
||||
data && (seriesUnit.data = data)
|
||||
// 配置项变成一级属性,处理sort和gap
|
||||
sort && (seriesUnit.sort = sort)
|
||||
gap && (seriesUnit.gap = gap)
|
||||
// 配置漏斗图的label
|
||||
setLabel(seriesUnit, iChartOption)
|
||||
// 处理漏斗图的size和position
|
||||
setSize(size, seriesUnit)
|
||||
setPosition(position, seriesUnit)
|
||||
// 处理图形边框颜色
|
||||
seriesUnit.itemStyle.borderColor = chartToken.borderColor
|
||||
series.push(seriesUnit)
|
||||
}
|
||||
return series
|
||||
}
|
||||
|
||||
// 处理漏斗图的大小
|
||||
function setSize(size, seriesUnit) {
|
||||
for (let index = 0; index < SIZE_NAME.length; index++) {
|
||||
const name = SIZE_NAME[index]
|
||||
if (size !== undefined && size[name] !== undefined) {
|
||||
seriesUnit[name] = size[name]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 处理漏斗图的位置
|
||||
function setPosition(position, seriesUnit) {
|
||||
for (let index = 0; index < POSITION_NAME.length; index++) {
|
||||
const name = POSITION_NAME[index]
|
||||
if (position !== undefined && position[name] !== undefined) {
|
||||
seriesUnit[name] = position[name]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 设置label的属性主要是formatter
|
||||
function setLabel(seriesUnit, iChartOption) {
|
||||
seriesUnit.label.color = chartToken.labelColor
|
||||
seriesUnit.label.position = 'inside'
|
||||
seriesUnit.label.show = true
|
||||
Object.assign(seriesUnit.label, iChartOption.label)
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
import init from '../../option/init'
|
||||
import { event } from '../../util/event'
|
||||
import { setLegend } from './handleLegend.js'
|
||||
import { setSeries } from './handleSeries.js'
|
||||
import PolarCoordSys from '../../option/PolarSys'
|
||||
|
||||
const CHART_NAME = 'FunnelChart'
|
||||
|
||||
export default class FunnelChart {
|
||||
constructor(iChartOption, chartInstance) {
|
||||
this.baseOption = {}
|
||||
this.iChartOption = {}
|
||||
// 组装 iChartOption, 补全默认值
|
||||
this.iChartOption = init(iChartOption)
|
||||
// 根据 iChartOption 组装 baseOption
|
||||
this.updateOption(chartInstance)
|
||||
}
|
||||
|
||||
updateOption(chartInstance) {
|
||||
const iChartOption = this.iChartOption
|
||||
// 装载除series之外的其他配置
|
||||
PolarCoordSys(this.baseOption, iChartOption, CHART_NAME)
|
||||
// 组装series
|
||||
this.baseOption.series = setSeries(iChartOption)
|
||||
// 组装legend.data
|
||||
// eslint-disable-next-line no-unused-expressions
|
||||
this.baseOption.legend.data ? this.baseOption.legend.data : setLegend(this.baseOption)
|
||||
// 配置图表事件
|
||||
if (iChartOption.event) {
|
||||
event(chartInstance, iChartOption.event)
|
||||
}
|
||||
}
|
||||
|
||||
getOption() {
|
||||
return this.baseOption
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
import BaseOption from '../../option/base'
|
||||
|
||||
BaseOption.series = []
|
||||
BaseOption.tooltip = {
|
||||
show: true,
|
||||
trigger: 'item',
|
||||
formatter: '{b}: {c} ({d}%)'
|
||||
}
|
||||
BaseOption.legend = {}
|
||||
|
||||
export default BaseOption
|
|
@ -0,0 +1,31 @@
|
|||
import Theme from '../../feature/token'
|
||||
import proxy from '../../util/proxy'
|
||||
|
||||
function getChartToken() {
|
||||
const {
|
||||
axisLine: {
|
||||
lineStyle: { color: colorAxisLine }
|
||||
},
|
||||
splitLine: {
|
||||
lineStyle: { color: colorAxisSplitLine }
|
||||
},
|
||||
axisLabel: { color: colorTextSecondary },
|
||||
detail: {
|
||||
rich: { color: colorTextPrimary }
|
||||
}
|
||||
} = Theme.config.GaugeChart
|
||||
|
||||
const { colorState } = Theme.config
|
||||
|
||||
return {
|
||||
marklineColor: colorState.colorError,
|
||||
axisLineColor: colorAxisLine,
|
||||
splitLineColor: colorAxisSplitLine,
|
||||
axisLabelColor: colorTextSecondary,
|
||||
detailRichColor: colorTextPrimary
|
||||
}
|
||||
}
|
||||
|
||||
const chartToken = proxy(getChartToken)
|
||||
|
||||
export default chartToken
|
|
@ -0,0 +1,9 @@
|
|||
import tooltip from '../../option/config/tooltip'
|
||||
|
||||
/**
|
||||
* 配置鼠标悬浮提示框
|
||||
*/
|
||||
export function handleTooltip(iChartOpt, chartName) {
|
||||
const basicTip = tooltip(iChartOpt, chartName)
|
||||
return basicTip
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue