InDesignで円グラフを作成する(1)

久々にスクリプト作成中。今回は仕事に使うものなので、完成形は公開できません。なので作りかけのものを公開しますが、これだけでもそれらしく動くので、試してみたい方はどうぞ。

今回はソースコードだけです。次回以降解説しますが、毎度尻切れトンボになるので期待しないでください。

title = "グラフタイトル";
vals = [30, 25, 20, 15, 5, 3, 1, 1]; //パーセンテージ
var r = 30; //半径
var s = 2; //グラフ周囲のアキ
var tw = 6; //数値の枠の幅
var th = 2; //数値の枠の高さ
//円グラフの中心位置
//CS5で回転をトラブルなく行うには座標をページの左端中央にする
var x = 0;
var y = (app.activeWindow.activePage.bounds[2] -
    app.activeWindow.activePage.bounds[0]) / 2;
app.activeWindow.transformReferencePoint = [x, y];
var d = 0.552284746666667; //Directionの定数(半径を1)
var pp1 = new Array(); //半円、[[左], [アンカー], [右]]
pp1.push([[x, y+r], [x, y+r], [x+r*d, y+r]]);
pp1.push([[x+r, y+r*d], [x+r, y], [x+r, y-r*d]]);
pp1.push([[x+r*d, y-r], [x, y-r], [x, y-r]]);
var r2 = r * 1.1;
var pp2 = new Array(); //半円マスク
pp2.push([[x, y+r2], [x, y+r2], [x+r2*d, y+r2]]);
pp2.push([[x+r2, y+r2*d], [x+r2, y], [x+r2, y-r2*d]]);
pp2.push([[x+r2*d, y-r2], [x, y-r2], [x, y-r2]]);
var pp3 = new Array(); //引き出し線
pp3.push([x, y-r*0.9]);
pp3.push([x, y-r*1.1]);
pp3.push([x, y-r*1.2]);
var doc = app.activeDocument;
var ttxf = doc.textFrames.add();
ttxf.geometricBounds = [y-40, x-r, y-34, x+r];
ttxf.contents = title;
var ovl = doc.ovals.add();
ovl.geometricBounds = [y-r, x-r, y+r, x+r];
var grp = doc.groups.add([ttxf, ovl]);
ref = 0;
for (i=0; i<vals.length; i++){
    if (vals[i]>100 || vals[i]<=0) {
        alert("値が0以下か100を超えています");
        exit();
    }
    if (vals[i]==100) {
        var txf = grp.textFrames.add();
        //txf.appliedObjectStyle = "";
        txf.contents = vals[i] + "%";
        txf.geometricBounds = [y-th/2, x-tw/2, y+th/2, x+tw/2];
        break;
    }
    //扇形
    fan = grp.ovals.add();
    fan.paths[0].entirePath = pp1;
    if (vals[i]<50){
        msk = grp.ovals.add();
        msk.paths[0].entirePath = pp2;
        msk.rotationAngle = vals[i] * -3.6; fan = msk.subtractPath(fan);
    } else if (vals[i]>50){
        msk = grp.ovals.add();
        msk.paths[0].entirePath = pp2;
        msk.rotationAngle = (vals[i] - 50) * -3.6;
        fan = msk.subtractPath(fan);
        fan.rotationAngle = -180;
        fan2 = grp.ovals.add();
        fan2.paths[0].entirePath = pp1;
        fan = fan.addPath(fan2);
    }
    fan.rotationAngle = ref * -3.6;
    fan.strokeColor = doc.swatches[3];
    //数値および引き出し線
    if (vals[i] < 3) {
        var ln = grp.graphicLines.add();
        ln.paths[0].entirePath = pp3;
        ln.rotationAngle = (ref + vals[i] / 2) * -3.6;
        ln.strokeColor = doc.swatches[3];
        var txf = grp.textFrames.add();
        //txf.appliedObjectStyle = "";
        txf.contents = vals[i] + "%";
        if (ln.paths[0].pathPoints[2].anchor[0] > x){
            ln.paths[0].pathPoints[2].anchor =
                [x + r + s, ln.paths[0].pathPoints[1].anchor[1]];
            txf.geometricBounds =
                [ln.paths[0].pathPoints[1].anchor[1]-1, x+r+s,
                ln.paths[0].pathPoints[1].anchor[1]+1, x+r+s+tw];
        } else {
            ln.paths[0].pathPoints[2].anchor =
                [x-r-s, ln.paths[0].pathPoints[1].anchor[1]];
            txf.geometricBounds =
                [ln.paths[0].pathPoints[1].anchor[1]-1, x-r-s-tw,
            ln.paths[0].pathPoints[1].anchor[1]+1, x-r-s];
        }
    } else {
        var txf = grp.textFrames.add();
        //txf.appliedObjectStyle = "";
        txf.contents = vals[i] + "%";
        txf.geometricBounds =
            [y-r*0.8, x-tw/2, y-r*0.8+th, x+tw/2];
        txf.rotationAngle = (ref + vals[i] / 2) * -3.6;
        app.activeWindow.transformReferencePoint = AnchorPoint.CENTER_ANCHOR;
        txf.rotationAngle = 0;
        app.activeWindow.transformReferencePoint = [x, y];
    }
    //次へ
    ref = ref + vals[i];
}