ccchart icon indicating copy to clipboard operation
ccchart copied to clipboard

水平目盛り線AxisXを切りの良い値にする

Open toshirot opened this issue 7 years ago • 8 comments

ちょっと考えてみる 設定部分で関連しそうなのはこの辺。Pie type以外のY軸を使うチャートにはほぼすべて影響する。

       //水平目盛り線AxisXの本数
      if(typeof this.op.config.axisXLen === 'number'){
        this.axisXLen = this.op.config.axisXLen;
      } else {
        if(typeof this.gcf.axisXLen === 'number'){
          this.axisXLen = this.gcf.axisXLen;
        } else {
          this.axisXLen = 10; //default

          //Y目盛を小数点無しで (this.maxY - this.minY) < axisXLen なら
          //水平目盛り線の数を (this.maxY - this.minY +1)まで減らす
          if(this.yScaleDecimal === 'no'){
            if((this.maxY - this.minY) <  this.axisXLen) this.axisXLen = parseInt((this.maxY - this.minY));
          }
        }
      }

       //水平目盛線1本当たりのラベル値
      this.yGapValue = (this.maxY - this.minY) / (this.axisXLen);

      //値1当たりの高さ
      this.unitH = this.chartHeight / (this.maxY - this.minY);

      if(isFinite(this.unitH) === false){
        this.unitH = this.chartHeight;
        //0で割るとInfinityになってしまうのでY値の変化がない場合のように0ならchartHeightにしておく
      }

      if (this.type === 'stacked%') this.unitH = this.chartHeight / 100;
       //ラベルの値初期値
      this.wkYScale = this.minY;

      //for drawAxisX
      //水平目盛線用
      this.yGap = this.chartHeight / (this.axisXLen);


      var val = '', percent = '';
      if(this.type === 'stacked%'){
        val =Math.round( count * 100/this.axisXLen) +'%';
      } else {
        if(expression){this.wkYScale = this.maxY}//小手先修正あとで再考
        val = this.util.addComma(this, this.wkYScale, yScaleDecimal);
        percent = (this.yScalePercent==='yes')?( ' ('+ Math.round(count * 100/this.axisXLen)  +'%)' ):'';
      }
      this.wkYScaleStr = val + percent;//change type to string


toshirot avatar Dec 14 '17 06:12 toshirot

要するに、いま自動計算している axisXLenの 値を100とか1000とかのunitで指定して、そこから自動計算すればよいはず。

そこから yGap値を計算。

toshirot avatar Dec 14 '17 06:12 toshirot

this.op.config.に この「キリ番タイプ」を使うか今までの「旧自動計算タイプ」を使うかを useAxisXLenUnit 'yes'|'no' などで与える必要がある。

その時、後方互換が必要なので、「旧自動計算タイプ」がDefault値。

toshirot avatar Dec 14 '17 07:12 toshirot

あるいは this.op.config.axisXLenUnit 的な値を configに入れてもらって、それが number なら 「キリ番タイプ」 number以外なら「旧自動計算タイプ」。

この方がシンプルだけど、 useAxisXLenUnit とか明示した方が判りやすい?

toshirot avatar Dec 14 '17 07:12 toshirot

「キリ番」て英語でなんて言うだろう?

toshirot avatar Dec 14 '17 07:12 toshirot

たくまに聞いたら nice round number かなと。ナイスなroundなのかな。 じゃ this.op.config.niceRound にしとこうかな。

たとえば、こんな感じ?

{
  "config": {
        "title": "テスト",
        "subTitle": "niceRound 1000です",
        "type": "line",
        "niceRound": 1000,  //number | undefined undefinedまたは指定が無ければ自動計算
          :
  }

toshirot avatar Dec 14 '17 10:12 toshirot

小数点はどうする?

toshirot avatar Dec 14 '17 11:12 toshirot

小数点については、この辺も関係してくる。

      //端数処理桁数の指定(整数部または小数第n桁以下を四捨五入で丸めるための桁数 int)
      //小数点以下桁数を指定する
      this.roundDigit = this.op.config.roundDigit;
      if(this.roundDigit === undefined)this.gcf.roundDigit;
      if(typeof this.roundDigit === 'number'){ //2, 0, 2.5, -3など
        this._useDecimal = 'yes';//2, 0, -3など
        this.roundDigit = parseInt(this.roundDigit);//桁数なので整数化
      } else {//undefined, null, '', [2], "2"
        //configに指定がない場合
        if(this.roundDigit === undefined){
          if(JSON.stringify(this.data).indexOf('.') !== -1){
            this._useDecimal = 'yes'; //configに指定がないけど、少数値が有れば yes。
            this.roundDigit = 3;//デフォルト値 0.12345は0.123 1や0.1や0.12 は、1や0.1や0.12。
          } else {
	          this._useDecimal = 'no'; //configに指定がなければ no。
	          this.roundDigit = 0;
          }
        } else {
          this._useDecimal = 'no'; //configに指定がなければ no。文字列の数字'2'もダメ
        }
      }

      //Y軸の天地を反転する デフォルトは 降順'DESC' 昇順'ASC' line,bezi2,bezi のみ
      this.yScaleOrder =
        this.op.config.yScaleOrder || this.gcf.yScaleOrder || 'DESC';

      //X目盛を小数点有りにするか?
      this.xScaleDecimal = this._useDecimal;
      //Y目盛を小数点有りにするか?
      this.yScaleDecimal = this._useDecimal;

toshirot avatar Dec 14 '17 11:12 toshirot

ざっと見ての印象ですが、チャート上の価格の区切りの1目盛は常識的に「 (a = 1 or 2.5 or 5) * 10^n 」(nは整数)ですよね。一方、チャート上を何目盛にするかは、チャートのピクセル数からだいたい決まります。あとは、チャート全体が収まる範囲で最小の(a,n)を求めればいいのでそんな難しい話ではないと思います。

okajimad avatar Dec 14 '17 14:12 okajimad