/* DeerFlow generated-HTML runtime. Browser ES5; no module loader required. */ (function () { "use strict"; function ready(fn) { if (document.readyState === "loading") document.addEventListener("DOMContentLoaded", fn); else fn(); } function blocks(name) { return document.querySelectorAll('script[type="application/json"][' + name + "]"); } function parse(block, target) { try { return JSON.parse(block.textContent || "{}"); } catch (error) { showError(target, "图形数据格式错误:" + (error && error.message ? error.message : "无法解析 JSON")); return null; } } function showError(target, message) { var box = document.createElement("div"); box.className = "df-runtime-error"; box.setAttribute("role", "alert"); box.textContent = message; if (target && target.parentNode) target.parentNode.insertBefore(box, target.nextSibling); } function size(target) { if (target.clientHeight < 40) target.style.minHeight = "360px"; if (target.clientWidth < 40) target.style.width = "100%"; } function escapeHtml(value) { return String(value == null ? "" : value).replace(/[&<>"']/g, function (ch) { return { "&": "&", "<": "<", ">": ">", '"': """, "'": "'" }[ch]; }); } function geoPoint(value) { if (!value || value.length < 2) return null; var lng = Number(value[0]); var lat = Number(value[1]); if (!isFinite(lng) || !isFinite(lat) || lng < -180 || lng > 180 || lat < -90 || lat > 90) return null; return [lng, lat]; } function initCharts() { var items = blocks("data-df-chart"); for (var i = 0; i < items.length; i += 1) { var block = items[i]; var target = document.getElementById(block.getAttribute("data-df-chart")); if (!target) continue; var option = parse(block, target); if (!option) continue; if (!window.echarts) { showError(target, "ECharts 运行库加载失败"); continue; } try { size(target); target.setAttribute("role", "img"); target.setAttribute("aria-label", option.title && option.title.text ? option.title.text : "数据图表"); var chart = window.echarts.init(target); chart.setOption(option); (function (instance) { window.addEventListener("resize", function () { instance.resize(); }); })(chart); } catch (error) { showError(target, "图表渲染失败:" + (error && error.message ? error.message : "请检查图表数据")); } } } var geoMapCache = {}; var geoMapLoads = {}; var geoMapDefaultViews = { "us-states": { center: [-98, 38], zoom: 2.1 } }; function geoMapUrl(mapId) { var config = window.DEERFLOW_HTML_RUNTIME_CONFIG || {}; var maps = config.geoMaps || {}; return typeof maps[mapId] === "string" ? maps[mapId] : ""; } function loadGeoMap(mapId) { if (geoMapCache[mapId]) return Promise.resolve(geoMapCache[mapId]); if (geoMapLoads[mapId]) return geoMapLoads[mapId]; var url = geoMapUrl(mapId); if (!url) return Promise.reject(new Error("未配置地图资源:" + mapId)); if (!window.fetch) return Promise.reject(new Error("当前浏览器不支持加载本地 GeoJSON")); geoMapLoads[mapId] = window.fetch(url, { credentials: "omit" }).then(function (response) { if (!response.ok) throw new Error("地图资源加载失败(HTTP " + response.status + ")"); return response.json(); }).then(function (geoJson) { if (!geoJson || !geoJson.type) throw new Error("地图资源不是有效 GeoJSON"); normalizeGeoJsonNames(geoJson); geoMapCache[mapId] = geoJson; return geoJson; }).catch(function (error) { delete geoMapLoads[mapId]; throw error; }); return geoMapLoads[mapId]; } function normalizeGeoJsonNames(geoJson) { var features = geoJson && geoJson.features; if (!features || !features.length) return; for (var i = 0; i < features.length; i += 1) { var feature = features[i] || {}; var properties = feature.properties || (feature.properties = {}); if (!properties.name) { properties.name = properties.shapeName || properties.NAME_1 || properties.name_en || properties.id || "区域"; } } } function geoRegions(data) { var values = data.regions || []; var output = []; for (var i = 0; i < values.length; i += 1) { var region = values[i]; if (!region || !region.name) continue; var item = { name: String(region.name) }; if (isFinite(Number(region.value))) item.value = Number(region.value); if (region.color) item.itemStyle = { areaColor: String(region.color) }; if (region.description) item.description = String(region.description); if (region.selected === true) item.selected = true; output.push(item); } return output; } function geoMarkers(data) { var values = data.markers || []; var output = []; for (var i = 0; i < values.length; i += 1) { var marker = values[i]; var coordinate = marker && geoPoint(marker.coordinate); if (!coordinate) continue; output.push({ name: marker.name || "地点", value: coordinate.concat([Number(marker.value) || 1]), description: marker.description || "", itemStyle: marker.color ? { color: marker.color } : undefined }); } return output; } function geoLines(data) { var values = data.lines || []; var output = []; for (var i = 0; i < values.length; i += 1) { var line = values[i] || {}; var rawCoordinates = line.coordinates || []; var coordinates = []; for (var j = 0; j < rawCoordinates.length; j += 1) { var coordinate = geoPoint(rawCoordinates[j]); if (coordinate) coordinates.push(coordinate); } if (coordinates.length > 1) output.push({ name: line.name || "连接", coords: coordinates, description: line.description || "", lineStyle: line.color ? { color: line.color } : undefined }); } return output; } function geoTooltip(params, data) { var name = params.name || "地图区域"; var detail = geoDetail(data, name, params.data); var description = detail.description || ""; return "" + escapeHtml(name) + "" + (description ? "
" + escapeHtml(description) : ""); } function geoDetail(data, name, itemData) { var groups = [data.markers || [], data.regions || [], data.lines || []]; for (var groupIndex = 0; groupIndex < groups.length; groupIndex += 1) { var group = groups[groupIndex]; for (var itemIndex = 0; itemIndex < group.length; itemIndex += 1) { if (group[itemIndex] && group[itemIndex].name === name) return group[itemIndex]; } } return itemData || {}; } function showGeoPopup(target, params, data) { var name = params.name || "地图区域"; var detail = geoDetail(data, name, params.data); var popup = target.querySelector(".df-geo-popup"); if (!popup) { if (window.getComputedStyle && window.getComputedStyle(target).position === "static") { target.style.position = "relative"; } popup = document.createElement("section"); popup.className = "df-geo-popup"; popup.setAttribute("role", "dialog"); popup.setAttribute("aria-live", "polite"); popup.style.cssText = "position:absolute;z-index:10;max-width:280px;padding:16px 42px 16px 16px;border:1px solid #5aa8df;border-radius:12px;background:rgba(5,23,45,.96);box-shadow:0 16px 36px rgba(0,0,0,.34);color:#f8fbff;font:16px/1.55 -apple-system,BlinkMacSystemFont,'Segoe UI','Microsoft YaHei',sans-serif;"; target.appendChild(popup); } var description = detail.description || "暂无更多说明。"; var value = isFinite(Number(detail.value)) ? "
指标:" + escapeHtml(detail.value) + "
" : ""; popup.innerHTML = "" + "" + escapeHtml(name) + "" + "
" + escapeHtml(description) + "
" + value; var close = popup.querySelector("button"); if (close) close.onclick = function () { popup.style.display = "none"; }; var rawX = params.event && Number(params.event.offsetX); var rawY = params.event && Number(params.event.offsetY); var x = isFinite(rawX) ? rawX : target.clientWidth / 2; var y = isFinite(rawY) ? rawY : target.clientHeight / 2; popup.style.left = Math.max(12, Math.min(Math.max(12, target.clientWidth - 292), x + 14)) + "px"; popup.style.top = Math.max(12, Math.min(Math.max(12, target.clientHeight - 150), y + 14)) + "px"; popup.style.display = "block"; } function initGeoMaps() { var items = blocks("data-df-geo"); for (var i = 0; i < items.length; i += 1) { var block = items[i]; var target = document.getElementById(block.getAttribute("data-df-geo")); if (!target) continue; var data = parse(block, target); if (!data) continue; if (!window.echarts) { showError(target, "ECharts 运行库加载失败"); continue; } (function (mapTarget, mapData) { var mapId = mapData.map || "china-provinces"; loadGeoMap(mapId).then(function (geoJson) { size(mapTarget); mapTarget.setAttribute("role", "application"); mapTarget.setAttribute("aria-label", mapData.title || "交互地图"); window.echarts.registerMap(mapId, geoJson); var background = mapData.mode === "background"; var labels = mapData.showLabels === true || (!background && mapData.showLabels !== false); var areaColor = mapData.areaColor || (background ? "#123b67" : "#d8ecff"); var borderColor = mapData.borderColor || (background ? "#4e8cbf" : "#5d8cbb"); var emphasisColor = mapData.emphasisColor || (background ? "#2578bc" : "#8ec5f0"); var regions = geoRegions(mapData); var defaultView = geoMapDefaultViews[mapId] || {}; var mapCenter = geoPoint(mapData.center) || defaultView.center; var configuredZoom = Number(mapData.zoom); var mapZoom = isFinite(configuredZoom) && configuredZoom > 0 ? configuredZoom : defaultView.zoom; var chart = window.echarts.init(mapTarget, null, { renderer: "canvas" }); chart.setOption({ animation: false, backgroundColor: "transparent", tooltip: { trigger: "item", backgroundColor: "rgba(8, 22, 45, 0.94)", borderColor: "#5aa8df", textStyle: { color: "#f8fbff", fontSize: 16 }, formatter: function (params) { return geoTooltip(params, mapData); } }, geo: { map: mapId, roam: mapData.roam !== false, layoutCenter: mapData.layoutCenter || ["50%", "50%"], layoutSize: mapData.layoutSize || (background ? "118%" : "100%"), center: mapCenter, zoom: mapZoom, label: { show: labels, color: background ? "#d7ecff" : "#183450", fontSize: 16 }, itemStyle: { areaColor: areaColor, borderColor: borderColor, borderWidth: 1.25 }, emphasis: { label: { show: labels }, itemStyle: { areaColor: emphasisColor } }, select: { label: { show: labels }, itemStyle: { areaColor: mapData.selectColor || "#1e6cac" } } }, series: [ { type: "map", map: mapId, geoIndex: 0, data: regions, selectedMode: "single", z: 1, itemStyle: { areaColor: areaColor, borderColor: borderColor, borderWidth: 1.25 }, emphasis: { label: { show: labels }, itemStyle: { areaColor: emphasisColor } }, select: { label: { show: labels }, itemStyle: { areaColor: mapData.selectColor || "#1e6cac" } } }, { type: "effectScatter", coordinateSystem: "geo", z: 4, data: geoMarkers(mapData), symbolSize: mapData.markerSize || 13, showEffectOn: "render", rippleEffect: { scale: 3.2, brushType: "stroke" }, label: { show: true, formatter: "{b}", position: "right", color: background ? "#f8fbff" : "#183450", fontSize: 16, fontWeight: 700 }, itemStyle: { color: mapData.markerColor || "#f4bd57", shadowBlur: 12, shadowColor: "rgba(244,189,87,0.55)" } }, { type: "lines", coordinateSystem: "geo", z: 3, data: geoLines(mapData), lineStyle: { color: mapData.lineColor || "#77d4ff", width: 2, opacity: 0.82, curveness: 0.16 }, effect: { show: true, period: 5, symbol: "arrow", symbolSize: 8, trailLength: 0.08 } } ] }); chart.on("click", function (params) { var detail = geoDetail(mapData, params.name || "", params.data); if (mapData.popup !== false) showGeoPopup(mapTarget, params, mapData); if (!window.CustomEvent) return; window.dispatchEvent(new window.CustomEvent("deerflow:geo-map-click", { detail: { targetId: mapTarget.id, name: params.name || "", kind: params.seriesType || "region", data: detail, description: detail.description || "" } })); }); window.addEventListener("resize", function () { chart.resize(); }); }).catch(function (error) { showError(mapTarget, "地图渲染失败:" + (error && error.message ? error.message : "请检查地图数据")); }); })(target, data); } } function initFlows() { var items = blocks("data-df-flow"); for (var i = 0; i < items.length; i += 1) { var block = items[i]; var target = document.getElementById(block.getAttribute("data-df-flow")); if (!target) continue; var data = parse(block, target); if (!data) continue; if (!window.G6 || !window.G6.Graph) { showError(target, "AntV G6 运行库加载失败"); continue; } try { size(target); var nodes = data.nodes || []; var edges = data.edges || []; var rankDirection = data.direction === "TB" ? "TB" : "LR"; var colors = { start: ["#dcfce7", "#22c55e", "#14532d"], end: ["#ede9fe", "#8b5cf6", "#4c1d95"], decision: ["#fef3c7", "#f59e0b", "#78350f"], risk: ["#fee2e2", "#ef4444", "#7f1d1d"], process: ["#dbeafe", "#3b82f6", "#1e3a8a"], stage: ["#e0e7ff", "#6366f1", "#312e81"], task: ["#f1f5f9", "#94a3b8", "#1e293b"] }; var typeNames = { start: "开始", end: "结束", decision: "判断", risk: "异常", process: "处理", stage: "阶段", task: "任务" }; var graphData = { nodes: [], edges: [] }; for (var n = 0; n < nodes.length; n += 1) { var node = nodes[n]; var pair = colors[node.type] || colors.task; graphData.nodes.push({ id: String(node.id), data: { label: node.label || node.id, description: node.description || "", typeName: typeNames[node.type] || typeNames.task, fill: node.color || pair[0], stroke: pair[1], textColor: pair[2], terminal: node.type === "start" || node.type === "end" }}); } for (var e = 0; e < edges.length; e += 1) { graphData.edges.push({ source: String(edges[e].source), target: String(edges[e].target), data: { label: edges[e].label || "" } }); } var graph = new window.G6.Graph({ container: target, data: graphData, autoFit: "view", padding: 72, zoomRange: [0.1, 2], animation: false, layout: { type: "dagre", rankdir: rankDirection, nodesep: 44, ranksep: 60 }, node: { type: "rect", style: { size: function (d) { var width = Math.max(190, Math.min(260, 118 + String(d.data.label || "").length * 15)); return [width, 68]; }, radius: function (d) { return d.data.terminal ? 38 : 16; }, opacity: 1, fillOpacity: 1, strokeOpacity: 1, fill: function (d) { return d.data.fill; }, stroke: function (d) { return d.data.stroke; }, lineWidth: 2.5, shadowColor: "rgba(15,23,42,0.10)", shadowBlur: 12, shadowOffsetY: 4, labelText: function (d) { return d.data.typeName + " · " + d.data.label; }, labelPlacement: "center", labelFill: function (d) { return d.data.textColor; }, labelOpacity: 1, labelFontSize: 16, labelFontWeight: 700, labelWordWrap: true, labelMaxWidth: 220, cursor: "grab" }}, edge: { type: "polyline", style: { opacity: 1, strokeOpacity: 1, stroke: "#94a3b8", lineWidth: 2.25, radius: 16, endArrow: true, labelText: function (d) { return d.data.label; }, labelFill: "#334155", labelOpacity: 1, labelFontSize: 12, labelBackground: true, labelBackgroundFill: "#ffffff", labelBackgroundRadius: 6, labelPadding: [4, 7] }}, behaviors: ["drag-canvas", "zoom-canvas", "drag-element"] }); var rendered = graph.render(); if (rendered && rendered.catch) rendered.catch(function (error) { showError(target, "流程图渲染失败:" + error.message); }); (function (instance) { window.addEventListener("resize", function () { instance.resize(); }); })(graph); } catch (error) { showError(target, "流程图渲染失败:" + (error && error.message ? error.message : "请检查流程数据")); } } } ready(function () { initFlows(); initCharts(); initGeoMaps(); }); })();