@363045841yyt/klinechart 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +48 -0
- package/dist/App.vue.d.ts +2 -0
- package/dist/api/data/kLine.d.ts +11 -0
- package/dist/components/KLineChart.vue.d.ts +33 -0
- package/dist/components/index.d.ts +2 -0
- package/dist/favicon.ico +0 -0
- package/dist/index.cjs +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +149 -0
- package/dist/klinechart.css +2 -0
- package/dist/main.d.ts +0 -0
- package/dist/stores/counter.d.ts +13 -0
- package/dist/types/kLine.d.ts +3 -0
- package/dist/types/price.d.ts +17 -0
- package/dist/utils/draw/MA.d.ts +5 -0
- package/dist/utils/draw/kLine.d.ts +16 -0
- package/dist/utils/logger.d.ts +3 -0
- package/dist/utils/mock/genRandomPriceData.d.ts +3 -0
- package/dist/utils/priceToY.d.ts +1 -0
- package/package.json +56 -0
package/README.md
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# kmap
|
|
2
|
+
|
|
3
|
+
This template should help get you started developing with Vue 3 in Vite.
|
|
4
|
+
|
|
5
|
+
## Recommended IDE Setup
|
|
6
|
+
|
|
7
|
+
[VS Code](https://code.visualstudio.com/) + [Vue (Official)](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur).
|
|
8
|
+
|
|
9
|
+
## Recommended Browser Setup
|
|
10
|
+
|
|
11
|
+
- Chromium-based browsers (Chrome, Edge, Brave, etc.):
|
|
12
|
+
- [Vue.js devtools](https://chromewebstore.google.com/detail/vuejs-devtools/nhdogjmejiglipccpnnnanhbledajbpd)
|
|
13
|
+
- [Turn on Custom Object Formatter in Chrome DevTools](http://bit.ly/object-formatters)
|
|
14
|
+
- Firefox:
|
|
15
|
+
- [Vue.js devtools](https://addons.mozilla.org/en-US/firefox/addon/vue-js-devtools/)
|
|
16
|
+
- [Turn on Custom Object Formatter in Firefox DevTools](https://fxdx.dev/firefox-devtools-custom-object-formatters/)
|
|
17
|
+
|
|
18
|
+
## Type Support for `.vue` Imports in TS
|
|
19
|
+
|
|
20
|
+
TypeScript cannot handle type information for `.vue` imports by default, so we replace the `tsc` CLI with `vue-tsc` for type checking. In editors, we need [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) to make the TypeScript language service aware of `.vue` types.
|
|
21
|
+
|
|
22
|
+
## Customize configuration
|
|
23
|
+
|
|
24
|
+
See [Vite Configuration Reference](https://vite.dev/config/).
|
|
25
|
+
|
|
26
|
+
## Project Setup
|
|
27
|
+
|
|
28
|
+
```sh
|
|
29
|
+
pnpm install
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
### Compile and Hot-Reload for Development
|
|
33
|
+
|
|
34
|
+
```sh
|
|
35
|
+
pnpm dev
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
### Type-Check, Compile and Minify for Production
|
|
39
|
+
|
|
40
|
+
```sh
|
|
41
|
+
pnpm build
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
### Run Unit Tests with [Vitest](https://vitest.dev/)
|
|
45
|
+
|
|
46
|
+
```sh
|
|
47
|
+
pnpm test:unit
|
|
48
|
+
```
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
declare const _default: import('vue').DefineComponent<{}, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, true, {}, HTMLDivElement>;
|
|
2
|
+
export default _default;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { KLineDailyDongCaiResponse } from '../../types/price';
|
|
2
|
+
interface KLineDailyDongCaiRequest {
|
|
3
|
+
symbol: string;
|
|
4
|
+
period: 'daily' | 'weekly' | 'monthly';
|
|
5
|
+
start_date: string;
|
|
6
|
+
end_date: string;
|
|
7
|
+
adjust?: 'qfq' | 'hfq';
|
|
8
|
+
timeout?: number;
|
|
9
|
+
}
|
|
10
|
+
export declare function getKlineDataDongCai(param: KLineDailyDongCaiRequest): Promise<KLineDailyDongCaiResponse[]>;
|
|
11
|
+
export type { KLineDailyDongCaiResponse };
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { KLineData } from '../types/price';
|
|
2
|
+
type MAFlags = {
|
|
3
|
+
ma5?: boolean;
|
|
4
|
+
ma10?: boolean;
|
|
5
|
+
ma20?: boolean;
|
|
6
|
+
};
|
|
7
|
+
type __VLS_Props = {
|
|
8
|
+
data: KLineData[];
|
|
9
|
+
kWidth?: number;
|
|
10
|
+
kGap?: number;
|
|
11
|
+
yPaddingPx?: number;
|
|
12
|
+
showMA?: MAFlags;
|
|
13
|
+
autoScrollToRight?: boolean;
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* rAF 节流:scroll/resize/data变化都用它触发
|
|
17
|
+
*/
|
|
18
|
+
declare function scheduleRender(): void;
|
|
19
|
+
declare function scrollToRight(): void;
|
|
20
|
+
declare const _default: import('vue').DefineComponent<__VLS_Props, {
|
|
21
|
+
scheduleRender: typeof scheduleRender;
|
|
22
|
+
scrollToRight: typeof scrollToRight;
|
|
23
|
+
}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
|
|
24
|
+
kWidth: number;
|
|
25
|
+
kGap: number;
|
|
26
|
+
yPaddingPx: number;
|
|
27
|
+
showMA: MAFlags;
|
|
28
|
+
autoScrollToRight: boolean;
|
|
29
|
+
}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {
|
|
30
|
+
containerRef: HTMLDivElement;
|
|
31
|
+
canvasRef: HTMLCanvasElement;
|
|
32
|
+
}, HTMLDivElement>;
|
|
33
|
+
export default _default;
|
package/dist/favicon.ico
ADDED
|
Binary file
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});let e=require(`vue`);function t(e){return e.open>e.close?`down`:e.open<e.close?`up`:`flat`}function n(e,t,n,r,i,a){let o=t-n||1,s=(e-n)/o;return i+Math.max(1,r-i-a)*(1-s)}var r={info:`background:#1677ff;color:#fff;border:1px solid #1677ff;`,success:`background:#389e0d;color:#fff;border:1px solid #389e0d;`,warn:`background:#d46b08;color:#fff;border:1px solid #d46b08;`,error:`background:#cf1322;color:#fff;border:1px solid #cf1322;`},i=`padding:4px 8px;font-weight:600;border-radius:6px;`,a=`padding:4px 10px;border:1px solid #d9d9d9;background:#fff;color:#111;border-radius:6px;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;`;function o(e,t,n){console.log(`%c${t}%c`,`${i}${r[e]}`,a,n)}var s=`rgba(214, 10, 34, 1)`,c=`rgba(3, 123, 102, 1)`;function l(e,r,i,a,l=1){if(o(`info`,`kLineDraw`,r),r.length===0)return;let u=a,d=i.yPaddingPx??0,f=Math.max(0,Math.min(d,Math.floor(u/2)-1)),p=f,m=f,h=r.reduce((e,t)=>Math.max(e,t.high),-1/0),g=r.reduce((e,t)=>Math.min(e,t.low),1/0);e.lineWidth=1/l;let _=i.kGap;for(let a=0;a<r.length;a++){let o=r[a];if(!o)continue;let d=n(o.high,h,g,u,p,m),f=n(o.low,h,g,u,p,m),v=n(o.open,h,g,u,p,m),y=n(o.close,h,g,u,p,m),b=Math.min(v,y),x=Math.max(Math.abs(v-y),2/l),S=t(o)===`up`?s:c;e.fillStyle=S,e.fillRect(_,b,i.kWidth,x),e.strokeStyle=S,e.lineWidth=3/l;let C=_+i.kWidth/2;e.beginPath(),e.moveTo(C,d),e.lineTo(C,b),e.stroke(),e.beginPath(),e.moveTo(C,b+x),e.lineTo(C,f),e.stroke(),_+=i.kWidth+i.kGap}}function u(e,t){let n=[...e].sort((e,t)=>e.timestamp-t.timestamp),r=n.length;if(t<=0)throw Error(`x must be > 0`);if(r<t)return[];let i=0;for(let e=0;e<t;e++)i+=n[e].close;let a=Array(r-t+1);a[0]=i/t;for(let e=t;e<r;e++)i+=n[e].close-n[e-t].close,a[e-t+1]=i/t;return a}function d(e,t,r,i,a,o,s=1){if(t.length===0)return;let c=[...t].sort((e,t)=>e.timestamp-t.timestamp),l=u(c,a);if(l.length===0)return;let d=i,f=r.yPaddingPx??0,p=Math.max(0,Math.min(f,Math.floor(d/2)-1)),m=p,h=p,g=c.reduce((e,t)=>Math.max(e,t.high),-1/0),_=c.reduce((e,t)=>Math.min(e,t.low),1/0);if(!Number.isFinite(g)||!Number.isFinite(_)||g<=_)return;let v=Array(l.length);for(let e=0;e<l.length;e++)v[e]=n(l[e],g,_,d,m,h);e.strokeStyle=o,e.lineWidth=2/s,e.beginPath();let y=!1;for(let t=0;t<v.length;t++){let n=v[t];if(!Number.isFinite(n))continue;let i=t+(a-1),o=r.kGap+i*(r.kWidth+r.kGap)+r.kWidth/2;y?e.lineTo(o,n):(e.moveTo(o,n),y=!0)}y&&e.stroke()}function f(e,t,n,r,i=1){d(e,t,n,r,10,`rgba(190, 131, 12, 1)`,i)}function p(e,t,n,r,i=1){d(e,t,n,r,20,`rgba(69, 112, 249, 1)`,i)}function m(e,t,n,r,i=1){d(e,t,n,r,5,`rgba(251, 186, 62, 1)`,i)}var h=(0,e.defineComponent)({__name:`KLineChart`,props:{data:{},kWidth:{default:10},kGap:{default:2},yPaddingPx:{default:60},showMA:{default:()=>({ma5:!0,ma10:!0,ma20:!0})},autoScrollToRight:{type:Boolean,default:!0}},setup(t,{expose:n}){let r=t,i=(0,e.ref)(null),a=(0,e.ref)(null),o=null;function s(){return{kWidth:r.kWidth,kGap:r.kGap,yPaddingPx:r.yPaddingPx}}function c(){let e=i.value,t=a.value;if(!e||!t||!r.data||r.data.length===0)return;let n=e.getContext(`2d`);if(!n)return;let o=r.data,c=t.getBoundingClientRect(),u=Math.max(1,Math.round(c.width)),d=Math.max(1,Math.round(c.height)),h=window.devicePixelRatio||1,g=s(),_=o.length,v=Math.max(u,g.kGap+_*(g.kWidth+g.kGap));e.style.width=`${v}px`,e.style.height=`${d}px`,e.width=Math.round(v*h),e.height=Math.round(d*h);let y=t.scrollLeft;n.setTransform(1,0,0,1,0,0),n.scale(h,h),n.clearRect(0,0,v,d),n.translate(-y,0),l(n,o,g,d,h),r.showMA.ma5&&m(n,o,g,d,h),r.showMA.ma10&&f(n,o,g,d,h),r.showMA.ma20&&p(n,o,g,d,h)}function u(){o!==null&&cancelAnimationFrame(o),o=requestAnimationFrame(()=>{o=null,c()})}function d(){let e=a.value;e&&(e.scrollLeft=e.scrollWidth,u())}return n({scheduleRender:u,scrollToRight:d}),(0,e.onMounted)(()=>{window.addEventListener(`resize`,u,{passive:!0}),u()}),(0,e.onUnmounted)(()=>{window.removeEventListener(`resize`,u),o!==null&&cancelAnimationFrame(o)}),(0,e.watch)(()=>[r.data,r.kWidth,r.kGap,r.yPaddingPx,r.showMA],async()=>{r.autoScrollToRight?(await(0,e.nextTick)(),d()):u()},{deep:!0}),(t,n)=>((0,e.openBlock)(),(0,e.createElementBlock)(`div`,{class:`chart-container`,ref_key:`containerRef`,ref:a,onScrollPassive:u},[(0,e.createElementVNode)(`canvas`,{ref_key:`canvasRef`,ref:i,class:`chart-canvas`},null,512)],544))}}),g=(e,t)=>{let n=e.__vccOpts||e;for(let[e,r]of t)n[e]=r;return n},_=g(h,[[`__scopeId`,`data-v-7f0057f3`]]);const v=_,y={install(e){e.component(`KLineChart`,v)}};exports.KLineChart=v,exports.KMapPlugin=y;
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import { createElementBlock, createElementVNode, defineComponent, nextTick, onMounted, onUnmounted, openBlock, ref, watch } from "vue";
|
|
2
|
+
function getKLineTrend(e) {
|
|
3
|
+
return e.open > e.close ? "down" : e.open < e.close ? "up" : "flat";
|
|
4
|
+
}
|
|
5
|
+
function priceToY(e, n, r, i, a, o) {
|
|
6
|
+
let s = n - r || 1, c = (e - r) / s;
|
|
7
|
+
return a + Math.max(1, i - a - o) * (1 - c);
|
|
8
|
+
}
|
|
9
|
+
var tagStyle = {
|
|
10
|
+
info: "background:#1677ff;color:#fff;border:1px solid #1677ff;",
|
|
11
|
+
success: "background:#389e0d;color:#fff;border:1px solid #389e0d;",
|
|
12
|
+
warn: "background:#d46b08;color:#fff;border:1px solid #d46b08;",
|
|
13
|
+
error: "background:#cf1322;color:#fff;border:1px solid #cf1322;"
|
|
14
|
+
}, leftBase = "padding:4px 8px;font-weight:600;border-radius:6px;", rightBase = "padding:4px 10px;border:1px solid #d9d9d9;background:#fff;color:#111;border-radius:6px;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,\"Liberation Mono\",\"Courier New\",monospace;";
|
|
15
|
+
function tagLog(e, n, r) {
|
|
16
|
+
console.log(`%c${n}%c`, `${leftBase}${tagStyle[e]}`, rightBase, r);
|
|
17
|
+
}
|
|
18
|
+
var UP_COLOR = "rgba(214, 10, 34, 1)", DOWN_COLOR = "rgba(3, 123, 102, 1)";
|
|
19
|
+
function kLineDraw(e, n, r, i, a = 1) {
|
|
20
|
+
if (tagLog("info", "kLineDraw", n), n.length === 0) return;
|
|
21
|
+
let o = i, s = r.yPaddingPx ?? 0, c = Math.max(0, Math.min(s, Math.floor(o / 2) - 1)), l = c, f = c, p = n.reduce((e, n) => Math.max(e, n.high), -Infinity), m = n.reduce((e, n) => Math.min(e, n.low), Infinity);
|
|
22
|
+
e.lineWidth = 1 / a;
|
|
23
|
+
let v = r.kGap;
|
|
24
|
+
for (let i = 0; i < n.length; i++) {
|
|
25
|
+
let s = n[i];
|
|
26
|
+
if (!s) continue;
|
|
27
|
+
let c = priceToY(s.high, p, m, o, l, f), h = priceToY(s.low, p, m, o, l, f), y = priceToY(s.open, p, m, o, l, f), b = priceToY(s.close, p, m, o, l, f), x = Math.min(y, b), S = Math.max(Math.abs(y - b), 2 / a), C = getKLineTrend(s) === "up" ? UP_COLOR : DOWN_COLOR;
|
|
28
|
+
e.fillStyle = C, e.fillRect(v, x, r.kWidth, S), e.strokeStyle = C, e.lineWidth = 3 / a;
|
|
29
|
+
let w = v + r.kWidth / 2;
|
|
30
|
+
e.beginPath(), e.moveTo(w, c), e.lineTo(w, x), e.stroke(), e.beginPath(), e.moveTo(w, x + S), e.lineTo(w, h), e.stroke(), v += r.kWidth + r.kGap;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
function calcMAx(e, n) {
|
|
34
|
+
let r = [...e].sort((e, n) => e.timestamp - n.timestamp), i = r.length;
|
|
35
|
+
if (n <= 0) throw Error("x must be > 0");
|
|
36
|
+
if (i < n) return [];
|
|
37
|
+
let a = 0;
|
|
38
|
+
for (let e = 0; e < n; e++) a += r[e].close;
|
|
39
|
+
let o = Array(i - n + 1);
|
|
40
|
+
o[0] = a / n;
|
|
41
|
+
for (let e = n; e < i; e++) a += r[e].close - r[e - n].close, o[e - n + 1] = a / n;
|
|
42
|
+
return o;
|
|
43
|
+
}
|
|
44
|
+
function drawMALine(e, n, r, i, a, o, s = 1) {
|
|
45
|
+
if (n.length === 0) return;
|
|
46
|
+
let c = [...n].sort((e, n) => e.timestamp - n.timestamp), l = calcMAx(c, a);
|
|
47
|
+
if (l.length === 0) return;
|
|
48
|
+
let u = i, f = r.yPaddingPx ?? 0, p = Math.max(0, Math.min(f, Math.floor(u / 2) - 1)), m = p, h = p, g = c.reduce((e, n) => Math.max(e, n.high), -Infinity), _ = c.reduce((e, n) => Math.min(e, n.low), Infinity);
|
|
49
|
+
if (!Number.isFinite(g) || !Number.isFinite(_) || g <= _) return;
|
|
50
|
+
let v = Array(l.length);
|
|
51
|
+
for (let e = 0; e < l.length; e++) v[e] = priceToY(l[e], g, _, u, m, h);
|
|
52
|
+
e.strokeStyle = o, e.lineWidth = 2 / s, e.beginPath();
|
|
53
|
+
let b = !1;
|
|
54
|
+
for (let n = 0; n < v.length; n++) {
|
|
55
|
+
let i = v[n];
|
|
56
|
+
if (!Number.isFinite(i)) continue;
|
|
57
|
+
let o = n + (a - 1), s = r.kGap + o * (r.kWidth + r.kGap) + r.kWidth / 2;
|
|
58
|
+
b ? e.lineTo(s, i) : (e.moveTo(s, i), b = !0);
|
|
59
|
+
}
|
|
60
|
+
b && e.stroke();
|
|
61
|
+
}
|
|
62
|
+
function drawMA10Line(e, n, r, i, a = 1) {
|
|
63
|
+
drawMALine(e, n, r, i, 10, "rgba(190, 131, 12, 1)", a);
|
|
64
|
+
}
|
|
65
|
+
function drawMA20Line(e, n, r, i, a = 1) {
|
|
66
|
+
drawMALine(e, n, r, i, 20, "rgba(69, 112, 249, 1)", a);
|
|
67
|
+
}
|
|
68
|
+
function drawMA5Line(e, n, r, i, a = 1) {
|
|
69
|
+
drawMALine(e, n, r, i, 5, "rgba(251, 186, 62, 1)", a);
|
|
70
|
+
}
|
|
71
|
+
const KLineChart = /* @__PURE__ */ ((e, n) => {
|
|
72
|
+
let r = e.__vccOpts || e;
|
|
73
|
+
for (let [e, i] of n) r[e] = i;
|
|
74
|
+
return r;
|
|
75
|
+
})(/* @__PURE__ */ defineComponent({
|
|
76
|
+
__name: "KLineChart",
|
|
77
|
+
props: {
|
|
78
|
+
data: {},
|
|
79
|
+
kWidth: { default: 10 },
|
|
80
|
+
kGap: { default: 2 },
|
|
81
|
+
yPaddingPx: { default: 60 },
|
|
82
|
+
showMA: { default: () => ({
|
|
83
|
+
ma5: !0,
|
|
84
|
+
ma10: !0,
|
|
85
|
+
ma20: !0
|
|
86
|
+
}) },
|
|
87
|
+
autoScrollToRight: {
|
|
88
|
+
type: Boolean,
|
|
89
|
+
default: !0
|
|
90
|
+
}
|
|
91
|
+
},
|
|
92
|
+
setup(r, { expose: u }) {
|
|
93
|
+
let d = r, f = ref(null), p = ref(null), m = null;
|
|
94
|
+
function h() {
|
|
95
|
+
return {
|
|
96
|
+
kWidth: d.kWidth,
|
|
97
|
+
kGap: d.kGap,
|
|
98
|
+
yPaddingPx: d.yPaddingPx
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
function g() {
|
|
102
|
+
let e = f.value, n = p.value;
|
|
103
|
+
if (!e || !n || !d.data || d.data.length === 0) return;
|
|
104
|
+
let r = e.getContext("2d");
|
|
105
|
+
if (!r) return;
|
|
106
|
+
let i = d.data, a = n.getBoundingClientRect(), o = Math.max(1, Math.round(a.width)), s = Math.max(1, Math.round(a.height)), c = window.devicePixelRatio || 1, l = h(), u = i.length, m = Math.max(o, l.kGap + u * (l.kWidth + l.kGap));
|
|
107
|
+
e.style.width = `${m}px`, e.style.height = `${s}px`, e.width = Math.round(m * c), e.height = Math.round(s * c);
|
|
108
|
+
let g = n.scrollLeft;
|
|
109
|
+
r.setTransform(1, 0, 0, 1, 0, 0), r.scale(c, c), r.clearRect(0, 0, m, s), r.translate(-g, 0), kLineDraw(r, i, l, s, c), d.showMA.ma5 && drawMA5Line(r, i, l, s, c), d.showMA.ma10 && drawMA10Line(r, i, l, s, c), d.showMA.ma20 && drawMA20Line(r, i, l, s, c);
|
|
110
|
+
}
|
|
111
|
+
function _() {
|
|
112
|
+
m !== null && cancelAnimationFrame(m), m = requestAnimationFrame(() => {
|
|
113
|
+
m = null, g();
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
function y() {
|
|
117
|
+
let e = p.value;
|
|
118
|
+
e && (e.scrollLeft = e.scrollWidth, _());
|
|
119
|
+
}
|
|
120
|
+
return u({
|
|
121
|
+
scheduleRender: _,
|
|
122
|
+
scrollToRight: y
|
|
123
|
+
}), onMounted(() => {
|
|
124
|
+
window.addEventListener("resize", _, { passive: !0 }), _();
|
|
125
|
+
}), onUnmounted(() => {
|
|
126
|
+
window.removeEventListener("resize", _), m !== null && cancelAnimationFrame(m);
|
|
127
|
+
}), watch(() => [
|
|
128
|
+
d.data,
|
|
129
|
+
d.kWidth,
|
|
130
|
+
d.kGap,
|
|
131
|
+
d.yPaddingPx,
|
|
132
|
+
d.showMA
|
|
133
|
+
], async () => {
|
|
134
|
+
d.autoScrollToRight ? (await nextTick(), y()) : _();
|
|
135
|
+
}, { deep: !0 }), (r, i) => (openBlock(), createElementBlock("div", {
|
|
136
|
+
class: "chart-container",
|
|
137
|
+
ref_key: "containerRef",
|
|
138
|
+
ref: p,
|
|
139
|
+
onScrollPassive: _
|
|
140
|
+
}, [createElementVNode("canvas", {
|
|
141
|
+
ref_key: "canvasRef",
|
|
142
|
+
ref: f,
|
|
143
|
+
class: "chart-canvas"
|
|
144
|
+
}, null, 512)], 544));
|
|
145
|
+
}
|
|
146
|
+
}), [["__scopeId", "data-v-7f0057f3"]]), KMapPlugin = { install(e) {
|
|
147
|
+
e.component("KLineChart", KLineChart);
|
|
148
|
+
} };
|
|
149
|
+
export { KLineChart, KMapPlugin };
|
package/dist/main.d.ts
ADDED
|
File without changes
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export declare const useCounterStore: import('pinia').StoreDefinition<"counter", Pick<{
|
|
2
|
+
count: import('vue').Ref<number, number>;
|
|
3
|
+
doubleCount: import('vue').ComputedRef<number>;
|
|
4
|
+
increment: () => void;
|
|
5
|
+
}, "count">, Pick<{
|
|
6
|
+
count: import('vue').Ref<number, number>;
|
|
7
|
+
doubleCount: import('vue').ComputedRef<number>;
|
|
8
|
+
increment: () => void;
|
|
9
|
+
}, "doubleCount">, Pick<{
|
|
10
|
+
count: import('vue').Ref<number, number>;
|
|
11
|
+
doubleCount: import('vue').ComputedRef<number>;
|
|
12
|
+
increment: () => void;
|
|
13
|
+
}, "increment">>;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export interface KLineData {
|
|
2
|
+
timestamp: number;
|
|
3
|
+
open: number;
|
|
4
|
+
high: number;
|
|
5
|
+
low: number;
|
|
6
|
+
close: number;
|
|
7
|
+
}
|
|
8
|
+
export interface KLineDailyDongCaiResponse extends KLineData {
|
|
9
|
+
stockCode: string;
|
|
10
|
+
volume: number;
|
|
11
|
+
turnover: number;
|
|
12
|
+
amplitude: number;
|
|
13
|
+
changePercent: number;
|
|
14
|
+
changeAmount: number;
|
|
15
|
+
turnoverRate: number;
|
|
16
|
+
}
|
|
17
|
+
export declare function toKLineData(arr: KLineDailyDongCaiResponse[]): KLineData[];
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { KLineData } from '../../types/price';
|
|
2
|
+
import { drawOption } from './kLine';
|
|
3
|
+
export declare function drawMA10Line(ctx: CanvasRenderingContext2D, data: KLineData[], option: drawOption, logicHeight: number, dpr?: number): void;
|
|
4
|
+
export declare function drawMA20Line(ctx: CanvasRenderingContext2D, data: KLineData[], option: drawOption, logicHeight: number, dpr?: number): void;
|
|
5
|
+
export declare function drawMA5Line(ctx: CanvasRenderingContext2D, data: KLineData[], option: drawOption, logicHeight: number, dpr?: number): void;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { KLineData } from '../../types/price';
|
|
2
|
+
export interface drawOption {
|
|
3
|
+
kWidth: number;
|
|
4
|
+
kGap: number;
|
|
5
|
+
yPaddingPx?: number;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* K 线图绘制
|
|
9
|
+
* @param ctx
|
|
10
|
+
* @param data
|
|
11
|
+
* @param option
|
|
12
|
+
* @param logicHeight
|
|
13
|
+
* @param dpr
|
|
14
|
+
* @returns
|
|
15
|
+
*/
|
|
16
|
+
export declare function kLineDraw(ctx: CanvasRenderingContext2D, data: KLineData[], option: drawOption, logicHeight: number, dpr?: number): void;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function priceToY(price: number, maxPrice: number, minPrice: number, canvasHeight: number, paddingTop: number, paddingBottom: number): number;
|
package/package.json
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@363045841yyt/klinechart",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"engines": {
|
|
6
|
+
"node": "^20.19.0 || >=22.12.0"
|
|
7
|
+
},
|
|
8
|
+
"scripts": {
|
|
9
|
+
"dev": "vite",
|
|
10
|
+
"build": "run-p type-check \"build-only {@}\" --",
|
|
11
|
+
"build-only": "vite build",
|
|
12
|
+
"preview": "vite preview",
|
|
13
|
+
"type-check": "vue-tsc --build",
|
|
14
|
+
"test:unit": "vitest",
|
|
15
|
+
"format": "prettier --write --experimental-cli src/",
|
|
16
|
+
"prepublishOnly": "pnpm run build-only"
|
|
17
|
+
},
|
|
18
|
+
"main": "./dist/index.cjs",
|
|
19
|
+
"module": "./dist/index.js",
|
|
20
|
+
"types": "./dist/index.d.ts",
|
|
21
|
+
"exports": {
|
|
22
|
+
".": {
|
|
23
|
+
"types": "./dist/index.d.ts",
|
|
24
|
+
"import": "./dist/index.js",
|
|
25
|
+
"require": "./dist/index.cjs"
|
|
26
|
+
},
|
|
27
|
+
"./style.css": "./dist/kmap.css"
|
|
28
|
+
},
|
|
29
|
+
"files": [
|
|
30
|
+
"dist"
|
|
31
|
+
],
|
|
32
|
+
"peerDependencies": {
|
|
33
|
+
"vue": "^3.5.0"
|
|
34
|
+
},
|
|
35
|
+
"dependencies": {
|
|
36
|
+
"axios": "^1.13.2",
|
|
37
|
+
"pinia": "^3.0.4"
|
|
38
|
+
},
|
|
39
|
+
"devDependencies": {
|
|
40
|
+
"@tsconfig/node24": "^24.0.3",
|
|
41
|
+
"@types/jsdom": "^27.0.0",
|
|
42
|
+
"@types/node": "^24.10.4",
|
|
43
|
+
"@vitejs/plugin-vue": "^6.0.3",
|
|
44
|
+
"@vue/test-utils": "^2.4.6",
|
|
45
|
+
"@vue/tsconfig": "^0.8.1",
|
|
46
|
+
"jsdom": "^27.4.0",
|
|
47
|
+
"npm-run-all2": "^8.0.4",
|
|
48
|
+
"prettier": "3.7.4",
|
|
49
|
+
"typescript": "~5.9.3",
|
|
50
|
+
"vite": "npm:rolldown-vite@^7.3.0",
|
|
51
|
+
"vite-plugin-dts": "^4.5.4",
|
|
52
|
+
"vite-plugin-vue-devtools": "^8.0.5",
|
|
53
|
+
"vitest": "^4.0.16",
|
|
54
|
+
"vue-tsc": "^3.2.1"
|
|
55
|
+
}
|
|
56
|
+
}
|