ドラッグ可能で編集可能なガントチャートの詳細な説明(HighchartsはVueとReactで使用できます)

ドラッグ可能で編集可能なガントチャートの詳細な説明(HighchartsはVueとReactで使用できます)

序文

Excel は強力で、広く使用されています。 Web アプリケーションの登場と改善に伴い、ユーザーの要件はますます高まっています。多くの Excel 関数が Sass に移行されました。彼らのために Excel を作成できればと思います。 。 。プログラマーになるのはとても難しいです。 。 。

昨年、ガントチャートの必要性に気づき、それについて多くの作業を行い、ブログも 2 つ書きました。 1つはGSTCパッケージを使用して作成したガントチャートで、もう1つは自分で作成したシンプルなガントチャートです。どちらの効果も理想的ではなく、特にGSTCには多くの問題があります。多くの道教の友人がブログを読んだ後に問題に遭遇しました。この問題の解決をお手伝いできないことを恥ずかしく思います。以前は忙しすぎて、このガントチャートに再び取り組むことはありませんでしたが、今日、私たちのニーズをほぼ完全に満たす新しいパッケージを見つけました。

まず、私たちは Highcharts を使用しています。次に、大規模なチームの製品であるため、事後メンテナンスが保証されており、ドキュメントも完全です。

Vue3で書いたのですがhighchartsでは区別されません。jsパッケージなのでvue reactでもネイティブマルチページでも動作します。

次に、最も基本的なニーズ、実装する必要がある機能、エフェクト図の GIF、最後にソースコードを見てみましょう。Git に置きました。役に立ったと思ったら、スターを付けてください。

必要

1. 横軸の左側はテーブルデータで、基本的な情報を表示できます。
2. 時間軸は水平軸の右側にあり、異なる精度で時間表示を切り替えることができます。
3. 水平方向のデータ ブロックが複数ある場合は、重ね合わせるのが最適です。
4. データブロックをドラッグしたりクリックしたりして、タスクの時間やその他の情報を変更できます。

レンダリング

このハイチャートは、左側の表と右側のアイコンを実装するだけでなく、データのリンクも実現しています。右側の横軸は時間軸で、フォーマットをカスタマイズできます。データを競合なく重ね合わせることができます。データにはクリックなどのさまざまなイベントがあり、単一のデータブロックを選択して編集できます。データをドラッグできます。たとえば、上下にドラッグして列を変更したり、水平にドラッグしたり、一方的にドラッグしたりできます。イベントにはコールバック関数があります。これらの機能は基本的に私たちのニーズを満たすことができます。たとえば、期間、時間の長さ、データ情報の変更と表示などです。

ソースコードアドレス、コード分析

まずコードの Git アドレスを貼り付け、GitHub ソース コードをクリックしてソース コードをダウンロードします。ソースコードを直接ダウンロードしてプロジェクトを実行することをお勧めします。また、このプロジェクトはvue3用ですが、この種のパッケージの場合、記述方法は、主にパラメータ以外はそれほど変わりません。

コードを投稿して、機能の実装について説明します。もちろん、コメントも非常に詳細です。

まず、highcharts-gantt.js はガントチャートを実装するために特別に使用されるファイルであり、draggable-points.js はポイントイベントバインディングを実装するファイルです。 Vue は変数を直接導入するとエラーを報告したため、 draggable-points の 2 つのモジュールを highcharts-gantt に直接追加し、混乱なく再圧縮しました。そのため、最終的なパッケージは 160K+ のみとなり、はるかに小さくなり、直接使用できます。圧縮されたソースコードは安心して使用できます。2 つのファイルの機能を結合しただけですが、公式のソースファイルではないことに注意してください。興味のある学生は公式のソースコードにアクセスできます。.src ファイルは圧縮されておらず、難読化されており、コメントは非常に詳細です。これは、ファイルをマージしたときのバージョン Highcharts Gantt JS v9.3.1 (2021-11-05) であり、現在の安定バージョンでもあります。

機能はちょっと単純で、コードについてはあまり言うことはないようです。要点を注釈しました。それでも分からない場合は、メッセージやコメントを残してください。

