グラフ付HTMLダイアログ

サマリー

このチュートリアルでは以下のようにダイアログ機能を構築します。

  1. ダイアログには3つのパネルがあります。このうち、左のパネルにテキストボックス、中央パネルにグラフがあり、右のパネルはブランクになっています。
  2. 手動でグラフに垂直線を移動すると、プログラムによってテキストボックスにXの値が表示されます。
  3. また、テキストボックスのXの値を入力してEnterキーを押すと、プログラムによって垂直線は指定した位置に移動します。

ここでは、以下の項目を解説します。

  1. HTMLダイアログでグラフを含む方法
  2. 好きなようにダイアログのサイズを変更する方法
  3. JavaScriptでOriginCを呼び出す方法(チュートリアル計算機の作成にも解説があります。
  4. Origin CでJavaScriptを呼び出す

このチュートリアルを終えると、異なる番号を除いて以下の画像のようにダイアログが表示されます。

Result.png

必要なOriginのバージョン: Origin 2017 以降

サンプルファイル

  1. Composite Spectrum.opj: このOPJにはダイアログに表示されるグラフを含んでいます。
  2. index.html: htmlページのHTMLコード
  3. DlgWithGraph.cpp: HTMLダイアログを呼び出して、OriginCとJacaScriptの連携を行うOriginCのコードです。
  4. Background_image1.png: ダイアログの背景用の最初の画像です。
  5. Background_image2.jpg: ダイアログの背景用の二番目の画像です。
Note: こちらから、サンプルファイルをダウンロードできます。

準備

  1. 「Composite Spectrum.opj」というOriginのプロジェクトを作成して、「HTML Dialog with A Graph」フォルダに保存します。
  2. Originのメニューからファイル: インポート: 単一ASCII を選択して「\Samples\Curve Fitting」にあるデータ「Composite Spectrum.dat」をインポートします。
  3. 列Bから列Dを選択して、メニューから作図>2D: 複数Y軸軸: Yオフセット付き積み上げ折れ線を選択して折れ線グラフを作成します。
  4. Graph1をダブルクリックして作図の詳細ダイアログを開き、Graph 1のフォーマットを変更します。
  5. 直線ツールボタンButton Line Tool.pngをクリックしてグラフに垂直線を追加します。(SHIFTキーを押して描画します。
  6. 垂直線を右クリックして、コンテキストメニューからプロパティを選択します。
  7. のタブと矢印のタブを開いて、垂直線の形式を変更し、サイズタブで水平移動のみが有効になるように設定します。
    Line Properties.png
  8. プログラミングのタブでオブジェクトにLineという名前を付けます。
  9. のあとでスクリプトを実行のドロップダウンリストから移動を選択して、テキストボックスに以下のLabTalkスクリプトを入力します。
    line_move(this.X);
            
    
    Line Programming Tab.png
    Note: 垂直線を移動する場合、この手順で関数 line_move()のトリガを設定します。この関数line_move()は、後程、OriginCで作成します。
  10. コードビルダを開き、ワークスペースウィンドウのプロジェクトフォルダを開きます。「ProjectEvents.OGS」をダブルクリックしてファイルを開き、[AfterOpenDoc]のセクションにスクリプトを追加します。
    if(run.LoadOC("%X\DlgWithGraph.cpp", 16) == 0)
    {
        @G=0;//両サイドに灰色のバンドが無くなるようにグラフの背景を塗りつぶし
        HTMLandGraphDlgEx; //ダイアログを立ち上げる関数
    }
    else
    {
       type "Failed to load the dialog!";
       return 0;
    }
    
    Note: Originのプロジェクトを開いた後、このスクリプトによりダイアログが起動します。ProjectEvents スクリプトについての詳細はこちらをご覧ください。
  11. コードビルダのProjectEvents.OGSを保存して、Originにプロジェクトを保存します。

ダイアログ用のHTMLページの作成

HTMLダイアログを作成する際には、まず初めにHTMLページを作成します。

  1. 「HTML Dialog with A Graph」フォルダに背景用の画像を2つ用意します。
  2. コードビルダを開き、新しいHTMLファイルを作成して、「index.html」という名前で「HTML Dialog with A Graph」フォルダに保存します。
  3. 以下のコードをコピーして「index.html」内に貼り付けます。
    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="utf-8" />
            <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
                <style>
                body{
                    background-image:url("background_image1.png")
                }
                input[type="text"] {
                    font-size: 14px;
                }
                input[type="text"]:focus {
                    outline: none;
                }
                .style-2 input[type="text"] {
                    padding: 3px;
                    border: solid 5px #c9c9c9;
                    transition: border 0.3s;
                }
                .style-2 input[type="text"]:focus,
                .style-2 input[type="text"].focus {
                    border: solid 5px #969696;
                }               
                #container {
                    border: 3px solid #ffffff;
                    position: absolute;
                    left: 0;
                    right: 0;
                    bottom: 0;
                    top: 0;
                }
                #leftcontainer {
                    border-right: 3px solid #ffffff;
                    width: 250px;
                    height: 100%;
                    float: left;
                }
                #rightcontainer {
                    border-left: 3px solid #ffffff;
                    width: 250px;
                    height: 100%;
                    float: right;
                    text-align: center;
                }
            </style>                
        </head>
        <body>
            <div id="container">
                <div id="leftcontainer">
                    <h2><font color="ffffff">X-Value</font></h2>
                    <ul class="input-list style-2 clearfix">
                        <input type="text" name="XValue"  id="X" placeholder="X"  onkeydown = "">
                    </ul>
                    <p><font color="ffffff">*Move the vertical line in graph, and get the x-value and y-values.</font></p>
                    <p><font color="ffffff">*Enter x-value in textbox and hit ENTER key, then the vetical line will move to the specified position.</font></p>
                </div>
     
                <div id="rightcontainer">
                    <h3> &nbsp </h3>
                    <h3> &nbsp </h3>
                    <h3><font color="ffffff">You can place other controls on this side.</font></h3>
                </div>
            </div>
        </body>
    </html>
            
    

