UNPKG

@visactor/vmind

Version:

<div align="center"> <a href="https://github.com/VisActor#gh-light-mode-only" target="_blank"> <img alt="VisActor Logo" width="200" src="https://github.com/VisActor/.github/blob/main/profile/logo_500_200_light.svg"/> </a> <a href="https://githu

43 lines (35 loc) 5.97 kB
import { pick, uniqArray } from "@visactor/vutils"; import { chartGenerationConstraints, chartKnowledgeDict, defaultExamples, getCartesianCoordinateSystemKnowledge, getNeedColorAndSizeKnowledge, visualChannelInfoMap } from "./knowledges"; import { getStrFromArray } from "../../../utils/common"; import { ChartType } from "../../../types"; const ChartAdvisorPromptEnglish = (showThoughts, supportedChartList, knowledge, visualChannels, examples, stackOrPercent, transpose) => `You are a data visualization expert with an in-depth understanding of visualization grammar. Your task is to provide the chart type and field visualization mapping based on the user's visualization needs and the existing field descriptions.\n# User Input\nUser Input is Bellow:\n\`\`\`typescript\n{\nuserInput: string; // User visualization instructions.\nfieldInfo: { // field information\nid: string; // id of this field, also the field's name\nrole: 'measure' | 'dimension',\ntype: 'numerical' | 'ratio' | 'string' | 'date', // 'ratio' means percentage data, 'string' means regular categorical text\ndescription?: string; // description of field\n}[],\n}\n\`\`\`\n# Response\nResponse in the following format:\n\`\`\`\n{${showThoughts ? '\n"thoughts" : your thoughts' : ""}\n"CHART_TYPE": string; // The chart type you choose.\n"FIELD_MAP": { // Visualization channel mapping results\n${visualChannels}\n}${showThoughts ? ',\n"Reason": the reason for selecting the chart type and visual mapping.' : ""}${stackOrPercent ? '\n"stackOrPercent"?: "stack" | "percent" // default undefined' : ""}${transpose ? '\n"transpose"?: boolean // 是否横向展示,或者是否为条形图' : ""}\n}\n\`\`\`\n\n# Requirements\n1. CHART_TYPE MUST selected from ${JSON.stringify(supportedChartList)}\n2. All fields MUST be mapped to visual channels.\n3. The field names in FIELD_MAP MUST be CONSISTENT with the id in fieldInfo.\n4. The color field MUST be a dimension field\n5. The y-axis field MUST be a measure field.\n6. The x field and the time field MUST be different.\n7. Focus only on chart visualization tasks.\n8. Strictly define the type of return format, use JSON format to reply, do not include any extra content.\n9. The xy fields remain UNCHANGED even under transpose.\n${knowledge.length > 0 ? "\n# Knowledge" : ""}\n${knowledge}\n\n# Steps\nYou should think step-by-step as follow, while ensuring all requirements are met during the process.\n1. Based on the user's input, infer the user's intention, such as comparison, ranking, trend display, proportion, distribution, etc. If user did not show their intention, just ignore and do the next steps.\n2. Select the SINGLE chart type that best suites the data from the Requirment 1.\n3. Map ALL the fields in the data to the visual channels according to user input and the chart type you choose.\n4. Check the results to ensure they meet all the requirements.\n\n# Examples\n${examples}\n`; export const getPrompt = (propsChartList, showThoughts = !0) => { const chartTypeList = propsChartList.filter((v => !!chartKnowledgeDict[v])), sortedChartTypeList = chartTypeList.sort(((a, b) => chartKnowledgeDict[a].index - chartKnowledgeDict[b].index)), chartKnowledge = sortedChartTypeList.reduce(((res, chartType) => { const {knowledge: knowledge} = chartKnowledgeDict[chartType]; return [ ...res, ...null != knowledge ? knowledge : [] ]; }), [ getNeedColorAndSizeKnowledge(chartTypeList), getCartesianCoordinateSystemKnowledge(chartTypeList) ]), knowledgeStr = getStrFromArray(chartKnowledge), visualChannels = sortedChartTypeList.reduce(((res, chartType) => { const {visualChannels: visualChannels} = chartKnowledgeDict[chartType]; return [ ...res, ...visualChannels ]; }), []), visualChannelsStr = uniqArray(visualChannels).map((channel => `"${channel}": ${visualChannelInfoMap[channel](sortedChartTypeList)}`)).join("\n"), chartExamples = (getStrFromArray(chartGenerationConstraints), sortedChartTypeList.reduce(((res, chartType) => { const {examples: examples} = chartKnowledgeDict[chartType]; return [ ...res, ...examples.map((e => e(showThoughts))) ]; }), [])), examplesStr = (chartExamples.length > 0 ? chartExamples.slice(0, 4) : defaultExamples).join("\n\n------------------------\n\n"); return ChartAdvisorPromptEnglish(showThoughts, chartTypeList, knowledgeStr, visualChannelsStr, examplesStr, !!chartTypeList.find((v => [ ChartType.BarChart, ChartType.AreaChart ].includes(v))), chartTypeList.includes(ChartType.BarChart)); }; const patchUserInput = userInput => { const FULL_WIDTH_SYMBOLS = [ ",", "。" ], HALF_WIDTH_SYMBOLS = [ ",", "." ], ALLOWED_WORD_LIST = [ "动态条形图", "动态柱状图", "动态柱图" ], tempStr1 = ALLOWED_WORD_LIST.reduce(((prev, cur, index) => prev.split(cur).join("_USER_INPUT_PLACE_HOLDER_" + index)), userInput), tempStr2 = [ "动态" ].reduce(((prev, cur) => prev.split(cur).join("")), tempStr1), replacedStr = ALLOWED_WORD_LIST.reduce(((prev, cur, index) => prev.split("_USER_INPUT_PLACE_HOLDER_" + index).join(cur)), tempStr2); let finalStr = HALF_WIDTH_SYMBOLS.reduce(((prev, cur, index) => prev.split(HALF_WIDTH_SYMBOLS[index]).join(FULL_WIDTH_SYMBOLS[index])), replacedStr); const lastCharacter = finalStr[finalStr.length - 1]; return FULL_WIDTH_SYMBOLS.includes(lastCharacter) || HALF_WIDTH_SYMBOLS.includes(lastCharacter) || (finalStr += "。"), finalStr += "Use the original id in fieldInfo and DO NOT change or translate any word of the data fields in the response.", finalStr; }; export const revisedUserInput = (query, vizSchema) => { const userInput = patchUserInput(query), filteredFields = vizSchema.fields.filter((field => field.visible)).map((field => Object.assign({}, pick(field, [ "id", "description", "type", "role" ])))); return JSON.stringify({ userInput: userInput, fieldInfo: filteredFields }); }; //# sourceMappingURL=index.js.map