JSはキャンバス技術を使用してeChartsの棒グラフを模倣します

JSはキャンバス技術を使用してeChartsの棒グラフを模倣します

Canvas は HTML5 の新しいタグです。js を使用して Canvas 描画 API を操作し、Web ページ上に画像を描画することができます。

Baidu はオープンソースの視覚化チャート ライブラリ ECharts を開発しました。これは非常に強力で、折れ線グラフ、棒グラフ、散布図、円グラフ、ローソク足グラフ、地図など、さまざまなチャートを実現できます。多くのプロジェクトでは、チャート機能の開発に ECharts が使用されています。

このチュートリアルでは、ネイティブ js を使用して、ECharts に似た棒グラフを開発する方法を説明します。このチュートリアルを学習する前に、読者は HTML と CSS のスキルと、簡単な JavaScript の基礎知識を持っている必要があります。

ECharts の開発方法に従って、チャートは HTML 要素内に生成されます。したがって、この例では、以下に示すように、ID 名が canvasWrap である div 要素も準備します。

<div class="canvas_wrap" id="canvasWrap"></div>

次に、canvasWrap 要素内にキャンバス要素を作成し、キャンバス要素上に棒グラフを描画します。開発の前に、いつものように、まず棒グラフの具体的な操作を分析し、具体的な操作に基づいて機能を実装する方法を複数のステップに分割し、1ステップずつ完了させます。

1. 棒グラフデータを書き込む
2. canvasWrap要素とその幅と高さを取得する
3. 描画環境を作成する
3.1 キャンバスを作成する
3.2 キャンバスの幅と高さを設定する
3.3 キャンバスをcanvasWrap要素に配置する
3.4 描画コンテキストの作成
4. 座標領域を設定する
5. x軸を描く
5.1 軸線の描画
5.2 目盛りの描画
5.3 図面スケール名
6. Y軸を描く
6.1 軸線の描画
6.2 目盛りの描画
6.3 図面スケール値
6.4 x軸グリッド線の描画
7. 縦棒グラフを描く
7.1 列幅の計算
7.2 柱の高さの計算
7.3 列Xの開始点を計算する
7.4 棒グラフのY開始点を計算する
7.5 縦棒グラフの描画

具体的なコードは次のとおりです。

//1 棒グラフデータを書き込むオプション = {
  //x軸データ xAxis: {
    データ: ['月', '火', '水', '木', '金', '土', '日']
  },
  //縦棒グラフデータ系列: [{
    // 異なるデータのチャート効果を確認するために、さらにいくつかのデータセットを記述します // データ: [0.01, 0.2, 0.05, 0.07, 0.04, 0.13, 0.9],
    // データ: [1, 1, 5, 7, 4, 1, 9],
    // データ: [1213, 30, 150, 80, 70, 910, 630],
    データ: [120, 199, 150, 180, 70, 110, 130],
    //グラフィックスタイル: 棒グラフタイプ: 'bar'
  }]
};

