3.修正方法3
新しい属性の追加
a. パーツCollecXYの修正
計算する間隔を線形的に等間隔にしていたが、今回は対数的と逆数的にも
等間隔にできるように変更する。
1.WorkFrame IDEアイコンをクリックし、「既存のオブジェクトを
オープンします」をクリックする。
2.DataColl.IWPを選択する。
3.WorkFrameのDataColl.vbbをダブルクリックし、ビジュアル・ビルダーを起動する。
4.非ビジュアル・パーツのCollecXYをダブルクリックする。
5.「パーツ・インターフェース・エディター」の属性を選び、属性名typeOfIncrement、
属性タイプIStringと入力し、「デフォルト」をクリックする。
「追加」をクリックする。
6.優先のページで、属性typeOfIncrementを追加する。
7.「ファイル」->「保管および生成」->「フィーチャー・ソース」をクリックする。
8.「CollecXY−フィーチャー・ソース・コードを作成します」ダイアログにおいて、
メンバー関数の
virtual CollecXY& setTypeOfIncrement(const IString& aTypeOfIncrement)
virtual IString typeOfIncrement() const
属性データ・メンバーの
iTypeOfIncrement
イベント・データ・メンバーの
typeOfIncrementId
を選択し(ctrlキーを押しながらクリックし)、「選択したものの生成」をクリックする。
9.「プロジェクト」->「編集」をクリックし、CollecXY.cpvを開く。
下記のようなコードが自動作成されている。
// Feature source code generation begins here....
最初のコードが書かれている。
// Feature source code generation ends here.
の次に、
自動作成されている。
10.最初に作成されたコードのlong CollecXY::calc()を下記のように修正する。
long CollecXY::calc()
{
double delta; // dataXの計算間隔
long iCount=0; // データ数
DataXY* iResultXY; // DataXY構造のポインターをiResultXYとする。
// resultの全てのデータを削除する。
removeAll();
// 修正箇所開始
if( iMaximumDataX<=iMinimumDataX ) // 範囲の値が逆の場合、例外処理を行う。
{
IString errorText = IString( "範囲を設定し直してください。" );
IException exc( errorText, 0, IException::unrecoverable );
ITHROW( exc );
} // 例外処理終了
// 修正箇所終了
// データ数が1以下の場合、例外処理を行う。
if( iNumber<=1)
{
IString errorText = IString( "データ数が1以下です。" );
IException exc( errorText, 0, IException::unrecoverable);
ITHROW( exc );
} // 例外処理終了
// resultのイベント通知機能を禁止する。
iResult->disableNotification();
if( iTypeOfIncrement=="linear" ) // 等間隔の場合 修正箇所
{ // 修正箇所
delta = (iMaximumDataX - iMinimumDataX)/(iNumber - 1); // 計算間隔
// データ数だけ繰り返す。
for( int i=0; i<=(iNumber-1); i++ )
{
iResultXY = new DataXY; // iResultXYの実体(メモリー領域)を確保する。
// dataXに数値を代入し、dataXのイベントを発生させる。
iDataX = iMinimumDataX + delta*i; // 1997年10月30日修正
notifyObservers(INotificationEvent(CollecXY::dataXId, *this)); // 1997年10月30日修正
// 1.他のパーツのdataXに対応する属性の値を変更する。
// 2.dataXのイベントで、他のパーツのdataYに対応する値を計算させる。
// 3.dataYに対応する値が戻ってくるまで待つ。
// 変数dataXをiResultXYのdataXに代入する。
iResultXY->setDataX( iDataX );
// 関数値dataYをiResultXYのdataYに代入する。
iResultXY->setDataY( iDataY );
// シーケンシャルなresultの最後の項に加える。
iResult->addAsLast( iResultXY );
iCount++;
}
} // 修正箇所
// 修正箇所開始
if( iTypeOfIncrement=="log" ) // 対数的に等間隔の場合
{
if( iMinimumDataX<=0 ) // 最小値が0または負のとき、例外処理を行う。
{
IString errorText = IString( "最小値が0または負です。" );
IException exc( errorText, 0, IException::unrecoverable );
ITHROW( exc );
} // 例外処理終了
delta = log(iMaximumDataX/iMinimumDataX)/(iNumber - 1); // 計算間隔
// データ数だけ繰り返す。
for( int i=0; i<=(iNumber-1); i++ )
{
iResultXY = new DataXY; // iResultXYの実体(メモリー領域)を確保する。
// dataXに数値を代入し、dataXのイベントを発生させる。
iDataX = exp( log(iMinimumDataX) + delta*i); // 1997年10月30日修正
notifyObservers(INotificationEvent(CollecXY::dataXId, *this)); // 1997年10月30日修正
// 1.他のパーツのdataXに対応する属性の値を変更する。
// 2.dataXのイベントで、他のパーツのdataYに対応する値を計算させる。
// 3.dataYに対応する値が戻ってくるまで待つ。
// 変数dataXをiResultXYのdataXに代入する。
iResultXY->setDataX( iDataX );
// 関数値dataYをiResultXYのdataYに代入する。
iResultXY->setDataY( iDataY );
// シーケンシャルなresultの最後の項に加える。
iResult->addAsLast( iResultXY );
iCount++;
}
}
if( iTypeOfIncrement=="inverse" ) // 逆数的に等間隔の場合
{
if( iMinimumDataX*iMaximumDataX<=0 ) // 例外処理
{
IString errorText = IString( "範囲内に0が含まれます。" );
IException exc( errorText, 0, IException::unrecoverable );
ITHROW( exc );
} // 例外処理終了
delta = (1/iMinimumDataX - 1/iMaximumDataX)/(iNumber - 1); // 計算間隔
// データ数だけ繰り返す。
for( int i=0; i<=(iNumber-1); i++ )
{
iResultXY = new DataXY; // iResultXYの実体(メモリー領域)を確保する。
// dataXに数値を代入し、dataXのイベントを発生させる。
iDataX = 1/(1/iMinimumDataX - delta*i); // 1997年10月30日修正
notifyObservers(INotificationEvent(CollecXY::dataXId, *this)); // 1997年10月30日修正
// 1.他のパーツのdataXに対応する属性の値を変更する。
// 2.dataXのイベントで、他のパーツのdataYに対応する値を計算させる。
// 3.dataYに対応する値が戻ってくるまで待つ。
// 変数dataXをiResultXYのdataXに代入する。
iResultXY->setDataX( iDataX );
// 関数値dataYをiResultXYのdataYに代入する。
iResultXY->setDataY( iDataY );
// シーケンシャルなresultの最後の項に加える。
iResult->addAsLast( iResultXY );
iCount++;
}
} // 修正箇所終了
// resultのイベント通知機能を回復する。
iResult->enableNotification();
// resultが変更されたことを通知する。
notifyObservers(INotificationEvent(CollecXY::resultId, *this));
return iCount;
}
11.セーブする。
12.クラス・エディターの必要なインクルード・ファイルに<math.h> _MATH_と
入力する。
13.「ファイル」->「保管」をクリックする。
14.今後パーツCollecXYを利用できるように、覚え書きCollecXY.htmlを下記のように
修正する。
パーツCollecXYの説明
DataXの最小値、最大値、データ数を指定する。
接続するパーツでDataYに対応する値を計算して、
(x, y)のデータ対をDataXの最小値から順にならべる。
CollecXYパーツ | |||
属性 |
タイプ |
コメント |
優先 |
dataX |
double |
変数(横軸X) |
O |
dataY |
double |
関数値(縦軸Y) |
O |
minimumDataX |
double |
変数の最小値 |
O |
maximumDataX |
double |
変数の最大値 |
O |
number |
int |
変数の分割数 |
O |
stop |
IStirng |
文字列stopを代入すると、計算が中止される |
|
typeOfIncrement |
IString |
増加分を線形的、対数的、逆数的に等間隔にする |
|
result |
IVSequence<DataXY*>* |
全データ |
O |
set関数の引数のconstを削除 |
|||
アクション |
タイプ |
パラメータ |
|
calc |
long |
|
O |
removeAll |
void |
|
O |
calc()はデータ数を戻り値とする。
例外処理のメッセージが含まれている。
接続方法:dataXの値からdataYに対応する値を計算するパーツとは、
1.dataX -> パーツのxに対応する属性
2.パーツのyに対応する属性 -> dataY
3.dataX -> パーツの計算に対応するアクション
と接続する。
注意:上記の接続1と3の順番は間違えないこと。
属性typeOfIncrementは
linearで線形的に等間隔で増加、
logで対数的に等間隔に増加、
inverseで逆数的に等間隔に増加
する。
属性stopに文字列stopを代入すると、calc()が停止する。
必要なファイル |
||
DataColl.vbb |
CollecXY.cpv |
CollecXY.hpv |
|
DataXY.cpv |
DataXY.hpv |