
Converter: #TSV String to #MdChart String
Converts a numeric TSV string into a Markdown-embeddable stacked bar chart (MdChart). The first TSV column is used as the aggregation unit, such as “YYYYMM”, and the first row as data series, such as “Sales Representative” or “Client”.
Configs for this Auto Step
- StrConfA
- A: Set TSV String *#{EL}
- StrConfB1
- B1: Set Pixel Widths (Unit Bar Total) as CSV (default:60,360,60)#{EL}
- StrConfB2
- B2: Set Series Color in CSV (default: “#e66,#39f,#f90,#a3c,…”)#{EL}
- StrConfB3
- B3: Set Max Scale Value (default: 100)#{EL}
- StrConfB4
- B4: Set Scale Labels in CSV (eg. “0,50,100%”)#{EL}
- StrConfB5
- B5: Set Value Prefix/Suffix in CSV (eg. “$,”, “,usd”)#{EL}
- BoolConfB6
- B6: Legend (Color Marker + Series Name), Hide or Show
- BoolConfB7
- B7: Scale Labels, Hide or Show
- SelectConfC
- C: Select DATA to store Converted Markdown String (update) *
- StrConfB8
- B8: Set Max Num of MdChart String (default: 8000)#{EL}
- SelectConfD1
- D1: Select NUMERIC for Number of TSV Lines (update)
- SelectConfD2
- D2: Select NUMERIC for TSV Rows (ignore blanks) (update)
Script (click to open)
// Script Example of Business Process Automation
// for 'engine type: 3' ("GraalJS standard mode")
//////// START "main()" /////////////////////////////////////////////////////////////////
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 numMaxLength = parseInt(configs.get("StrConfB8" ), 10) || 8000;
const strPocketC = configs.getObject ( "SelectConfC" );
const numPocketD1 = configs.getObject ( "SelectConfD1" );
const numPocketD2 = configs.getObject ( "SelectConfD2" );
//// == Data Retrieving / ワークフローデータの参照 ==
// (Nothing. Retrieved via Expression Language in Config Retrieving)
//// == Calculating / 演算 ==
let strMarkdown = "";
// 凡例の表示
if (isShowLegend) {
for (let i = 1; i < arr2dTsv[0].length; i++) {
const color = arrColors[(i - 1) % arrColors.length]; // 色の数が足りない場合はループさせる
strMarkdown += `<span style="color:${color}">■${arr2dTsv[0][i]}</span> `;
}
strMarkdown += "\n";
}
// 目盛りの表示
if (isShowLabels) {
strMarkdown += `<div style="display:flex;color:#777"><span style="display:inline-block;width:${numWidthUnit}px"></span>`;
strMarkdown += `<span style="display:flex;width:${numWidthBar}px;justify-content:space-between">`;
for (let i = 0; i < arrLabels.length; i++) {
strMarkdown += `<span>${arrLabels[i]}</span>`;
}
strMarkdown += `</span><span style="display:inline-block;width:${numWidthTotal}px"></span></div>`;
strMarkdown += "\n";
}
// 棒グラフの表示
for (let i = 1; i < arr2dTsv.length; i++) {
let strRow = ""; // 1行分の文字列を一時保存する変数
// ユニット名
strRow += `<div style="display:flex;align-items:center"><span style="display:inline-block;width:${numWidthUnit}px">`;
strRow += arr2dTsv[i][0];
strRow += `</span>`;
// 一本の棒グラフ(背景)
strRow += `<span style="display:inline-block;width:${numWidthBar}px;background:#eee">`;
strRow += `<span style="display:flex;width:100%;height:10px">`;
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 barRatio = Math.max(0, cellValue / numMaxScale);
const color = arrColors[(j - 1) % arrColors.length];
strRow += `<span style="flex:${barRatio};background:${color}"></span>`;
}
// 一本の棒グラフ: グラフ部分を閉じる
strRow += `<span style="flex:${Math.max(0, 1 - (totalValue / numMaxScale))}"></span>`;
strRow += `</span></span>`;
// 一本の棒グラフの横に積み上げ合計値
strRow += `<span style="display:inline-block;width:${numWidthTotal}px;text-align:right">${strPrefix}${totalValue.toLocaleString()}${strSuffix}</span></div>`;
strRow += "\n";
// 文字数制限チェック (B8)
// 現在の文字列と追加予定の行の文字数を足して、上限を超えるなら追加せずにループを終了
if (strMarkdown.length + strRow.length > numMaxLength) {
engine.log(`Warning: Reached Max Length (${numMaxLength}) at row ${i}. Stopping chart generation to prevent unclosed HTML tags.`);
break;
}
// 制限内に収まる場合のみ全体文字列に追加
strMarkdown += strRow;
}
//// == Data Updating / ワークフローデータへの代入 ==
if ( strPocketC !== null) {
engine.setData( strPocketC, strMarkdown );
}
// オリジナルの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;
// Step 1: パースと最大最小幅算出を1度のループで / Parse and Calc max-min widths in single loop
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 );
}
// 全て空行だった場合のフェイルセーフ / Fail-safe in case all lines are blank
if( numMinWidth === Infinity ){
numMinWidth = 0;
}
engine.log( " AutomatedTask TsvDataCheck:" +
" MinWidth:" + numMinWidth +
" MaxWidth:" + numMaxWidth +
" Lines:" + arrTsv.length +
" (BlankLines:" + numBlanklines + ")" );
// Step 2: 矩形へ整形 (不足列に "") / Format into rectangle (fill in missing columns with "")
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 (MdChart string) 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 "MdChart string" is an HTML string where `div` and `span` elements are arranged using flexbox.
- 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.
- If the stacked total value exceeds the "Max Scale Value (B3)", the chart will be automatically scaled down to fit exactly within the chart width (100%) while maintaining the ratio of each series (no blank space will be displayed on the right).
- The input TSV is parsed as the "simplest tab-separated string".
- Double quotes and other characters within the TSV string are retained as is.
- The number of lines in the input TSV string can also be saved as Case Data.
### NOTES-ja
- このアドオン自動工程にケース(案件)が到達する度に、自動的に棒グラフ(MdChart文字列)が生成されます。
- 入力TSV文字列の2行目以降は、全フィールドが「数値文字列」として解析されます。※1列目(A列)を除く
- 1列目(A列)だけは、「年月」や「四半期」などの集計単位名とみなされます。
- 「ピリオド(.)」と「マイナス記号」と「0~9」以外の文字が存在する場合、「除去された文字列」が解析されます。
- カンマが存在する場合も、(桁区切り文字とみなされ)、「除去された文字列」が解析されます。
- 「除去された文字列」が `parseFloat()` によって解析されます。
- 解析に失敗した場合 `0` とみなされます。
- "MdChart文字列" は `div` と `span` が flex 配置されたHTML文字列です。
- N行2列TSV文字列の場合、シンプル棒グラフが表示されます。 ※「月ごとの売上」など
- N行M列TSV文字列の場合、"系列" が (M-1) 個の積み上げ棒グラフが表示されます。
- 積み上げ合計値が「グラフ目盛りの最大値(B3)」を超えた場合、縮小して表示されます。
- グラフの表示幅(100%)にぴったり収まるよう、各系列の比率を維持したまま、縮小されます。
- 右側の余白は生成されません。
- 入力TSVは「もっともシンプルなタブ区切り文字列」としてパースされます。
- 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".
- Blank lines within the input TSV string are ignored regarding the character limit for the MdChart string.
- 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"
- MdChart文字列の文字数制限は、入力TSV文字列内の空行は無視されます。
- 合計値には接頭辞・接尾辞を指定できます。
- 前だけにつけたい場合: `¥,` と設定 → `¥1,200,000`
- 後ろだけにつけたい場合: `,件` と設定 → `150件`
- 前後両方につけたい場合: `約,時間` と設定 → `約40時間`
- 間にスペースを入れたい場合: `$ ,` と設定 → `$ 1,200`
*/
Download
- converter-tsv-string-to-markdown-chart-2026.xml
- 2026-06-15 (C) Questetra, Inc. (MIT License)
Freely modifiable JavaScript (ECMAScript) code. No warranty of any kind.
(Installing Addon Auto-Steps are available only on the Professional edition.)
(Installing Addon Auto-Steps are available only on the Professional edition.)
Notes
- A bar chart (MdChart string) 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 “MdChart string” is an HTML string where
divandspanelements are arranged using flexbox.- 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.
- If the stacked total value exceeds the “Max Scale Value (B3)”, the chart will be automatically scaled down to fit exactly within the chart width (100%) while maintaining the ratio of each series (no blank space will be displayed on the right).
- From the second row of the input TSV string onward, all fields are parsed as “numeric strings”, except for the first column (Column A).
- The input TSV is parsed as the “simplest tab-separated string”.
- Double quotes and other characters within the TSV string are retained as is.
- The number of lines in the input TSV string can also be saved as Case Data.
Capture





Appendix
- 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”.
- Blank lines within the input TSV string are ignored regarding the character limit for the MdChart string.
- 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
- To add only a prefix: Set