最後に、まだ問題があります。ソースコードを注意深く研究していません。この例にはまだ問題があります。ドラッグイベントが中断されず、チャートのデータ表示が直接変更されます。たとえば、線を垂直にドラッグすると、左側の表のデータが変更されます。まだ満足のいく解決策は見つかっていません。現在は、ドラッグ終了時にコールバックドロップ関数でデータを処理し、必要なデータを書き戻してチャートを更新しています。同様に、ドラッグや時間の競合などのさまざまなチェックを行って、前述の要件を満たすこともできます。しかし、まだ 1 つの欠陥があります。それは、ドラッグ プロセス中にデータが変更することです。ドラッグ プロセス中に左側のテーブルのデータが変更されないようにしたいのですが、まだ解決されていません。良い事例、良いアプリケーション、良い提案があれば、ぜひ提出していただき、一緒に前進していただければ幸いです。

<div class="hightChart-gantt">
    <div id="コンテナ"></div>
    <button @click="getData">現在のデータを印刷</button>
  </div>
</テンプレート>

<スクリプト>
'vue' から {defineComponent、onMounted、ref} をインポートします。
'@jsModule/highcharts/highcharts-gantt.src.js' から Highcharts として * をインポートします。
'dayjs' から dayjs をインポートします
'./constants' から{ WEEKS } をインポートします

// API ドキュメント: https://api.Highcharts.com.cn/gantt/index.html
// コミュニティアドレス: https://forum.jianshukeji.com/tags/c/Highcharts/35/Highcharts-gantt
// 公式例: https://www.highcharts.com.cn/demo/gantt/interactive-gantt

//解決すべき問題// 1. ドラッグ中断: ユーザー操作を検証する必要がありますが、現在のところ、ユーザー操作を中断する方法がわかりません。
// 解決策: 現在のアプローチは、ドロップで判断を行い、ビジネス ロジックに基づいてプロンプトを作成し、データを再レンダリングすることです。実行可能ですが、十分にフレンドリーではありません。