この手順を終了すると、ウェブブラウザで「index.html」が開き、以下のページが表示されます。

HTMLInit.png

ダイアログ用のJavaScriptコードの追加

この手順で、JavaScriptコードを追加します。

  1. 以下のJavaScriptコードをコピーしてhtmlファイルの<script>内に貼りつけます。
    <script>
        var vbg = 1;//html背景を交換する
        function lineMove(xVal) 
        {
            var XValue = document.getElementById("X");
            XValue.value = xVal;
            //html背景を変更を表示し、グラフには影響しない。
            switch (vbg)
            {
                case 1:
                    document.body.style.backgroundImage = "URL(&apos;background_image2.jpg&apos;)";
                    vbg = 2;
                break;
                case 2:
                    document.body.style.backgroundImage = "URL(&apos;background_image1.png&apos;)";
                    vbg = 1;
                break;
            }
        }
                            
        function enterXval()
        {
            var XValue = document.getElementById("X");                      
            window.external.ExtCall("OnEnterXvalToUpdateGraph", XValue.value);
        }
                                                                                                    
        function getGraphRect()
        {                  
            var leftDiv = document.getElementById("leftcontainer");
            var leftpos = leftDiv.getBoundingClientRect().right;
            var toppos = leftDiv.getBoundingClientRect().top;
            var bottompos = leftDiv.getBoundingClientRect().bottom;
                                    
            var rightDiv = document.getElementById("rightcontainer");
            var rightpos = rightDiv.getBoundingClientRect().left;
                                    
            return JSON.stringify({
                left: leftpos + 20,
                top: toppos + 20,
                right: rightpos - 20,
                bottom: bottompos - 20})
        }
    </script>
            
    
    Note:このコードで、機能をHTMLページに追加します。
    • lineMove()lineMove():垂直線を移動する場合に、テキストボックスのX値を更新します。
    • enterXval()enterXval(): テキストボックスのEnterキーを押すことに対応します。
    • getGraphRect()getGraphRect(): グラフが表示されている四角形のボックスを返します。
  2. Enterを押すことをキャプチャするため、onkeydown HTMLコードのテキストボックスタブにあるイベントハンドラーを追加します。これは、Enterキーを押して関数enterXval()を起動するためです。
    <input type="text" name="XValue"  id="X" placeholder="X"  onkeydown = "javascript:if(event.keyCode == 13) enterXval();">
                    
    
  1. 関数lineMove()では, switch文の追加を推奨しています。 コメントの通り、グラフがHTMLページに重なり、背景を変更しても影響しないことが分かります。
  2. 関数enterXval(), window.external.ExtCallはOrigin Cを呼び出す時に使います。window.external.ExtCallについての詳細は、こちらをご覧ください。

グラフ付HTMLダイアログの作成

