Files
timeline-svg/example/template-v2.svg
tegwick 2bab447fa8 refactor: use abstract ITEM placeholders with dynamic property mapping
Changed from fixed TASK placeholders to flexible ITEM placeholders that
automatically map all CSV fields to template placeholders.

Key changes:
- Renamed task-template → item-template in all templates
- Changed TASK_* → ITEM_* placeholder naming
- Implemented dynamic placeholder generation from item properties
- Any field in fieldMapping now creates ITEM_{FIELD} placeholder
- Updated all tests and documentation

Naming convention: CSV field → item.property → ITEM_PROPERTY
Example: "assignee" → item.assignee → {{ITEM_ASSIGNEE}}

This enables users to add custom fields without modifying generator code:
- Add "assignee": "Assignee" to fieldMapping
- Use {{ITEM_ASSIGNEE}} in template
- No code changes required

Benefits:
- More flexible and extensible
- Clearer abstraction (items vs tasks)
- Consistent naming convention
- Better documented

All 56 tests passing.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-27 23:17:34 +01:00

82 lines
3.5 KiB
XML

<svg xmlns="http://www.w3.org/2000/svg" style="background: linear-gradient(135deg, #f0f9f4 0%, #e6f7ea 100%);">
<defs>
<!-- Enhanced month indicator styling -->
<linearGradient id="monthHeaderGrad" x1="0%" y1="0%" x2="0%" y2="100%">
<stop offset="0%" style="stop-color:#2d8659;stop-opacity:0.15"/>
<stop offset="100%" style="stop-color:#4a9b6b;stop-opacity:0.08"/>
</linearGradient>
<!-- Drop shadow for month labels -->
<filter id="textShadow" x="-50%" y="-50%" width="200%" height="200%">
<feDropShadow dx="1" dy="1" stdDeviation="1.5" flood-color="#2d8659" flood-opacity="0.4"/>
</filter>
<!-- Subtle background grid pattern -->
<pattern id="bgGrid" width="40" height="40" patternUnits="userSpaceOnUse">
<rect width="40" height="40" fill="transparent"/>
<circle cx="20" cy="20" r="1" fill="#4a9b6b" opacity="0.1"/>
</pattern>
<!-- Template elements (hidden, will be cloned) -->
<g id="month-template" style="display: none;">
<line x1="{{MONTH_X}}" y1="{{GRID_TOP}}" x2="{{MONTH_X}}" y2="{{GRID_BOTTOM}}"
stroke="#4a9b6b" stroke-width="2" opacity="0.6"/>
<rect x="{{MONTH_X_OFFSET}}" y="{{MONTH_LABEL_Y_OFFSET}}" width="60" height="25"
fill="#2d8659" opacity="0.1" rx="4"/>
<text x="{{MONTH_TEXT_X}}" y="{{MONTH_LABEL_Y}}" fill="#2d8659"
font-size="13" font-weight="600">{{MONTH_LABEL}}</text>
<rect x="{{MONTH_SEP_X}}" y="{{GRID_TOP}}" width="2" height="{{GRID_HEIGHT}}"
fill="#4a9b6b" opacity="0.3"/>
</g>
<g id="lane-template" style="display: none;">
<rect x="{{LANE_X}}" y="{{LANE_Y}}" width="{{LANE_WIDTH}}" height="{{LANE_HEIGHT}}"
fill="rgba(255,255,255,0.7)" stroke="#4a9b6b" stroke-width="1" opacity="0.5" rx="8"/>
<text x="{{LABEL_X}}" y="{{LABEL_Y}}" fill="#2d8659"
font-size="14" font-weight="700">{{LANE_NAME}}</text>
</g>
<g id="item-template" style="display: none;">
<circle cx="{{ITEM_X}}" cy="{{ITEM_Y}}" r="6"
fill="#2d8659" stroke="#4a9b6b" stroke-width="2"/>
<text x="{{TEXT_X}}" y="{{TEXT_Y}}" font-size="12" fill="#2d8659" font-weight="500">
<tspan class="item-id">{{ITEM_ID}}: </tspan>
<tspan class="item-title" fill="#1e5a3d">{{ITEM_TITLE}}</tspan>
</text>
</g>
</defs>
<!-- Background with subtle pattern -->
<rect width="100%" height="100%" fill="url(#bgGrid)"/>
<!-- Enhanced month header background -->
<rect x="0" y="0" width="100%" height="130" fill="url(#monthHeaderGrad)"
stroke="#2d8659" stroke-width="1" opacity="0.6"/>
<!-- Title area with visual indicator -->
<rect x="10" y="10" width="300" height="60" fill="#ffffff"
stroke="#2d8659" stroke-width="2" rx="8" opacity="0.9"/>
<text x="20" y="35" fill="#2d8659" font-size="16" font-weight="bold" filter="url(#textShadow)">
📊 Template V2 Active
</text>
<text x="20" y="55" fill="#4a9b6b" font-size="11" font-weight="500">
Template-based rendering with cloned elements ✨
</text>
<!-- Month indicators with enhanced styling -->
<g class="enhanced-months" transform="translate(0,0)">
<rect x="0" y="75" width="100%" height="55" fill="rgba(45, 134, 89, 0.05)"
stroke="#4a9b6b" stroke-width="1"/>
{{MONTHS}}
</g>
<!-- Lane content -->
<g class="enhanced-lanes">
{{LANES}}
</g>
<!-- Decorative border -->
<rect x="1" y="1" width="calc(100% - 2)" height="calc(100% - 2)"
fill="none" stroke="#2d8659" stroke-width="2" rx="4" opacity="0.7"/>
</svg>