エクスポートデフォルトdefineComponent({
  名前: 'hightCharts-gantt',
  コンポーネント: {},
  設定 () {
    const gantt = ref({});
    // 公式の推奨は UTC 時間を使用することです。ビジネス上のニーズにより、データベース時間との一貫性を保つ必要があります。これはデータベースの保存形式によって異なります。const data = [
      {開始: '2021-6-1 0'、終了: '2021-6-1 18'、工場: 'Huawei'、材料: 'P50'、uid: 1、y: 0、完了: 0.35}、 
      {開始: '2021-6-2 8'、終了: '2021-6-2 16'、工場: 'Huawei'、材質: 'P50'、uid: 2、y: 0}、 
      {開始: '2021-6-3 8'、終了: '2021-6-4 24'、工場: 'Huawei'、材質: 'P50'、uid: 3、y: 0}、 
      {開始: '2021-6-4 12'、終了: '2021-6-5 15'、工場: 'Huawei'、材質: 'P50'、uid: 4、y: 0}、 

      {開始: '2021-6-1 8'、終了: '2021-6-1 12'、工場: 'Xiaomi'、素材: 'Redmi 3'、uid: 5、y: 1}、 
      {開始: '2021-6-3 3'、終了: '2021-6-3 9'、工場: 'Xiaomi'、素材: 'Redmi 3'、uid: 6、y: 1}、 

      {開始: '2021-6-1 6'、終了: '2021-6-1 16'、工場: 'Apple'、素材: 'iPhone13'、uid: 7、y: 2}、 
      {開始: '2021-6-2 3'、終了: '2021-6-2 19'、工場: 'Apple'、素材: 'iPhone13'、uid: 8、y: 2}、 
      {開始: '2021-6-3 8'、終了: '2021-6-3 17'、工場: 'Apple'、素材: 'iPhone13'、uid: 9、y: 2}、 

      {開始: '2021-6-1 12'、終了: '2021-6-1 24'、工場: 'OPPO'、素材: 'Reno7'、uid: 10、y: 3}、
      {開始: '2021-6-2 5'、終了: '2021-6-2 18'、工場: 'OPPO'、素材: 'Reno7'、uid: 11、y: 3}、
      {開始: '2021-6-3 1'、終了: '2021-6-5 12'、工場: 'OPPO'、素材: 'Reno7'、uid: 12、y: 3}、
    ];
    newData = data.map(item => { とする
      アイテムの開始 = dayjs(アイテムの開始).valueOf();
      アイテムの終了 = dayjs(アイテムの終了).valueOf();
      返品商品
    });
    
    // グローバル設定。アイコンを初期化する前に設定する必要があります。Highcharts.setOptions({
      グローバル:
        useUTC: false // UTC 時間を使用しない}, // すべてデフォルトで英語ですが、一部中国語に翻訳されています lang: {
        noData: 「まだデー​​タがありません」
        平日: ['月曜日'、'火曜日'、'水曜日'、'木曜日'、'金曜日'、'土曜日'、'日曜日']、
        月: ['1月'、'1月'、'3月'、'4月'、'5月'、'6月'、'7月'、'8月'、'9月'、'10月'、'11月'、'12月']
      },
    });
    const ドラッグ開始 = (e) => {
    }
    定数ドラッグ = (e) => {
    }
    定数ドロップ = (e) => {
      const { newPoint = {}、ターゲット = {} } = e;
      newPoint.y が 0 の場合
        list = [] とし、 tar = newData.find(item => item.y === newPoint.y && item.uid !== target.uid);
        リスト = newData.map(item => {
          // 現在のドラッグデータ if(item.uid === target.uid) {
            戻る {
              ...アイテム、
              ファクトリー: tar.factory、
              材質: タール、 
              ...新しいポイント
            }
          } それ以外 {
            返品商品
          }
        })
        gantt.value.update({
          シリーズ: [{
            データ: リスト
          }]
        })
      }
    }
    // 選択すると、ビジネスデータを編集するためのウィンドウがポップアップ表示されます。const handleSelect = (e) => {
      console.log('選択済み')
    }
    // 最終データを取得する const getData = () => {
      データを gantt.value.series[0].data.map(item => { とします。
        戻る {
          uid: アイテム.uid、
          工場: アイテム.工場、
          素材: アイテム.素材、
          開始: アイテム.開始、
          終了: 項目.終了
        }
      })
      コンソール.log(データ)
    }


    マウント時(() => {
      試す {
        gantt.value = Highcharts.ganttChart('コンテナ', {
          タイトル:
            テキスト: 'hightCharts ガントチャートの例'
          },
          x軸: [{
            現在の日付インジケーター: true、
            ティックピクセル間隔: 70,
            グリッド: {
              borderWidth: 1, // 右ヘッダーの境界線の幅 cellHeight: 35, // 右日付ヘッダーの高さ },
            ラベル: {
              配置: '中央'、
              フォーマッタ: 関数() {
                `${dayjs(this.value).format('M月D')} ${WEEKS[dayjs(this.value).day()]}` を返します。
              }
            },
          }, {
            ラベル: {
              配置: '中央'、
              フォーマッタ: 関数() {
                `${dayjs(this.value).format('YYYY年M月')}` を返します。
              }
            },
          }],
          y軸: {
            タイプ: 'カテゴリ',
            グリッド: {
              有効: true、
              境界線の色: 'rgba(0,0,0,0.3)',
              境界線の幅: 1,
              列: [
                { タイトル: { テキスト: '工場' }, ラベル: { フォーマット: '{point.factory}' } }, 
                { タイトル: { テキスト: 'モデル' }, ラベル: { フォーマット: '{point.material}' } }, 
              ]
            }
          },
          ツールチップ: {
            フォーマッタ: 関数 () {
              `<div> を返します
               ファクトリー: ${this.point.factory}
              開始時刻: ${dayjs(this.point.start).format('YYYY-MM-DD HH:mm:ss')}}
              終了時間: ${dayjs(this.point.end).format('YYYY-MM-DD HH:mm:ss')'',
              </div>`
            }
          },
          シリーズ: [{ データ: newData }],
          プロットオプション: {
            シリーズ: {
              animation: false, // 依存関係コネクタをアニメーション化しない
              ドラッグドロップ: {
                draggableX: true, // 水平ドラッグ draggableY: true, // 垂直ドラッグ dragMinY: 0, // 垂直ドラッグ下限 dragMaxY: 3, // 垂直ドラッグ上限 dragPrecisionX: 3600000 // 水平ドラッグ精度(ミリ秒単位)},
              データラベル: {
                有効: true、
                フォーマット: '{point.factory}-{point.uid}',
                スタイル: {
                  カーソル: 'デフォルト',
                  ポインタイベント: 'なし'
                }
              },
              allowPointSelect: true、
              ポイント: {
                イベント: {
                  ドラッグ開始: ドラッグ開始、
                  ドラッグ: ドラッグ、
                  ドロップ: ドロップ、
                  選択: ハンドル選択
                }
              }
            }
          },
          エクスポート: {
            ソース幅: 1000
          },
          credits: { // 右下隅の著作権情報を削除します enabled: false
          },
        });
      } キャッチ(エラー){
        コンソール.log(エラー)
      }
    })

    戻る {
      ガント、
      データを取得
    }
  },
})
</スクリプト>