OriginCコードを編集してHTMLダイアログを作成する準備ができました。

  1. コードビルダで、「HTML Dialog with A Graph」フォルダの下に、新しいcppファイル「DlgWithGraph.cpp」を作成します。
  2. 必要なヘッダの追加します。
    #include <Origin.h>
    #include <../OriginLab/DialogEx.h>
    #include <../OriginLab/HTMLDlg.h>
    #include <../OriginLab/GraphPageControl.h>
    
  3. GRAPH_CONTROL_IDを定義します。
    #define GRAPH_CONTROL_ID 1
            
    
  4. ユーザ定義HTMLダイアログクラスHTMLandGraphDlgHTMLDlgクラスから生成し、手法GetInitURL()の中にHTMLページを示します。
    class HTMLandGraphDlg: public HTMLDlg
    {
        protected:
            string GetInitURL() //htmlファイルのパスを取得            
            {
                string strFile = __FILE__; //現在のファイルの名前
                return GetFilePath(strFile) + "index.html";
            }
            string GetDialogTitle() {return "Vertical Cursor Example";} //ダイアログのタイトルをセット
    };
            
    
  5. イベントハンドラー手法をHTMLandGraphDlgに追加して、ユーザがダイアログ開く、サイズ変更、閉じるトリガーとなるイベントに応答します。
    private:
        GraphControl     m_gcCntrl;
    protected:
        BOOL OnInitDialog() //ダイアログが初めて表示された場合は、ダイアログを初期化する必要があります
        {
            LT_execute(";doc -m 0");//Originメインウィンドウを非表示にする
            HTMLDlg::OnInitDialog(); //HTMLDlgクラスからダイアログを生成
            ModifyStyle(0, WS_MAXIMIZEBOX);//標準的なHTMLダイアログリソースには、最大化ボタンがありません
            RECT rr;
            m_gcCntrl.CreateControl(GetSafeHwnd(), &rr, GRAPH_CONTROL_ID, WS_CHILD|WS_VISIBLE|WS_BORDER);
                    
            //グラフの様々な構成要素をクリックすることを無効にするオプションを設定でき、「OC_const.h」に詳細があります
            DWORD   dwNoClicks = NOCLICK_AXES | NOCLICK_DATA_PLOT | NOCLICK_LAYER | NOCLICK_TICKLABEL | NOCLICK_LAYERICON;
            GraphPage m_gp = Project.GraphPages("Graph1"); //OPJにあるこのグラフは手動でカスタマイズ可能です
            //OPJのGraph1をGraphControlに加えます
            BOOL bb = m_gcCntrl.AttachPage(m_gp, dwNoClicks); 
            return true;
        }
        BOOL OnDestroy()
        {
            //このディベロッパーで、OPJを修正できるようにしています
            //この部分をエンドユーザ用に削除し、LT_execute(";doc -ss;exit;")を実行のみします
            bool bExitOrigin = MessageBox(GetSafeHwnd(), _L("Are you sure you want to exit Origin?"),_L("Vertical Cursor Example"), MB_YESNO) == IDYES;
            if (bExitOrigin)
                LT_execute(";doc -ss;exit;"); //Originを終了します
            else
                LT_execute(";doc -m 1"); //Originのメインウィンドウを表示します
            return true;
        }
        //仮想
        //ダイアログの準備ができたら、ダイアログのサイズと位置を初期化する必要があります
        BOOL GetDlgInitSize(int& width, int& height) 
        {
            width = 1024;
            height = 450;
            return true;
        }
        //ダイアログのサイズを変更する場合、ダイアログのそれぞれのコントロールのサイズと位置を再度初期化する必要があります
        BOOL OnDlgResize(int nType, int cx, int cy) 
        {
            if ( !IsInitReady() )
                return false;
            // MoveControlsHelper _temp(this); // ダイアログのサイズを変更してそれがフリックしている場合、この行のコメントを外すことができます
            HTMLDlg::OnDlgResize(nType, cx, cy); //ダイアログにhtmlコントロールを配置します
                    
            if ( !IsHTMLDocumentCompleted() ) //HTMLコントロールの状態を確認します
                return false;
                    
            RECT rectGraph;
            //GetGraphRECTはプライベート関数でJavaScriptを呼び出して、グラフコントロールに関連付く四角形のボックスを作成します
            //次のセクションのOriginCで、JavaScriptを呼び出す方法を得ます。
            if ( !GetGraphRECT(rectGraph)) 
                return false;
            //HTMLコントロールの上にGraphControlを重ねます
            m_gcCntrl.SetWindowPos(HWND_TOP, rectGraph.left, rectGraph.top,RECT_WIDTH(rectGraph),RECT_HEIGHT(rectGraph), 0); 
                    
            return true;
        }
            
    
    Note: 手法 OnInitDialog() がトリガーにされる場合、グラフは、新しく作成したグラフコントロールに含まれます。
  6. クラスHTMLandGraphDlg内のダイアログメッセージをマップして、どのイベントを扱うのか、どの関数を呼び出すのかを指定します。
    EVENTS_BEGIN_DERIV(HTMLDlg)
        ON_INIT(OnInitDialog)
        ON_DESTROY(OnDestroy)
        ON_SIZE(OnDlgResize)
        ON_RESTORESIZE(OnRestoreSize)
    EVENTS_END_DERIV
    

