@expofp/floorplan
Version:
Interactive floor plan library for expos and events
2 lines (1 loc) • 5.68 kB
JavaScript
import{Box as A,degToRad as S,radToDeg as D}from"@expofp/geometry";import R from"color";import*as N from"d3-selection";import W from"../../data";import{getLayerSvg as M,getTrianglesFromFpPaths as O}from"../../data/svg";import{eventScopedCache as T}from"../../tools/event-scoped-cache.js";import{getNextId as V}from"../../tools/id";import C from"../../tools/logger";import w from"../../tools/settings";import{generateUniqueSlug as P}from"../../tools/slug";import{sortByName as G}from"../../utils";import{areLayersEnabled as $}from"../../utils/areLayersEnabled";import{getStorage as E,saveStorage as U}from"../../utils/entity-storage";import{extractMetaFromString as j}from"../../utils/extractMetaFromString";import{planAutorun as q}from"../../utils/plan-reactions.js";import{RegularBooth as k,SpecialBooth as z}from"../BoothStore";import{uiState as H}from"../index";const x=T();export function iniAllBooths(e){x().clear();const f=[];for(const i of W.booths||[]){const{text:d,meta:c}=j(i.name),o=i.special?new z:new k;Object.assign(o,i),o.meta=c,o.slug=P(o.name),x().set(o.name.toLowerCase(),o),K(o);const h=o;h.exhibitors=[];for(const u of i.exhibitors??[]){const p=e.exhibitorStore.exhibitorById.get(u);p&&(h.exhibitors.push(p),p.booths.push(h))}o.schedule=e.eventStore.eventItems.filter(u=>u.boothId===o.id),o.name=d,f.push(o)}f.sort((i,d)=>i.name.localeCompare(d.name,void 0,{sensitivity:"base",numeric:!0}));for(const i of e.exhibitorStore.exhibitors)G(i.booths);e.boothStore.booths=f,C.log("initBooths",e.boothStore.booths.length),X(e)}function X(e){const d=(E("bookmarked").booths||[]).filter(c=>{const o=e.boothStore.boothById.get(c);return o&&o.exhibitors.length===0});e.boothStore.replaceBookmarked(d),q(()=>{const c=E("bookmarked"),o=e.boothStore.booths.filter(h=>h.exhibitors.length===0&&h.bookmarkedDirectly).map(h=>h.id);U("bookmarked",{exhibitors:c.exhibitors,events:c.events,speakers:c.speakers,booths:o})})}export default function J(e,f){const i=f.name,{boothStore:d,layerStore:c}=e,o=[],h=$(),u=N.select(M(f)).selectAll(`[data-layer='${i}'] > [data-tagname='efp-booth'], [data-layer='${i}'] > g[id^=b], [data-layer='${i}'] > rect[id^=b]`).nodes();for(const r of u){const B=r.closest("svg > [data-layer]").getAttribute("data-layer");if(!B)continue;let a,F=!1;r.tagName==="rect"?a=r:(a=Array.from(r.children).find(n=>n.tagName==="rect"),F=a===r.firstElementChild);const I=r.id||r.getAttribute("data-name");if(!I){C.error("SVG booth element has neither id nor data-name:",r);continue}const g=I.substring(1).toLowerCase();let t=x().get(g),l=t instanceof k?t:null;const v=t instanceof z?t:null;if(t||(C.error("SVG booth rect not found in the event data:",g),t=l=new k,t.id=V(),t.name=g.toUpperCase(),t.slug=P(g),t.error=!0,t.exhibitors=[],x().set(g,t)),o.push(t),t.layer=h?c.layers.find(n=>n.name===B):null,t.borderColor=a?.getAttribute("stroke")||a?.style.stroke||w.boothBorderColor||"#FFFFFF",t.borderWidth=parseFloat(a?.getAttribute("stroke-width")||a?.style.strokeWidth),isNaN(t.borderWidth)&&(t.borderWidth=d.borderWidth),!H.heatmap)t.labelColor=a?.getAttribute("data-label-color");else{const n=e.heatmapStore.getTotalClicksByBooth(t),b=R(e.heatmapStore.getColorByClicks(n));t.labelColor=b.darken(.3).isLight()?"#555":"#fff"}t.rect=a?A.fromSvg(a):null,t.elevation=parseFloat(a?.dataset.elev??"")||0,t.noLabels=!!a?.dataset.nolabel||a?.id.startsWith("no"),l?(l.availColor=r.getAttribute("data-avail-color")||a?.getAttribute("data-avail-color")||l.availColor,l.soldColor=r.getAttribute("data-sold-color")||a?.getAttribute("data-sold-color")||l.soldColor,l.holdColor=r.getAttribute("data-hold-color")||a?.getAttribute("data-hold-color")||l.holdColor,l.size=W.dimensionless?null:l.size||r.getAttribute("data-size"),l.status==="reserved"?l.reserved=!0:l.status==="onhold"&&(l.onHold=!0)):v&&(v.color=(parseInt(a.getAttribute("data-poi-type")??"")>0?a.style?.fill:r.getAttribute("data-color")||a.getAttribute("data-color"))||v.color);const y=a?.getAttribute("transform");if(y){const n=y.match(/translate\(([-0-9.]+) ([-0-9.]+)\) rotate\(([-0-9.]+)\)/);if(n){const s=parseFloat(n[3]);t.rotate=S(s)}else{const s=y.match(/rotate\(([-0-9.]+).*\)/);if(s){const m=parseFloat(s[1]);t.rotate=S(m)}else{const m=y.match(/matrix\(\s*([-0-9.]+)\s*(?:,|\s)\s*([-0-9.]+)\s*(?:,|\s)\s*([-0-9.]+)\s*(?:,|\s)\s*([-0-9.]+)\s*(?:,|\s)\s*([-0-9.]+)\s*(?:,|\s)\s*([-0-9.]+)\s*\)/);m&&(t.rotate=Math.asin(parseFloat(m[2])))}}if(Math.abs(D(t.rotate))>180){t.rotate+=S(90);const s=t.rect;t.rect=new A(s.center.x-s.size.height/2,s.center.y-s.size.width/2,s.size.height,s.size.width)}}if(r.tagName==="g"){t.paths=[],t.pathsWithRect=F;const n=[];for(const b of N.select(r).selectAll("path, rect").nodes())if(b.tagName==="path"){const s=b;if(s.tagName!=="path")continue;const m=parseInt(s.getAttribute("data-index")??""),L=!!s.getAttribute("data-unblinking");t.paths.push({index:m,color:s.style.fill,unblinking:L}),a||n.push(...O(m,i))}if(n.length){const b=n.flatMap(s=>s.map(m=>({x:m[0],y:m[1]})));t.rect=A.fromPoints(b),t.noLabels=!0}}}const p=o.filter(r=>r.rect?!0:(C.error("event data booth not found in SVG:",r.name,r),!1));for(const r of p)r.store=d;return p}function K(e){w.EXPO==="cbresupplypartner"&&e instanceof k&&!e.availColor&&e.type&&(e.type.indexOf("Premium A - 2m height restriction Passport")!==-1?e.availColor="#939393":e.type.indexOf("No free-standing")!==-1?e.availColor="#BA3DC8":e.type.endsWith("Passport")?e.availColor="#939393":e.type.startsWith("Premium A - 2m")?e.availColor="#FF9E4E":e.type.startsWith("Premium A - 4m")?e.availColor="#EA4335":e.type.startsWith("Premium B - 2m")?e.availColor="#523BC0":e.type.startsWith("Premium C - 2.4m")&&(e.availColor="#3ECC78"))}