
コンバータ: #TSV 文字列 to #SVG ファイル
Converter: #TSV String to #SVG File
数値TSV文字列を「積み上げ棒グラフのSVGファイル」に変換します。TSVの1列目は「年月」や「四半期」などの集計単位として扱われます。また、TSVの1行目は「営業担当」や「取引先」といったデータ系列名として扱われます。
Configs for this Auto Step
- StrConfA
- A: TSV文字列をセットしてください *#{EL}
- StrConfB1
- B1: 表示幅ピクセル値(ユニット名・棒グラフ・合計値)をCSVでセットしてください(デフォルト: 60,360,60)#{EL}
- StrConfB2
- B2: 系列の色をCSVでセットしてください(デフォルト: “#e66,#39f,#f90,#a3c,…”)#{EL}
- StrConfB3
- B3: グラフ目盛りの最大値をセットしてください(デフォルト: 100)#{EL}
- StrConfB4
- B4: 目盛りとして表示する文字列をCSVでセットしてください(例: “0,50,100%”)#{EL}
- StrConfB5
- B5: 合計値の接頭辞・接尾辞をCSVでセットしてください(例: “¥,”, “,千円”)#{EL}
- BoolConfB6
- B6: 凡例 (色見本+系列名), 表示しない ⇔ 表示する
- BoolConfB7
- B7: 目盛りラベル, 表示しない ⇔ 表示する
- SelectConfC
- C: 生成されたSVGを格納するファイル型データを選択してください (追加) *
- StrConfB8
- B8: 生成されるSVGのファイル名をセットしてください(デフォルト: chart.svg)#{EL}
- SelectConfD1
- D1: TSV行数を格納する数値型データを選択してください (更新)
- SelectConfD2
- D2: TSV行数(空行を無視)を格納する数値型データを選択してください (更新)
Script (click to open)
// Script Example of Business Process Automation
// for 'engine type: 3' ("GraalJS standard mode")
main();
function main(){
//// == Config Retrieving / 工程コンフィグの参照 ==
const strTsv = configs.get ( "StrConfA" ); // REQUIRED
const arr2dTsv = parseAsRectangular( strTsv );
if( arr2dTsv.length === 0 ){
throw new Error( "\n AutomatedTask ConfigError: Config {A: TSV} is empty \n" );
}
if( arr2dTsv.length === 1 ){
throw new Error( "\n AutomatedTask ConfigError: Config {A: TSV} requires at least 2 lines (header and data) \n" );
}
const strWidths = configs.get ( "StrConfB1" ) || "60,360,60"; // default
const arrWidths = strWidths.split(",");
const numWidthUnit = parseInt (arrWidths[0], 10) || 60;
const numWidthBar = parseInt (arrWidths[1], 10) || 360;
const numWidthTotal = parseInt (arrWidths[2], 10) || 60;
const strColors = configs.get ( "StrConfB2" ) || "#e66,#39f,#f90,#a3c,#6a5,#678,#cc3,#999"; // default
const arrColors = strColors.split(",");
const strMaxScale = configs.get ( "StrConfB3" );
const numMaxScale = strMaxScale !== "" ? parseFloat(strMaxScale) : 100; // default 100
const strLabels = configs.get ( "StrConfB4" ) || "0,50,100%";
const arrLabels = strLabels.split(",");
const strPrefSuf = configs.get("StrConfB5") || ","; // デフォルトはカンマのみ
const arrPrefSuf = strPrefSuf.split(",");
const strPrefix = arrPrefSuf[0] || ""; // カンマの左側
const strSuffix = arrPrefSuf.length > 1 ? arrPrefSuf[1] : ""; // カンマの右側
const isShowLegend = configs.getObject ( "BoolConfB6" );
const isShowLabels = configs.getObject ( "BoolConfB7" );
const strFileName = configs.get ( "StrConfB8" ) || "chart.svg";
const filesPocketC = configs.getObject ( "SelectConfC" ); // REQUIRED
const numPocketD1 = configs.getObject ( "SelectConfD1" );
const numPocketD2 = configs.getObject ( "SelectConfD2" );
//// == Calculating / 演算 (SVG文字列の生成) ==
const marginL = 15; // 左側の余白
const marginR = 15; // 右側の余白
const svgTotalWidth = marginL + numWidthUnit + numWidthBar + numWidthTotal + marginR;
let svgY = 10; // Y座標の初期オフセット
let svgContent = `<style>text { font-family: sans-serif; font-size: 12px; fill: #333; }</style>\n`;
// XMLエスケープ用関数
function escapeXml(unsafe) {
return unsafe.replace(/[<>&'"]/g, function (c) {
switch (c) {
case '<': return '<';
case '>': return '>';
case '&': return '&';
case '\'': return ''';
case '"': return '"';
}
});
}
// --- 1. 凡例の描画 ---
if (isShowLegend) {
let lx = marginL;
for (let i = 1; i < arr2dTsv[0].length; i++) {
const color = arrColors[(i - 1) % arrColors.length];
const seriesName = escapeXml(arr2dTsv[0][i]);
// 簡易的な文字幅推測(長すぎたら改行)
const estimateW = seriesName.length * 12 + 25;
if (lx + estimateW > svgTotalWidth - marginR) {
lx = marginL;
svgY += 20;
}
svgContent += `<rect x="${lx}" y="${svgY}" width="10" height="10" fill="${color}" rx="2"/>\n`;
svgContent += `<text x="${lx + 16}" y="${svgY + 9}">${seriesName}</text>\n`;
lx += estimateW + 10;
}
svgY += 25; // 下部マージン
}
// --- 2. 目盛りの描画 ---
if (isShowLabels) {
const stepW = numWidthBar / (arrLabels.length - 1 || 1);
for (let i = 0; i < arrLabels.length; i++) {
const xPos = marginL + numWidthUnit + (stepW * i);
let anchor = i === 0 ? "start" : i === arrLabels.length - 1 ? "end" : "middle";
svgContent += `<text x="${xPos}" y="${svgY + 10}" fill="#777" text-anchor="${anchor}">${escapeXml(arrLabels[i])}</text>\n`;
}
svgY += 20;
}
// --- 3. 棒グラフの描画 ---
const rowHeight = 18; // 1行の高さ (MdChartの間隔に寄せるため短縮)
for (let i = 1; i < arr2dTsv.length; i++) {
// ユニット名(左側)
svgContent += `<text x="${marginL}" y="${svgY + 13}">${escapeXml(arr2dTsv[i][0])}</text>\n`;
// グラフ背景(グレー) ※MdChartに合わせて高さを10pxに変更
svgContent += `<rect x="${marginL + numWidthUnit}" y="${svgY + 4}" width="${numWidthBar}" height="10" fill="#eee" rx="2"/>\n`;
let currentX = marginL + numWidthUnit;
let totalValue = 0;
// 系列ごとの積み上げ描画
for (let j = 1; j < arr2dTsv[i].length; j++) {
const cellValue = parseFloat(arr2dTsv[i][j].replace(/[^0-9.-]/g, "")) || 0;
totalValue += cellValue;
const barW = Math.max(0, (cellValue / numMaxScale) * numWidthBar);
if (barW > 0) {
const color = arrColors[(j - 1) % arrColors.length];
svgContent += `<rect x="${currentX}" y="${svgY + 4}" width="${barW}" height="10" fill="${color}"/>\n`;
currentX += barW;
}
}
// 合計値(右側)
const totalStr = `${strPrefix}${totalValue.toLocaleString()}${strSuffix}`;
svgContent += `<text x="${marginL + numWidthUnit + numWidthBar + 10}" y="${svgY + 13}" text-anchor="start">${escapeXml(totalStr)}</text>\n`;
svgY += rowHeight; // 次の行へY座標を移動
}
// --- 4. 全体をSVGタグでラップ ---
const finalSvgHeight = svgY + 10;
let strSvg = `<?xml version="1.0" encoding="UTF-8"?>\n`;
strSvg += `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 ${svgTotalWidth} ${finalSvgHeight}" width="${svgTotalWidth}" height="${finalSvgHeight}">\n`;
strSvg += `<rect width="100%" height="100%" fill="#ffffff"/>\n`; // 背景の透過防止用白塗り
strSvg += svgContent;
strSvg += `</svg>`;
//// == Data Updating / ワークフローデータへの代入 ==
// SVGファイルの保存 (C)
if (filesPocketC !== null) {
let filesSvg = engine.findData(filesPocketC);
if (filesSvg === null) {
filesSvg = new java.util.ArrayList();
}
// 指定されたファイル名、なければ "chart.svg"
let finalFileName = strFileName;
if (!finalFileName.toLowerCase().endsWith(".svg")) {
finalFileName += ".svg";
}
filesSvg.add(
new com.questetra.bpms.core.event.scripttask.NewQfile(
finalFileName,
"image/svg+xml; charset=UTF-8",
strSvg
)
);
engine.setData(filesPocketC, filesSvg);
}
// オリジナルのTSV文字列の行数 (D1)
if ( numPocketD1 !== null) {
const totalLines = strTsv.split("\n").length;
engine.setData( numPocketD1, new java.math.BigDecimal(totalLines) );
}
// 空行を除いたTSV行数 (D2)
if ( numPocketD2 !== null) {
engine.setData( numPocketD2, new java.math.BigDecimal(arr2dTsv.length) );
}
} //////// END "main()" /////////////////////////////////////////////////////////////////
/**
* Parses TSV string as a two-dimensional rectangular data matrix and creates a 2D array.
* @param {string} strTsv - The input TSV string
* @returns {Array<Array<string>>} Rectangular 2D array
*/
function parseAsRectangular( strTsv ){
const arrTsv = strTsv.split("\n");
let numMinWidth = Infinity;
let numMaxWidth = 0;
let numBlanklines = 0;
const parsedRows = [];
for( let i = 0; i < arrTsv.length; i++ ){
const line = arrTsv[i];
if( line === "" ){
numBlanklines++;
continue;
}
const arrCells = line.split("\t");
const len = arrCells.length;
if( len < numMinWidth ){ numMinWidth = len; }
if( len > numMaxWidth ){ numMaxWidth = len; }
parsedRows.push( arrCells );
}
if( numMinWidth === Infinity ){
numMinWidth = 0;
}
engine.log( " AutomatedTask TsvDataCheck:" +
" MinWidth:" + numMinWidth +
" MaxWidth:" + numMaxWidth +
" Lines:" + arrTsv.length +
" (BlankLines:" + numBlanklines + ")" );
for( let i = 0; i < parsedRows.length; i++ ){
const row = parsedRows[i];
while( row.length < numMaxWidth ){
row.push( "" );
}
}
return parsedRows;
}
/*
### NOTES-en
- A bar chart (SVG file) is automatically generated each time a Case reaches this Automated Step.
- From the second row of the input TSV string onward, all fields are parsed as "numeric strings", except for the first column (Column A).
- Only the first column (Column A) is considered as the aggregation unit name, such as "YYYY-MM" or "Quarter".
- If characters other than a "period (.)", a "minus sign (-)", and "0-9" exist, the "stripped string" is parsed.
- Even if commas exist, they are considered thousands separators, and the "stripped string" is parsed.
- The "stripped string" is parsed using `parseFloat()`.
- If parsing fails, the value is evaluated as `0`.
- The generated "SVG file" will be added to the specified File-type data item.
- For an N-row, 2-column TSV string, a simple bar chart is displayed (e.g., "Monthly Sales").
- For an N-row, M-column TSV string, a stacked bar chart with (M-1) "series" is displayed.
- The width of each series is calculated and drawn based on the "Max Scale Value (B3)".
- The input TSV is parsed as the "simplest tab-separated string".
- The number of lines in the input TSV string can also be saved as Case Data.
### NOTES-ja
- このアドオン自動工程にケース(案件)が到達する度に、自動的に棒グラフ(SVGファイル)が生成されます。
- 入力TSV文字列の2行目以降は、全フィールドが「数値文字列」として解析されます。※1列目(A列)を除く
- 1列目(A列)だけは、「年月」や「四半期」などの集計単位名とみなされます。
- 「ピリオド(.)」と「マイナス記号」と「0~9」以外の文字が存在する場合、「除去された文字列」が解析されます。
- カンマが存在する場合も、(桁区切り文字とみなされ)、「除去された文字列」が解析されます。
- 「除去された文字列」が `parseFloat()` によって解析されます。
- 解析に失敗した場合 `0` とみなされます。
- 生成された "SVGファイル" は、指定されたファイル型データ項目に追加保存されます。
- N行2列TSV文字列の場合、シンプル棒グラフが表示されます。 ※「月ごとの売上」など
- N行M列TSV文字列の場合、"系列" が (M-1) 個の積み上げ棒グラフが表示されます。
- 各系列の横幅は「グラフ目盛りの最大値(B3)」を基準に算出・描画されます。
- 入力TSVは「もっともシンプルなタブ区切り文字列」としてパースされます。
- 入力TSV文字列の行数もケースデータとして格納可能です。
#### TSV example
YYYY-MM Tanaka Sato Suzuki Yamada
2026-01 610,000 520,000 380,000 450,000
2026-02 580,000 490,000 410,000 480,000
2026-03 700,000 600,000 450,000 550,000
2026-04 550,000 480,000 390,000 420,000
2026-05 590,000 510,000 420,000 460,000
2026-06 630,000 550,000 460,000 510,000
2026-07 680,000 620,000 250,000 280,000
2026-08 570,000 530,000 230,000 290,000
2026-09 650,000 310,000 220,000 250,000
2026-10 560,000 290,000 240,000 270,000
2026-11 600,000 300,000 250,000 260,000
2026-12 800,000 720,000 600,000 680,000
### APPENDIX-en
- Blank lines within the input TSV string are ignored.
- Please set series colors corresponding to the number of series in the TSV (TSV column count - 1).
- (It is fine to set more colors than required)
- Example of high-contrast series colors: "#e66,#39f,#f90,#a3c,#6a5,#678,#cc3,#999".
- Example of warm/cool color gradation: "#c42,#e84,#fb6,#cc3,#6ad,#9cf,#cde,#eef".
- Special characters like `<`, `>`, `&` in the TSV string will be automatically XML-escaped to prevent SVG file corruption.
- You can specify a prefix and suffix for the total value.
- To add only a prefix: Set `$,` → `$1,200,000`
- To add only a suffix: Set `, items` → `150 items`
- To add both: Set `Approx. , hours` → `Approx. 40 hours`
- To include a space: Set `$ ,` → `$ 1,200`
### APPENDIX-ja
- 入力TSV文字列内の空行は無視されます。
- 系列の色は、TSV内の系列の数(TSV列数 - 1)だけセットしてください。(多く設定する分には構いません)
- 系列のメリハリを効かせる例: "#e66,#39f,#f90,#a3c,#6a5,#678,#cc3,#999"
- 寒色暖色でグラデーション例: "#c42,#e84,#fb6,#cc3,#6ad,#9cf,#cde,#eef"
- TSV内の `<` や `&` といった特殊記号は、SVGファイルの破損を防ぐために自動的にXMLエスケープされます。
- 合計値には接頭辞・接尾辞を指定できます。
- 前だけにつけたい場合: `¥,` と設定 → `¥1,200,000`
- 後ろだけにつけたい場合: `,件` と設定 → `150件`
- 前後両方につけたい場合: `約,時間` と設定 → `約40時間`
- 間にスペースを入れたい場合: `$ ,` と設定 → `$ 1,200`
*/
Download
- converter-tsv-string-to-svg-file-2026.xml
- 2026-06-17 (C) Questetra, Inc. (MIT License)
自由改変可能な JavaScript (ECMAScript) コードです。いかなる保証もありません。
(アドオン自動工程のインストールは Professional editionでのみ可能です)
(アドオン自動工程のインストールは Professional editionでのみ可能です)
Notes
- このアドオン自動工程にケース(案件)が到達する度に、自動的に棒グラフ(SVGファイル)が生成されます。
- 入力TSV文字列の2行目以降は、全フィールドが「数値文字列」として解析されます。※1列目(A列)を除く
- 1列目(A列)だけは、「年月」や「四半期」などの集計単位名とみなされます。
- 「ピリオド(.)」と「マイナス記号」と「0~9」以外の文字が存在する場合、「除去された文字列」が解析されます。
- カンマが存在する場合も、(桁区切り文字とみなされ)、「除去された文字列」が解析されます。
- 「除去された文字列」が
parseFloat()によって解析されます。 - 解析に失敗した場合
0とみなされます。
- 生成された “SVGファイル” は、指定されたファイル型データ項目に追加保存されます。
- N行2列TSV文字列の場合、シンプル棒グラフが表示されます。 ※「月ごとの売上」など
- N行M列TSV文字列の場合、”系列” が (M-1) 個の積み上げ棒グラフが表示されます。
- 各系列の横幅は「グラフ目盛りの最大値(B3)」を基準に算出・描画されます。
- 入力TSV文字列の2行目以降は、全フィールドが「数値文字列」として解析されます。※1列目(A列)を除く
- 入力TSVは「もっともシンプルなタブ区切り文字列」としてパースされます。
- 入力TSV文字列の行数もケースデータとして格納可能です。
Capture





Appendix
- 入力TSV文字列内の空行は無視されます。
- 系列の色は、TSV内の系列の数(TSV列数 – 1)だけセットしてください。(多く設定する分には構いません)
- 系列のメリハリを効かせる例: “#e66,#39f,#f90,#a3c,#6a5,#678,#cc3,#999”
- 寒色暖色でグラデーション例: “#c42,#e84,#fb6,#cc3,#6ad,#9cf,#cde,#eef”
- TSV内の
<や&といった特殊記号は、SVGファイルの破損を防ぐために自動的にXMLエスケープされます。 - 合計値には接頭辞・接尾辞を指定できます。
- 前だけにつけたい場合:
¥,と設定 →¥1,200,000 - 後ろだけにつけたい場合:
,件と設定 →150件 - 前後両方につけたい場合:
約,時間と設定 →約40時間 - 間にスペースを入れたい場合:
$ ,と設定 →$ 1,200
- 前だけにつけたい場合:



