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 にインポートする方法の例

推薦する

MySQLクエリキャッシュの簡単な使い方の詳細な説明

目次1. クエリキャッシュの実装プロセス2. クエリキャッシュを構成する3. クエリキャッシュを有効...

Linux+ApacheサーバURLの大文字と小文字の区別の問題を解決する

今日、問題が発生しました。ブラウザのアドレスバーにURLアドレスを入力する際、ページを正常にアクセス...

CSS における px、em、rem、pt の特徴、違い、変換について詳しく説明します。

コンセプト紹介: 1. px (ピクセル):仮想的な長さの単位で、コンピュータ システムのデジタル画...

MySQLでデータベースのインストールパスを表示する方法

mysql コマンドを使用して、mysql のインストール パスを表示できます。 # 次の 2 つの...

VMWare Linux MySQL 5.7.13 のインストールと設定のチュートリアル

この記事では、参考までにVMWare LinuxにMySQL 5.7.13をインストールするチュート...

mysql データ型変換の実装

1. 問題下図のような表があり、結果値がreference_high値より大きいデータを見つける必要...

dockerfile における ENTRYPOINT と CMD の組み合わせと違い

前回の記事【dockerコンテナのためのdockerfileを詳しく解説】では、dockerfile...

Linux システムでのスケジュールされたタスクの紹介

目次1. 計画タスクをカスタマイズする2. 時間を同期する3. 練習する4. セキュリティの問題1....

Vueでaxiosをカプセル化する方法

目次1. インストール1. はじめに3. インターフェースルートアドレス4. 使用例4.1 ダウンロ...

HTML に画像が存在しない場合にデフォルトの画像を表示する方法の例

画像リンク <img src="" /> jsを使用してURLが有効...

モバイル Web アプリ上の画像が鮮明ではなく、非常にぼやけているのはなぜですか?

なぜ?最も簡単に言えば、ピクセルは均等ではないということです。携帯電話に表示される写真はとても繊細に...

Vueのドラッグ可能なコンポーネントであるVue Smooth DnDの使用方法の詳細な説明

目次紹介とデモAPI: コンテナ財産ライフサイクルコールバックイベントAPI: ドラッグ可能実際の戦...

HTMLインライン要素とブロックレベル要素の基本概念と使用例

HTML タグには、インライン要素とブロックレベル要素の 2 種類があります。まず、インライン要素と...

MySQLのマスタースレーブレプリケーションと読み取り書き込み分離を理解するための記事

目次導入1. MySQL マスタースレーブレプリケーション1. MySQLレプリケーションタイプ2....

VUE ユニアプリコア知識の簡単な紹介

目次仕様a. ページファイルはVueの単一ファイルコンポーネント仕様に準拠しています。 b. コンポ...