openalgo-charts
Version:
From-scratch, dependency-free canvas charting engine for OpenAlgo: professional-grade interactive rendering, advanced on-chart trading, and a one-call widget tier that adds the toolbar, drawing rail, dialogs and shortcuts.
3 lines (2 loc) • 10.2 kB
JavaScript
import{chromeIconSvg as e}from"./openalgo-charts.draw.mjs";import{widgetText as n,a as o,h as t,CHART_GRID_LAYOUTS as a,c as r,l as i,r as c,i as d,g as l}from"./openalgo-charts.widget.mjs";import{chrome as s,layoutTileSvg as p}from"./openalgo-charts.widget.grid-bar-Cm_CyA2j.mjs";import"./openalgo-charts.mjs";const u=e=>e.text;let h=0;const g={crosshair:e("crosshair"),viewport:e("time-range"),symbol:e("search"),interval:e("clock"),chartType:e("chart-candlestick"),appearance:e("palette"),drawings:e("drawing-sync")},m={crosshair:"Crosshair",viewport:"Time range",symbol:"Symbol",interval:"Interval",chartType:"Chart type",appearance:"Appearance",drawings:"Drawings"};function _(n,a,r,i,d,l){const s=n.doc;o(s,v);const p=t(s,"div","oac-menu oac-grid__menu",{role:"menu","aria-label":r}),u="oac-grid-note-"+ ++h;let g=()=>{};const m=(n=-1)=>{p.textContent="";let o=0;for(const n of i()){if("string"==typeof n){const e=t(s,"div","oac-head",{role:"presentation"});e.textContent=n,p.appendChild(e);continue}const a=t(s,"button","oac-menu__row",{type:"button",role:"radio"===n.kind?"menuitemradio":"check"===n.kind?"menuitemcheckbox":"menuitem","aria-disabled":String(!0===n.disabled)});if("action"!==n.kind&&a.setAttribute("aria-checked",String(!0===n.checked)),"check"===n.kind){const n=t(s,"span","oac-grid__box",{"aria-hidden":"true"});n.innerHTML=e("check"),a.appendChild(n)}void 0!==n.icon&&a.appendChild(n.icon);const r=t(s,"span","oac-menu__label");if(r.textContent=n.label,a.appendChild(r),void 0!==n.sub){const e=t(s,"span","oac-menu__sub");e.textContent=n.sub,a.appendChild(e)}!0===n.disabled&&null!=l&&a.setAttribute("aria-describedby",u);const i=o++;a.addEventListener("click",e=>{e.stopPropagation(),!0!==n.disabled&&(!0!==n.stay&&g(),n.onSelect(),!0===n.stay&&m(i))}),p.appendChild(a)}if(null!=l){const e=t(s,"div","oac-grid__note",{role:"none",id:u});e.textContent=l,p.appendChild(e)}d?.(p,()=>m()),n>=0&&p.querySelectorAll(".oac-menu__row")[n]?.focus()};return m(),p.addEventListener("keydown",e=>{const n=Array.from(p.querySelectorAll(".oac-menu__row")),o=n.indexOf(s.activeElement),t=c(e.key,o,n.length,["ArrowUp","ArrowDown"],!0);t<0||(e.preventDefault(),e.stopPropagation(),n[t].focus())}),g=n.overlays.open(p,{anchor:a,placement:"below",initialFocus:p.querySelector('.oac-menu__row[aria-checked="true"]')??void 0}),g}function b(e,c){const l=e.doc;o(l,v);const h=t(l,"div","oac-grid__picker",{role:"menu","aria-label":n(u(e),"Arrange charts")}),g=[],m=e.layout(),_=new Map;for(const n of e.layouts){const e=a[n].slots.length;_.set(e,[..._.get(e)??[],n])}let b=()=>{};const x=o=>1===a[o].slots.length?i(u(e),o):n(u(e),"{name}, {count} charts",{name:i(u(e),o),count:a[o].slots.length}),k=t(l,"div","oac-grid__picker-caption",{"aria-hidden":"true"}),f=()=>{k.textContent=null!==m&&d(m)?x(m):""};for(const[n,o]of _){const a=t(l,"div","oac-grid__picker-row",{role:"group","aria-label":r(u(e),n)}),c=t(l,"span","oac-grid__picker-count",{"aria-hidden":"true"});c.textContent=String(n),a.appendChild(c);const d=[];for(const n of o){const o=i(u(e),n),r=t(l,"button","oac-grid__tile",{type:"button",role:"menuitemradio","aria-checked":String(n===m),"aria-label":o});r.dataset.layout=n,r.appendChild(s(l,p(n)));const c=()=>{k.textContent=x(n)};r.addEventListener("pointerenter",c),r.addEventListener("focus",c),r.addEventListener("click",o=>{o.stopPropagation(),b(),e.setLayout(n)}),d.push(r),a.appendChild(r)}g.push(d),h.appendChild(a)}f(),h.appendChild(k),h.addEventListener("pointerleave",()=>{h.contains(l.activeElement)||f()});const w=g.flat();return h.addEventListener("keydown",e=>{const n=w.indexOf(l.activeElement);if(n<0)return;const o=g.findIndex(e=>e.includes(w[n])),t=g[o].indexOf(w[n]);let a;if("ArrowRight"===e.key)a=w[(n+1)%w.length];else if("ArrowLeft"===e.key)a=w[(n-1+w.length)%w.length];else if("ArrowDown"===e.key||"ArrowUp"===e.key){const n=g[(o+("ArrowDown"===e.key?1:g.length-1))%g.length];a=n[Math.min(t,n.length-1)]}else"Home"===e.key?a=w[0]:"End"===e.key&&(a=w[w.length-1]);void 0!==a&&(e.preventDefault(),e.stopPropagation(),a.focus())}),b=e.overlays.open(h,{anchor:c,placement:"below",initialFocus:w.find(e=>"true"===e.getAttribute("aria-checked"))??w[0]??void 0}),b}function x(o,a){const i=o.doc,c=u(o);let d=!1;return _(o,a,n(c,"Linking"),()=>{const a=o.links.current(),p=[n(c,"Link group")];p.push({kind:"radio",label:n(c,"Not linked"),checked:null===a,icon:l(i,null),stay:!0,onSelect:()=>o.links.setGroup(null)});for(const e of o.links.groups())p.push({kind:"radio",label:e.name,sub:r(c,e.cells.length),checked:a?.id===e.id,icon:l(i,e),stay:!0,onSelect:()=>o.links.setGroup(e.id)});if(p.push({kind:"action",label:n(c,"New group"),icon:s(i,e("plus")),stay:!0,onSelect:()=>o.links.newGroup()}),p.push({kind:"action",label:n(c,"Rename group"),icon:s(i,e("rename")),disabled:null===a,sub:null===a?n(c,"Link this chart to a group first"):void 0,stay:!0,onSelect:()=>{d=!0}}),null===a)return p;p.push(n(c,"Links in {group}",{group:a.name}));const u=a.links;for(const e of["crosshair","viewport","symbol","interval","chartType","appearance","drawings"])p.push({kind:"check",label:n(c,m[e]),checked:u[e],stay:!0,icon:s(i,g[e]),sub:"drawings"===e?n(c,"same instrument only"):void 0,onSelect:()=>o.links.setChannel(e,!u[e])}),"crosshair"===e&&p.push({kind:"check",label:n(c,"Nearest bar"),sub:n(c,"where a chart has no bar at that time"),checked:"nearest"===u.whenMissing,disabled:!u.crosshair,stay:!0,icon:t(i,"span","oac-grid__indent"),onSelect:()=>o.links.setChannel("nearest","nearest"!==u.whenMissing)});return p.push({kind:"action",label:n(c,"Share this chart's drawings"),icon:s(i,e("drawing-sync")),disabled:!u.drawings,sub:u.drawings?void 0:n(c,"Switch Drawings on first"),onSelect:()=>o.links.share()}),p},(e,a)=>{const r=o.links.current();if(!d||null===r)return;e.textContent="";const l=t(i,"div","oac-grid__rename"),s=t(i,"input",void 0,{type:"text","aria-label":n(c,"Group name"),maxlength:"120"});s.value=r.name;const p=n=>{n&&""!==s.value.trim()&&o.links.rename(r.id,s.value.trim()),d=!1,a(),e.querySelector('.oac-menu__row[aria-checked="true"]')?.focus()};s.addEventListener("keydown",e=>{"Enter"===e.key&&(e.preventDefault(),p(!0))});const u=t(i,"button","oac-btn oac-btn--primary",{type:"button"});u.textContent=n(c,"Save"),u.addEventListener("click",e=>{e.stopPropagation(),p(!0)});const h=t(i,"button","oac-btn",{type:"button"});h.textContent=n(c,"Cancel"),h.addEventListener("click",e=>{e.stopPropagation(),p(!1)}),l.append(s,h,u),e.appendChild(l),s.focus(),s.select()})}function k(o,t){const a=u(o),r=o.capture.blocked(),i=o.capture.canCopy();return _(o,t,n(a,"Capture every chart"),()=>[{kind:"action",label:n(a,"Download PNG of every chart"),disabled:null!==r,icon:s(o.doc,e("download")),onSelect:()=>o.capture.download()},{kind:"action",label:n(a,"Copy image of every chart"),disabled:null!==r||!i,sub:null!==r?void 0:n(a,i?"paste it anywhere":"needs https or localhost"),icon:s(o.doc,e("copy")),onSelect:()=>o.capture.copy()}],void 0,r)}const v='\n.oac-widget .oac-grid__menu { max-width: 380px; }\n.oac-grid__menu .oac-menu__row > .oac-glyph { color: var(--oac-mut); }\n.oac-grid__indent { width: 16px; flex: none; }\n.oac-grid__menu .oac-menu__row[role="menuitemcheckbox"]::before { display: none; }\n.oac-grid__menu .oac-menu__row[role="menuitemcheckbox"][aria-checked="true"] { color: var(--oac-tx); }\n.oac-grid__box { display: grid; place-items: center; width: 15px; height: 15px; flex: none; border: 1px solid var(--oac-bd);\n border-radius: 4px; background: var(--oac-elev); }\n.oac-grid__box > svg { width: 11px; height: 11px; fill: none; stroke: var(--oac-bg); stroke-width: 2.4; stroke-linecap: round;\n stroke-linejoin: round; opacity: 0; }\n.oac-grid__menu .oac-menu__row[aria-checked="true"] > .oac-grid__box { background: var(--oac-acc); border-color: var(--oac-acc); }\n.oac-grid__menu .oac-menu__row[aria-checked="true"] > .oac-grid__box > svg { opacity: 1; }\n.oac-grid__menu .oac-menu__row[aria-disabled="true"] > .oac-grid__box { opacity: .45; }\n.oac-grid__menu .oac-menu__row[role="menuitem"]::before { content: \'\'; width: 6px; margin: 0 2px 0 -2px; flex: none; }\n.oac-grid__rename { display: flex; align-items: center; gap: 6px; padding: 4px; }\n.oac-grid__rename > input { flex: 1 1 auto; min-width: 140px; }\n\n/* The layout picker: one row of tiles per chart count. */\n.oac-grid__picker { display: flex; flex-direction: column; gap: 2px; padding: 6px 8px 6px 6px; max-height: calc(100% - 16px);\n overflow-y: auto; background: var(--oac-panel); border: 1px solid var(--oac-bd); border-radius: 10px; box-shadow: var(--oac-shadow); outline: none; }\n.oac-grid__picker-row { display: flex; align-items: center; gap: 3px; }\n.oac-grid__picker-count { width: 20px; margin-right: 4px; text-align: right; color: var(--oac-faint); font-size: 11px;\n font-variant-numeric: tabular-nums; }\n.oac-grid__tile { display: grid; place-items: center; width: 34px; height: 30px; padding: 0; border: 1px solid transparent;\n border-radius: 6px; background: transparent; color: var(--oac-mut); transition: background .1s, color .1s; }\n.oac-grid__tile > .oac-glyph > svg { width: 22px; height: 22px; stroke-width: 1.5; }\n.oac-grid__tile:hover, .oac-grid__tile:focus-visible { background: var(--oac-elev-2); color: var(--oac-tx); }\n.oac-grid__tile:focus-visible { outline: 2px solid var(--oac-ring); outline-offset: -2px; }\n.oac-grid__tile[aria-checked="true"] { background: var(--oac-on-bg); border-color: var(--oac-on-bd); color: var(--oac-acc-2); }\n.oac-grid__picker-caption { min-height: 16px; margin: 4px 0 0; padding: 5px 2px 0 28px; border-top: 1px solid var(--oac-bd-soft);\n color: var(--oac-mut); font-size: 11.5px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }\n.oac-grid__note { max-width: 260px; padding: 6px 8px 4px 31px; border-top: 1px solid var(--oac-bd-soft); margin-top: 3px;\n color: var(--oac-faint); font-size: 11.5px; line-height: 1.4; }\n\n@media (prefers-reduced-motion: reduce) {\n .oac-grid__tile { transition: none; }\n}\n';export{k as openCaptureMenu,b as openLayoutPicker,x as openLinkMenu};
//# sourceMappingURL=openalgo-charts.widget.grid-menus-CPZWEiD3.mjs.map