|
|
@@ -1,26 +1,47 @@
|
|
|
import React, { useEffect, useState } from 'react'
|
|
|
|
|
|
-// 创作Query正交 Demo:仿"制作query"的多列 UI——左侧若干「轴列」(实质/形式/目的池/阶段/知识类型),
|
|
|
-// 右侧「Query 词」列出该家族机械正交出的原串(过 query_filter 后标 留/扔)。顶部 5 家族切换。
|
|
|
-const AXIS_KEY = { // 家族里写的轴名 → axis_values 里的键
|
|
|
- '实质': '实质', '形式': '形式', '作用/感受/意图': '目的池',
|
|
|
+// 创作Query正交 Demo:仿"制作query"的多列 UI——左侧若干「轴列」,右侧「Query 词」。
|
|
|
+// 关键:左侧轴列只显示【该家族 query 实际用到的去重值】,与右侧 query 一一对应(不是整池)。
|
|
|
+// 阶段列按 灵感/选题/脚本 分组缩进,只显示用到的子词。
|
|
|
+const PARTS_KEY = { // 家族 axes 里的轴名 → 每条 query 的 parts 里的键
|
|
|
+ '实质': '实质', '形式': '形式', '作用/感受/意图': '目的',
|
|
|
'阶段': '阶段', '模态': '模态', '知识类型': '知识类型',
|
|
|
}
|
|
|
|
|
|
-// 阶段值是 {灵感:[...],选题:[...],脚本:[...]} 分组结构,按组+缩进渲染;其余轴是扁平数组。
|
|
|
-function AxisValues({ vals }) {
|
|
|
- if (Array.isArray(vals)) {
|
|
|
- return vals.map((v, i) => <div className="axv" key={i}>{v}</div>)
|
|
|
+// 该家族 query 在某轴上实际用过的去重值(按首次出现顺序)
|
|
|
+function usedValues(items, pk) {
|
|
|
+ const set = new Set(), out = []
|
|
|
+ for (const it of items) {
|
|
|
+ const v = it.parts && it.parts[pk]
|
|
|
+ if (v && !set.has(v)) { set.add(v); out.push(v) }
|
|
|
}
|
|
|
- return Object.entries(vals || {}).map(([grp, words]) => (
|
|
|
- <div key={grp}>
|
|
|
- <div className="axv grp">{grp}</div>
|
|
|
- {words.map((w, i) => <div className="axv child" key={i}>{w}</div>)}
|
|
|
- </div>
|
|
|
- ))
|
|
|
+ return out
|
|
|
}
|
|
|
-function axisCount(vals) {
|
|
|
- return Array.isArray(vals) ? vals.length : Object.values(vals || {}).reduce((n, w) => n + w.length, 0)
|
|
|
+
|
|
|
+function AxisCol({ ax, fam, axisValues }) {
|
|
|
+ const used = usedValues(fam.items, PARTS_KEY[ax])
|
|
|
+ const usedSet = new Set(used)
|
|
|
+ const grouping = axisValues['阶段'] // {灵感:[...],选题:[...],脚本:[...]}
|
|
|
+ let body
|
|
|
+ if (ax === '阶段' && grouping && !Array.isArray(grouping)) {
|
|
|
+ const groups = Object.entries(grouping)
|
|
|
+ .map(([grp, words]) => [grp, words.filter(w => usedSet.has(w))])
|
|
|
+ .filter(([, words]) => words.length)
|
|
|
+ body = groups.map(([grp, words]) => (
|
|
|
+ <div key={grp}>
|
|
|
+ <div className="axv grp">{grp}</div>
|
|
|
+ {words.map((w, i) => <div className="axv child" key={i}>{w}</div>)}
|
|
|
+ </div>
|
|
|
+ ))
|
|
|
+ } else {
|
|
|
+ body = used.map((v, i) => <div className="axv" key={i}>{v}</div>)
|
|
|
+ }
|
|
|
+ return (
|
|
|
+ <div className="axcol">
|
|
|
+ <div className="axhd">{ax}<span className="gn">{used.length}</span></div>
|
|
|
+ <div className="axlist">{body}</div>
|
|
|
+ </div>
|
|
|
+ )
|
|
|
}
|
|
|
|
|
|
export default function CreationDemo() {
|
|
|
@@ -40,7 +61,7 @@ export default function CreationDemo() {
|
|
|
return (
|
|
|
<div>
|
|
|
<h1>创作知识 · Query 正交 Demo</h1>
|
|
|
- <div className="sub">5 套家族机械正交(取分类树创作支)→ LLM 只做排除(query_filter)→ 原串直接可搜(本 demo 不真搜)</div>
|
|
|
+ <div className="sub">5 套家族机械正交(取分类树创作支)→ LLM 只做排除(query_filter)→ 原串直接可搜(本 demo 不真搜)· 左侧轴列只显示这批 query 实际用到的值</div>
|
|
|
|
|
|
<div className="nav">
|
|
|
{data.families.map((f, i) => (
|
|
|
@@ -50,12 +71,7 @@ export default function CreationDemo() {
|
|
|
|
|
|
<div className="cdemo">
|
|
|
{fam.axes.map(ax => (
|
|
|
- <div className="axcol" key={ax}>
|
|
|
- <div className="axhd">{ax}<span className="gn">{axisCount(data.axis_values[AXIS_KEY[ax]])}</span></div>
|
|
|
- <div className="axlist">
|
|
|
- <AxisValues vals={data.axis_values[AXIS_KEY[ax]]} />
|
|
|
- </div>
|
|
|
- </div>
|
|
|
+ <AxisCol key={ax} ax={ax} fam={fam} axisValues={data.axis_values} />
|
|
|
))}
|
|
|
<div className="axcol qcol">
|
|
|
<div className="axhd qhd">Query 词<span className="gn">留 {kept}/{fam.items.length}</span></div>
|