<スタイルスコープ>
.hightChart-gantt {
  オーバーフローx: 自動;
    -webkit-オーバーフロースクロール: タッチ;
}
#容器 {
    最大幅: 1200px;
    最小幅: 800px;
    高さ: 400px;
    マージン: 1em 自動;
}
</スタイル>

ガントチャートをドラッグして編集する方法の詳細説明については、この記事で終わります(highchartsはVueとReactの両方で使用できます)。関連するVueガントチャートガントコンテンツの詳細については、123WORDPRESS.COMの以前の記事を検索するか、次の関連記事を続けて閲覧してください。今後とも123WORDPRESS.COMを応援してください!

以下もご興味があるかもしれません:
  • Vue3 の ref、computed、reactive、toRefs をご存知ですか?
  • setup+ref+reactive は vue3 の応答性を実装します
  • Vue/React シングルページ アプリケーションをリフレッシュなしで復元するソリューション
  • Vue3 のリアクティブ関数 toRef 関数 ref 関数の紹介
  • vue3 の setUp とリアクティブ関数の使用方法の詳細な説明
  • フロントエンドプロジェクトにおける Vue および React のエラー監視

<<:  HTML要素によるFlashブロックの詳細な例

>>:  ウェブインターフェースデザインでウェブサイトのスタイルガイドを作成する方法(画像とテキスト付き)

推薦する

JavaScript でロジック判定コードを最適化する方法

序文日常生活で使用する論理的判断文には、if...else...、switch...case...、...

Linux で特定のユーザーにフォルダーのすべてのコンテンツを許可するにはどうすればよいですか?

【問題分析】 chown コマンドを使用できます。ここで ch は change (変更) を表し...

Linux での MySQL 5.7.19 (tar.gz) インストール グラフィック チュートリアル

Linux で MySQL-5.7.19 バージョンをインストールするための最初のチュートリアル。す...

高性能ウェブサイトの最適化ガイド

パフォーマンスの黄金律:エンドユーザーの応答時間のわずか 10% ~ 20% が HTML ドキュメ...

WeChat アプレット wxs 日付と時刻処理の実装例

目次1. 日付までのタイムスタンプ2. UTCを北京時間に変換するWXS (WeiXin Scrip...

CSSスタイルとセレクターの使い方

HTML で CSS を使用する 3 つの方法: 1. インラインスタイル: 要素のスタイル属性を通...

CentOS 8 に MySql をインストールしてリモート接続を許可する方法

ダウンロードしてインストールします。まず、システムに MySQL または MariaDB があるかど...

MySQL 並列レプリケーションの簡単な分析

01 並列レプリケーションの概念MySQL のマスター スレーブ レプリケーション アーキテクチャで...

Tencent Cloud Serverをゼロから導入する方法

初めての投稿ですので、間違いや問題点などありましたら、コメント欄で指摘していただければ、今後改善させ...

モバイル ブラウザのビューポート パラメータ (Web フロントエンド デザイン)

モバイル ブラウザは、Web ページを仮想の「ウィンドウ」(ビューポート) に配置します。このウィン...

MySQL ストアド関数(カスタム関数)の定義と使用方法の詳細な説明

ストアド関数ストアド関数とは: SQL コードの一部をカプセル化し、特定の関数を完了して、結果を返し...

Dockerが独自のローカルイメージリポジトリを構築するための手順

1. 環境と準備1. Ubuntu 14.04 2.Docker環境2. 建設プロセス1. ミラーソ...

MySQL データベースの最適化に関する 9 つのヒント

目次1. 最も適切なフィールド属性を選択する2. フィールドをNOT NULLに設定してみる3. サ...

WeChatアプレットでSVGアイコンを使用する方法

SVG は、さまざまな利点があるため、近年広く使用されています。残念ながら、WeChat ミニプログ...

Windows での Nginx のインストールと環境設定 (nginx をサービスとして実行)

最初で最も重要なステップは、Windows 環境に Ngnix サービスをインストールする方法です。...