Origin CでJavaScriptを呼び出す

このセクションでは、OriginCでJavaScriptを呼び出して、以下を行います。

  • ダイアログのサイズを変更すると、グラフコントロールは中央パネルに沿って右に移動します。そして、同時にJavaScriptを呼び出し、四角形のボックスを返します。
  • 垂直線を移動すると、テキストボックスのX値が更新されます。そして、JavaScriptを呼び出して数字を更新します。


これらのセクションで、メンバー関数GetScript()を使って、スクリプトエンジンインターフェースを得ます。この関数は、DHtmlControlクラスにあります。

  1. 関数GetGraphRect()をクラスHTMLandGraphDlgに追加して、JavaScript関数getGraphRECT()を呼び出します。これは5番目のセクションに書かれています。
    private:
        BOOL GetGraphRECT(RECT& gcCntrlRect) //JavaScriptを呼び出してGraphControlの位置を得る関数
        {
            if (!m_dhtml)
                return false;
            Object jsscript = m_dhtml.GetScript();
                    
            if(!jsscript) //返されたCOMオブジェクトの妥当性をチェックすることが常に推奨されます
                return false;
                    
            string str = jsscript.getGraphRECT();  
                JSON.FromString(gcCntrlRect, str); //文字列を構造体に変換します
            return true;
        }
            
    
  2. 関数OnMoveVlineToUpdateHtml()をOrigin C クラスに加えて、JavaScriptで関数lineMove()を呼び出します。
    public:
        void OnMoveVlineToUpdateHtml(double dVal)
        { 
            Object jsscript = m_dhtml.GetScript();
            if(!jsscript)
                return;
            string strXValue = ftoa(dVal, "*5*");//小数点桁数を5までにして、末尾のゼロを削除します
            jsscript.lineMove(strXValue);
        }
            
    

Origin Cでプロトタイプを呼び出しできるJavaScript

このセクションでは、手法OnEnterXvalToUpdateGraph()をダイアログクラスHTMLandGraphDlgに追加します。X値を入力してEnterキーを押す際に垂直線を移動するため、このクラスはJavaScript関数enterXval()で呼び出します。

  1. 手法とDECLARE_DISPATCH_MAPをダイアログクラスに追加します。
    public:
        DECLARE_DISPATCH_MAP
        void OnEnterXvalToUpdateGraph(string strXValue)
        {
            GraphPage gp = m_gcCntrl.GetPage();
            if(!gp)
                return;
            GraphLayer gl = gp.Layers(0);
            if(!gl)
                return;
            double xVal = atof(strXValue);
            if(NANUM == xVal)//数値を入力しません
                return;
            GraphObject vline; 
            vline = gl.GraphObjects("Line"); //グラフの垂直線にアクセスします
            if(!vline)
                return;
            vline.X = xVal;
        }
            
    
  2. OriginCクラスの手法をHTMLダイアログにマップします。
    BEGIN_DISPATCH_MAP(HTMLandGraphDlg, HTMLDlg)
        DISP_FUNCTION(HTMLandGraphDlg, OnEnterXvalToUpdateGraph, VTS_VOID, VTS_STR)
    END_DISPATCH_MAP
    
    Note:DISP_FUNCTIONの詳細についてはこちらをご覧ください。

Origin Cでプロトタイプを呼び出しできるLabTalk

最後に追加する項目があります。
プロパティダイアログの垂直線プロパティの設定をする際に、関数line_move()をLabTalkで呼び出すスクリプトを書いたことを思い出してください。
OriginCにこの関数を追加して垂直線を移動する際のトリガーにします。

static HTMLandGraphDlg* s_pDlg = NULL;//ダイアログクラスをLabTalkから呼び出す必要があります
//これは、LabTalkから呼び出されるOC関数です
void line_move(double dVal) //直線を移動するとX値を得て、JavaScriptに値を渡します
{
   if ( s_pDlg ) //このダイアログで直線を移動したときのみのトリガー
                s_pDlg->OnMoveVlineToUpdateHtml(dVal);
}
Note:ダイアログクラスでLabTalkの手法を呼び出すには、HTMLandGraphDlgオブジェクトを宣言します。

ダイアログの起動

ダイアログを起動する準備ができたら、

  1. メイン関数を追加します。
    void HTMLandGraphDlgEx()
    {
        HTMLandGraphDlg dlg;
        s_pDlg = &dlg;
        dlg.DoModalEx(GetWindow());
        s_pDlg = NULL;
    }
    
    Note:ProjectEvents.OGS.に書いた関数と同じ名前を付けます。
  2. 全てのコードを保存して、ビルドします。
  3. OPJをダブルクリックして、直接ダイアログを立ち上げます。