//チャート関数を作成する、 wrap: チャートの親要素ID; data: チャートのデータ function fnCharts(wrap,data){
  //2. canvasWrap 要素を取得します。 var eWrap = document.getElementById(wrap);
  //2. canvasWrap 要素の幅と高さを取得してキャンバス サイズを設定します。var nWrapW = eWrap.offsetWidth;
  var nWrapH = eWrap.offsetHeight;

  //3.1 キャンバスを作成する var eCanvas = document.createElement('canvas');
  //3.2 キャンバスの幅と高さを設定します。eCanvas.width = nWrapW;
  eCanvas.height = nWrapH;
  //3.3 キャンバスを canvasWrap 要素に配置します。eWrap.appendChild(eCanvas);
  //3.4 描画コンテキストを作成する(Canvas キャンバスに描画できるようにするため)
  var oCtx = eCanvas.getContext('2d');

  //4. 座標領域の左上隅と右下隅を設定します // 線をわかりやすくするために、開始点は整数ではなく 50.5 に設定されます var nZoneStartX = 50.5;
  var nZoneStartY = 50.5;
  var nZoneEndX = nWrapW - nZoneStartX;
  var nZoneEndY = nWrapH - nZoneStartY;

  //5.1 ライン関数を使用して x 軸を描画します fnCreatLine(nZoneStartX,nZoneEndY,nZoneEndX,nZoneEndY);
  //X軸の長さを計算します var nLonX = nZoneEndX - nZoneStartX;
  // x 軸データ配列の長さを取得します。 var nDataLon = option.xAxis.data.length;
  //x軸データ配列の長さに応じてループし、ループ内にスケール線とスケール値の名前を描画します for(let i=0;i<nDataLon;i++){
    // x 軸上の x 軸スケール ラインの開始点の値を計算します。let nScaleX = nZoneStartX+Math.floor(nLonX*(i/nDataLon));
    //スケール ラインの開始点はすべて x 軸上にあります。let nScaleY = nZoneEndY;
    //5.2 長さ10のスケール線を描く
    fnCreateLine(nScaleX,nScaleY,nScaleX,nScaleY+10);
    //データからスケール名の文字列を取得します。let sName = option.xAxis.data[i];
    //スケール名の開始点を計算します。let nNameX = nZoneStartX+Math.floor(nLonX*(i/nDataLon))+Math.floor(nLonX*(1/nDataLon))/2;
    nNameY = nZoneEndY+15 とします。
    //5.3 スケール名を描画します fnCreatText(sName,nNameX,nNameY,'#aaa','center');
  }

  //6.1 ライン関数を使用して y 軸の線を描画します fnCreatLine(nZoneStartX,nZoneEndY,nZoneStartX,nZoneStartY);
  //Y軸の目盛りを描画する前に、目盛りの最大値と最小値、目盛り線の数、目盛り間の間隔が必要です。
  // 最大スケール値 最初に配列から最大値を取得し、表示する最大値を計算します var nMaxScal = Math.max.apply(null,option.series[0].data);
  //この例では最小スケール値は0です
  var nMinScal = 0;
  // この例ではスケールセグメントの数は4に設定されています
  var nSplit = 4;
  //スケール間隔値を計算します var nStep = (nMaxScal-nMinScal)/nSplit;
  //この時点で、一般的なチャートのスケール間隔は 5 の倍数であるため、スケール間隔が少し奇妙に見えるかもしれません。
  //たとえば、[0,0.5,1.0,1.5,2] または [0,50,100,150,200]。
  //したがって、nStep が 5 の倍数かどうかを確認するためにさらに計算が必要です。そうでない場合、nIncrease は最も近い 5 の倍数に増分されます。
  // 最初のステップを計算します。nStep によると、倍数値は 0.5 または 5 または 50 または... になります。
  // この例では、nStep 値は処理前に文字列に変換されます (計算には対数や指数も使用できます)。
  var sTemp = '' + nStep; //nStep を文字列に変換 //増加させる必要がある数値を宣言します。デフォルトは 1 です
  var nIncrease = 1;
  // 小数点乗算によって発生する精度のバグを解決するために変数を宣言する
  var nTempMultiple = 1;  

  //nIncrease は 10 の n 乗をとり、次の判定で計算します if(sTemp.indexOf('.')==-1){
    //nStep に小数点が含まれていない場合、nIncrease は 10 を sTemp.length-2 乗した値になります。
    //たとえば、nStep が 19 の場合、nIncrease は 10 の 0 乗で、増分は 1 です。
    //nStep が 9 の場合、nIncrease は 10 の -1 乗となり、増分は 0.1 になります。
    //nStep が 199 の場合、nIncrease は 10 の 1 乗で、増分は 10 です
    nIncrease = Math.pow(10,sTemp.length-2);
  }それ以外{
    //nStep に小数点が含まれている場合、nIncrease は 10 の sTemp - 2 乗になります。
    nIncrease = Math.pow(10,sTemp.indexOf('.')-2);
    //この変数は、nIncrease が小数の場合など、小数を乗算するときに発生する可能性のある精度のバグを解決するために使用されます。nTempMultiple = Math.pow(10,sTemp.indexOf('.')); 
  }
  // 165 を 160 に、16.5 を 16 に、1.65 を 1.6 にといった増分しやすいように倍数を丸めます。これは次の数式で実現できます。nStep = Math.ceil(nStep/nIncrease)*(nIncrease*nTempMultiple)/nTempMultiple;
  //ループを使用してnIncreaseを増分し、スケール値を修正します while(nStep%(nIncrease*5)!=0){
    nステップ += n増加*1;
  }
  // 間隔値にセグメント数を掛けて、最大スケール値 nMaxScal = nStep * nSplit を変更します。
  //y 軸の長さを計算します。ここでは、y 軸の上部にいくらかの距離を残す必要があるため、3 を減算します。var nLonY = nZoneEndY - nZoneStartY - 3;
  //y軸スケールを描画する for(let i=0;i<=nSplit;i++){
    //スケール ラインの開始点はすべて y 軸上にあります。let nScaleX = nZoneStartX;
    //y 軸上の y 軸スケール ラインの開始点の値を計算します。let nScaleY = nZoneEndY-Math.floor(nLonY*(i/nSplit));
    //6.2 スケールラインを描画する fnCreatLine(nScaleX,nScaleY,nScaleX-10,nScaleY);
    //6.3 スケール値を描画する fnCreatText(''+i*nStep,nScaleX-20,nScaleY,'#333');
    もし(i!=0){
      //6.4 ゼロ以外の位置で、x 軸グリッド線を描画します fnCreatLine(nScaleX,nScaleY,nScaleX+nLonX,nScaleY,'#ccc');
    }
  }

  //7.1 棒グラフの幅を計算する let nBarWidth = Math.ceil(Math.floor(nLonX*(1/nDataLon))*.8);
  //x軸データを走査する for(let i=0;i<nDataLon;i++){
    //7.2 棒グラフの高さを計算する let nBarHeight = nLonY/nMaxScal*option.series[0].data[i];
    //7.3 棒グラフの開始点Xを計算する let nBarStartX = nZoneStartX+Math.floor(nLonX*(i/nDataLon))
                     +(Math.floor(nLonX*(1/nDataLon))-nBarWidth)/2;
    //7.4 棒グラフの Y 開始点を計算します。let nBarStartY = nZoneEndY-nBarHeight;
    //7.5 棒グラフを描画する fnCreatRect(nBarStartX,nBarStartY,nBarWidth,nBarHeight);
  }

  //線を描く関数 function fnCreatLine(sX,sY,eX,eY,color='#000'){
    //パスの描画を開始します oCtx.beginPath();
    //パスの色を設定します oCtx.strokeStyle = color;
    //パスの開始点と終了点を設定し、線を描画します oCtx.moveTo(sX,sY);
    oCtx.lineTo(eX,eY);
    //パスに色を追加します oCtx.stroke();
  }

  //テキストを描画する function fnCreatText(text,x,y,color='#000',align='end',baseLine='middle'){
    //テキストの色を設定 oCtx.fillStyle = color;
    //水平方向の配置を設定します oCtx.textAlign = align;
    //垂直方向の配置を設定します。oCtx.textBaseline = baseLine;
    //テキストを描画 oCtx.fillText(text,x,y);
  }

  //四角形を描く function fnCreatRect(x,y,width,height,color='#a00'){
    //色を設定 oCtx.fillStyle = color;
    oCtx.fillRect(x,y,幅,高さ);
  }
}
//チャート関数を呼び出して、要素 ID とオプション データを渡します fnCharts('canvasWrap',option);

