From d9010cd580f67dda971abca290e306a9047b5e31 Mon Sep 17 00:00:00 2001 From: Nick Shirokov Date: Sun, 24 May 2026 16:18:16 +0300 Subject: [PATCH] =?UTF-8?q?feat(skd):=20multi-series=20=D0=B8=20multi-poin?= =?UTF-8?q?t=20=D0=B2=20StructureItemChart?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Диаграмма может содержать несколько (и аналогично ) — каждая со своим groupItems, filter, order, selection, viewMode, userSettingID и userSettingPresentation. Используется для multi-series графиков с группировкой по фильтру (например, АнализЛояльностиКлиентовXYZ — series по СтадияОтношений: Постоянный, Разовый, Потенциальный, Потерянный клиент). Раньше декомпилировали только первый блок (SelectSingleNode), теряя остальные → −113 строк diff на одном этом отчёте (134 → 21). decompile: SelectNodes → если >1, сохраняем как массив; single → object (backward-compat). compile: проверяем тип points/series — array → цикл, иначе single блок (backward-compat для существующего DSL). PS и Py compile синхронизированы. --- .../skd-compile/scripts/skd-compile.ps1 | 40 ++++++++++++++----- .../skills/skd-compile/scripts/skd-compile.py | 28 ++++++++----- .../skd-decompile/scripts/skd-decompile.ps1 | 26 +++++++++--- 3 files changed, 69 insertions(+), 25 deletions(-) diff --git a/.claude/skills/skd-compile/scripts/skd-compile.ps1 b/.claude/skills/skd-compile/scripts/skd-compile.ps1 index b5d680e1..2d3aab0a 100644 --- a/.claude/skills/skd-compile/scripts/skd-compile.ps1 +++ b/.claude/skills/skd-compile/scripts/skd-compile.ps1 @@ -1,4 +1,4 @@ -# skd-compile v1.90 — Compile 1C DCS from JSON +# skd-compile v1.91 — Compile 1C DCS from JSON # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills param( [string]$DefinitionFile, @@ -3014,18 +3014,40 @@ function Emit-StructureItem { X "$indent`t$(Esc-Xml "$($item.name)")" } - # Points + # Points — single object или массив (multi-series диаграмма) if ($item.points) { - X "$indent`t" - Emit-TableAxisBlock -block $item.points -indent "$indent`t`t" - X "$indent`t" + $pBlocks = if ($item.points -is [array] -or ($item.points -is [System.Collections.IList] -and $item.points -isnot [string])) { + @($item.points) + } else { @($item.points) } + # Эвристика: если это массив объектов (а не одиночный объект-с-полями) → multi. + $isPointsArray = ($item.points -is [array]) -or ($item.points -is [System.Collections.IList] -and $item.points -isnot [string] -and $item.points -isnot [System.Collections.IDictionary] -and $item.points -isnot [PSCustomObject]) + if ($isPointsArray) { + foreach ($pb in $pBlocks) { + X "$indent`t" + Emit-TableAxisBlock -block $pb -indent "$indent`t`t" + X "$indent`t" + } + } else { + X "$indent`t" + Emit-TableAxisBlock -block $item.points -indent "$indent`t`t" + X "$indent`t" + } } - # Series + # Series — single object или массив if ($item.series) { - X "$indent`t" - Emit-TableAxisBlock -block $item.series -indent "$indent`t`t" - X "$indent`t" + $isSeriesArray = ($item.series -is [array]) -or ($item.series -is [System.Collections.IList] -and $item.series -isnot [string] -and $item.series -isnot [System.Collections.IDictionary] -and $item.series -isnot [PSCustomObject]) + if ($isSeriesArray) { + foreach ($sb in @($item.series)) { + X "$indent`t" + Emit-TableAxisBlock -block $sb -indent "$indent`t`t" + X "$indent`t" + } + } else { + X "$indent`t" + Emit-TableAxisBlock -block $item.series -indent "$indent`t`t" + X "$indent`t" + } } # Selection (chart values) diff --git a/.claude/skills/skd-compile/scripts/skd-compile.py b/.claude/skills/skd-compile/scripts/skd-compile.py index 74d42999..ceb202d8 100644 --- a/.claude/skills/skd-compile/scripts/skd-compile.py +++ b/.claude/skills/skd-compile/scripts/skd-compile.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# skd-compile v1.90 — Compile 1C DCS from JSON +# skd-compile v1.91 — Compile 1C DCS from JSON # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills import argparse import json @@ -2418,17 +2418,23 @@ def emit_structure_item(lines, item, indent, short_group=False): if item.get('name'): lines.append(f'{indent}\t{esc_xml(str(item["name"]))}') - # Points - if item.get('points'): - lines.append(f'{indent}\t') - emit_table_axis_block(lines, item['points'], f'{indent}\t\t') - lines.append(f'{indent}\t') + # Points — single object или массив (multi-series диаграмма) + pts = item.get('points') + if pts: + pts_list = pts if isinstance(pts, list) else [pts] + for pb in pts_list: + lines.append(f'{indent}\t') + emit_table_axis_block(lines, pb, f'{indent}\t\t') + lines.append(f'{indent}\t') - # Series - if item.get('series'): - lines.append(f'{indent}\t') - emit_table_axis_block(lines, item['series'], f'{indent}\t\t') - lines.append(f'{indent}\t') + # Series — single object или массив + srs = item.get('series') + if srs: + srs_list = srs if isinstance(srs, list) else [srs] + for sb in srs_list: + lines.append(f'{indent}\t') + emit_table_axis_block(lines, sb, f'{indent}\t\t') + lines.append(f'{indent}\t') # Selection (chart values) emit_selection(lines, item.get('selection'), f'{indent}\t') diff --git a/.claude/skills/skd-decompile/scripts/skd-decompile.ps1 b/.claude/skills/skd-decompile/scripts/skd-decompile.ps1 index ecfe6844..e5da7719 100644 --- a/.claude/skills/skd-decompile/scripts/skd-decompile.ps1 +++ b/.claude/skills/skd-decompile/scripts/skd-decompile.ps1 @@ -1,4 +1,4 @@ -# skd-decompile v0.73 — Decompile 1C DCS Template.xml to JSON DSL (draft) +# skd-decompile v0.74 — Decompile 1C DCS Template.xml to JSON DSL (draft) # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills param( [Parameter(Mandatory)] @@ -2118,10 +2118,26 @@ function Build-Structure { $entry = [ordered]@{ type = 'chart' } $nm = Get-Text $it "dcsset:name" if ($nm) { $entry['name'] = $nm } - $pn = $it.SelectSingleNode("dcsset:point", $ns) - if ($pn) { $entry['points'] = Build-TableAxisBlock -node $pn -loc "$loc/$idx/point" } - $sn = $it.SelectSingleNode("dcsset:series", $ns) - if ($sn) { $entry['series'] = Build-TableAxisBlock -node $sn -loc "$loc/$idx/series" } + # point/series — может быть несколько (multi-series диаграмма). + # Single → сохраняем как object (backward-compat); >1 → массив. + $pnList = $it.SelectNodes("dcsset:point", $ns) + if ($pnList.Count -eq 1) { + $entry['points'] = Build-TableAxisBlock -node $pnList[0] -loc "$loc/$idx/point" + } elseif ($pnList.Count -gt 1) { + $pArr = @() + $pi = 0 + foreach ($p in $pnList) { $pArr += (Build-TableAxisBlock -node $p -loc "$loc/$idx/point[$pi]"); $pi++ } + $entry['points'] = $pArr + } + $snList = $it.SelectNodes("dcsset:series", $ns) + if ($snList.Count -eq 1) { + $entry['series'] = Build-TableAxisBlock -node $snList[0] -loc "$loc/$idx/series" + } elseif ($snList.Count -gt 1) { + $sArr = @() + $si = 0 + foreach ($s in $snList) { $sArr += (Build-TableAxisBlock -node $s -loc "$loc/$idx/series[$si]"); $si++ } + $entry['series'] = $sArr + } $selN = $it.SelectSingleNode("dcsset:selection", $ns) $selI = Build-Selection -selNode $selN -loc "$loc/$idx/selection" if ($selI.Count -gt 0 -and -not ($selI.Count -eq 1 -and $selI[0] -eq 'Auto')) {