このサンプル チュートリアルでは、ソース コードを読むのに多少の忍耐が必要になる場合があります。理解できない箇所に遭遇した場合は、ソース コードの理解できない箇所の値を出力すれば、理解できるかもしれません。

上記は、JS がキャンバス テクノロジを使用して echarts 棒グラフを模倣する方法の詳細です。キャンバス棒グラフを使用する JS の詳細については、123WORDPRESS.COM の他の関連記事に注目してください。

以下もご興味があるかもしれません:
  • JavaScript ECharts の使用方法の説明
  • Baidu ECharts プラグインを使用して JavaScript で円グラフを描画する例
  • ECharts.js を使用してローソク足チャートを描画する方法の例
  • レポート統計を実装するために echarts を使用する jsp の例
  • JavaScript によるデータ視覚化: ECharts マップの作成

<<:  大量のデータをMySQLにインポートする際に発生する問題と解決策の分析

>>:  nginx ログを elasticsearch にインポートする方法の例

推薦する

JSが絵柄デジタル時計を実現

この記事の例では、画像デジタル時計を実現するためのJSの具体的なコードを参考までに共有しています。具...

Javascript 共通高階関数の詳細

目次1. 一般的な高階関数1.1、フィルター1.2、地図1.3、減らすHigher Order fu...

jsを使用してサーバーに写真をアップロードする

この記事の例では、参考のために画像をサーバーにアップロードするためのjsの具体的なコードを共有してい...

Linuxでのソフトウェア(ライブラリ)の更新コマンドの詳しい説明

Ubuntu サーバーにパッケージをインストールする場合、sudo apt-get install ...

インデックスを設計する際の原則は何ですか? インデックスの障害を回避するにはどうすればよいでしょうか?

目次主キーインデックス頻繁にクエリされるフィールドのインデックスを作成する大きなフィールドのインデッ...

Alibaba Cloud で MySQL リモート接続を構成するための詳細な手順

序文ご存知のとおり、デフォルトでは、Alibaba Cloud にインストールされている MySQL...

MySQL 同時実行制御の原則に関する知識ポイント

Mysql は、高性能なデータ ストレージ サービスを提供する主流のオープン ソース リレーショナル...

Linux nohup コマンドの原理と例の分析

nohup コマンドUnix/Linux を使用する場合、通常はプログラムをバックグラウンドで実行す...

html5 の新しいメソッドを使用して JavaScript で要素クラス名を操作する方法の詳細な説明

目次1. classList属性2. 実用化以前の JavaScript では、最初にクラス属性を取...

Centos7.5 は mysql5.7.24 バイナリ パッケージの展開をインストールします

1. 環境整備:オペレーティング システム: CentOS Linux リリース 7.5.1804 ...

Apache、Tomcat、Nginx サーバーの詳細な理解と比較分析

質問1件会社のサーバーはApacheを使用しており、バックエンドはPHP、サーバーはLinux C/...

Layui は複数条件クエリのサンプルコードを実装します

最近ファイルシステムを作ったのですが、フィールドが多すぎることに気づきましたページングを使用した複数...

WeChatミニプログラムでEchartとサブパッケージを使用するための完全な手順

序文休日は終わっていますが、それは別の形で(お腹に触れることで)私たちに現れます。ミニプログラムでデ...

入力要素 [type="file"] を使用する場合のスタイルのカスタマイズとブラウザの互換性の問題に関する議論

この2日間、Baixing.comの筆記試験問題を解いているときに、このような問題に遭遇しました。H...

Docker の Windows ストレージ パス設定操作

Windows 10 に Docker をインストールする場合、コンテナタイプを Linux コンテ...