整合營銷服務商

          電腦端+手機端+微信端=數據同步管理

          免費咨詢熱線:

          「推薦」一個前端畫圖的javascript庫—Met

          「推薦」一個前端畫圖的javascript庫—MetricFlow.js

          各位網友大家好,今天給大家推薦一個前端畫圖的javascript庫,可用于構建數據流圖、任務流圖、知識圖譜展示等,他就是——MetricFlow.js。

          介紹

          MetricFlow是一個前端畫圖的javascript庫,可用于構建可拖拽、可靈活定義的數據流圖、任務流圖、知識圖譜展示等

          展示


          文檔

          快速上手

          1. 創建畫布

          創建畫布只需要定義div標簽即可,并聲明畫布的widthheight

          <div id="graph" height="700px" width="1100px" ></div>

          2. 創建節點

          /*在畫布上創建圖*/
          let metricFlow=MetricFlow("graph")
          /*定義節點數據*/
          let nodeData={
              "id":"primaryKey",//id在全局中不能重復,否則會被覆蓋
              "title":{'name':"運行時間統計"},
              "data":[
                 {'name':'方法:IndexController#method1'},
                 {'name':'平均耗時:0.333ms'},
               ]
          };
          /*在(20,200)坐標上創建一個節點*/
          let node1=metricFlow.createNode(nodeData,10,200);
          /*或者直接在nodeData中定義位置x和y屬性,然后*/
          /*metricFlow.createNode(nodeData);*/


          3. 創建連線

          let metricFlow=MetricFlow("graph")
          let node1Data={
              "x":10,
              "y":200,
              "id":"node1",
              "title":{'name':"運行時間統計"},
              "data":[
                 {'name':'方法:IndexController#method1'},
                 {'name':'平均耗時:0.333ms'},
               ]
          };
          let node1=metricFlow.createNode(node1Data);
          
          let node2Data={
              "x":300,
              "y":200,
              "id":"node2",
              "title":{'name':"運行時間統計"},
              "data":[
                 {'name':'方法:IndexController#method1'},
                 {'name':'平均耗時:0.333ms'},
               ]
          };
          let node2=metricFlow.createNode(node2Data);
          /*連接兩個節點*/
          metricFlow.createLink(node1,node2);

          或者直接在末尾節點中指定from屬性,無需metricFlow.createLink(node1,node2);

          let metricFlow=MetricFlow("graph")
          let node1Data={
              "x":10,
              "y":200,
              "id":"node1",
              "title":{'name':"運行時間統計"},
              "data":[]
          };
          let node1=metricFlow.createNode(node1Data);
          
          let node2Data={
              "x":300,
              "y":200,
              "id":"node2",
              "from":"node1",//from的值可以是string 也可以是數組
              "title":{'name':"運行時間統計"},
              "data":[]
          };
          let node2=metricFlow.createNode(node2Data);


          4. 批量創建節點

          批量創建節點有兩種方式,第一種使用list創建,并在每個節點數據中指定from屬性即可創建關系:

          
                      let metricFlow=MetricFlow("graph")
          
                      /*定義節點數據*/
                      let node1Data={
                          "x":20,
                          "y":200,
                          "id":"node1",
                          "title":{'name':"節點1"}
                      };
          
                      let node2Data={
                          "x":300,
                          "y":50,
                          "id":"node2",
                          "from":"node1",
                          "title":{'name':"節點2"}
                      };
                      let node3Data={
                          "x":300,
                          "y":300,
                          "id":"node3",
                          "from":"node1",
                          "title":{'name':"節點3"}
                      };
                      let nodes=[node1Data,node2Data,node3Data];
                      metricFlow.createNodes(nodes);


          第二種使用children屬性創建,根節點的x和y需指定,其余子節點會自動向右排列

          let nodes={
                      "x":20,
                      "y":200,
                       ...
                      "children":[
                          {
                              "id":"node3",
                               ...
                              "children":[
                                  {...}
                              ]
                          },
                      ]
                  };
          
          metricFlow.createNodes(nodes);
          

          自動創建的時候如果節點間距不合適,可調整

          let options={
                          'node-distance-offsetx':5,//左右間距+5
                          'node-distance-offsety':-5//上下間距-5
                      };
          let metricFlow=MetricFlow("graph",options)
          

          自動創建的時候如果數據格式不匹配,又不想遍歷處理,可傳入函數調整

          function format(data){
              data['value']=data['value']+"ms";
              return data;
          }
          metricFlow.createNodes(nodes,format);


          樣式定義

          1. 更改節點樣式

          節點由三部分組成,分別是 標題、元素集和剩余的背景,每一個部分都支持兩種樣式定義方式:

          第一種是沿用了css的樣式,在數據上添加style即可,如,更改整個節點的邊框顏色和粗細:

          let node2Data={
              "id":"node2",
              "style":"border-color:red;border-width:2px;",
              "title":{'name':"運行時間統計"},
              "data":[
                 {'name':'方法:IndexController#method1'},
                 {'name':'平均耗時:0.333ms'},
               ]
          };

          第二種是提取了background-colorborder-color兩個樣式,可以單獨配置

          let node2Data={
              "id":"node2",
              "background-color":"red",
              "border-color":"red",
              "title":{'name':"運行時間統計"},
              "data":[
                 {'name':'方法:IndexController#method1'},
                 {'name':'平均耗時:0.333ms'},
               ]
          };

          樣式定義demo-demo4.html

          2. 更改標題樣式

          let node2Data={
              "id":"node2",
              "title":{'name':"運行時間統計","style":"background-color:red;border-color:red;font-size:15px;"},
              "data":[
                 {'name':'方法:IndexController#method1'},
                 {'name':'平均耗時:0.333ms'},
               ]
          };


          3. 更改元素樣式

          let node2Data={
              "id":"node2",
              "title":{'name':"運行時間統計"},
              "data":[
                 {'name':'方法:IndexController#method1',"style":"font-size:10px;"},
                 {'name':'平均耗時:0.333ms',"style":"font-size:10px;"},
               ]
          };


          連線配置

          連線位置目前僅支持偏移量定義,可在創建MetricFlow時定義

          連線分為起始點和終點,可設置全局的起始點的偏移位置,主要考慮前端框架使用較為復雜時css沖突所導致位置偏移的校正

          let options={
                          'link-start-offsetx':1,//起始點向右偏移一個單位
                          'link-start-offsety':-1,//起始點向上偏移一個單位
                          'link-end-offsetx':-1,
                          'link-end-offsety':-1,
                          'link-width-offset':-1,//線段粗細減小1個單位
                          'link-color':"blue", //更改線段顏色
                      };
          let metricFlow=MetricFlow("graph",options)

          連線位置demo-demo5.html

          節點事件

          支持基本的鼠標事件,如clickdblclickmousedownmouseup等,與原生js一致,事件在對應節點身上配置即可:

          let node1Data={
                      "id":"primaryKey",
                      "title":{'name':"雙擊"},
                      'click':"sinclick", //單擊 sinclick為函數名
                      'dblclick':"doubleClick",//雙擊
                      "data":[
                         {'name':'方法:IndexController#method1'},
                         {'name':'平均耗時:0.333ms'},
                       ]
                  };


          版本說明

          V1.0:創建節點;連線;樣式定義;鼠標事件

          版權說明

          1.本項目版權屬作者所有,并使用 Apache-2.0進行開源;

          2.您可以使用本項目進行學習、商用或者開源,但任何使用了本項目的代碼的軟件和項目請尊重作者的原創權利;

          3.如果您使用并修改了本項目的源代碼,請注明修改內容以及出處;

          4.其他內容請參考Apache-2.0

          Python數據分析與可視化領域,Matplotlib作為一款功能強大的圖形庫,不僅能夠創建靜態圖表,更支持創建生動的動畫效果,使數據的演變過程得以直觀展現。本文將深入探討Matplotlib的動畫功能,通過實例代碼解析,幫助您掌握如何利用Matplotlib繪制出令人眼前一亮的動態圖表,為您的數據分析工作注入活力。


          Matplotlib動畫基礎

          Matplotlib動畫基于matplotlib.animation模塊,通過迭代更新圖表元素(如線條、文本、圖像等),實現數據隨時間變化的動態可視化。主要涉及以下核心類和方法:

          • FuncAnimation:創建基于回調函數的動畫,是最常用的動畫創建方式。
          • ArtistAnimation:基于一組預計算的圖表元素(Artists)創建動畫。
          • save:將動畫保存為視頻文件(如.mp4.gif等)或HTML5視頻。

          使用FuncAnimation創建動態圖表

          1. FuncAnimation基礎用法

          以下是一個使用FuncAnimation繪制動態正弦波的例子:

          import numpy as np
          import matplotlib.pyplot as plt
          from matplotlib.animation import FuncAnimation
          
          fig, ax=plt.subplots()
          
          x_data, y_data=[], []
          line,=ax.plot([], [], lw=2)
          
          def update(frame):
              t=frame / 10.0
              x=np.linspace(0, 2 * np.pi, 1000)
              y=np.sin(x + t)
              
              x_data.append(x)
              y_data.append(y)
              
              line.set_data(x_data[-1], y_data[-1])
              return line,
          
          ani=FuncAnimation(fig, update, frames=np.arange(100), interval=20, blit=True)
          
          plt.show()
          

          在這個例子中:

          • update函數定義了每一幀動畫時,圖表元素(線段line)如何更新數據。這里我們計算當前幀對應的正弦波曲線,并設置給線段。
          • FuncAnimation接收fig(圖表)、update(更新函數)、frames(幀數)等參數,創建并返回一個動畫對象。
          • interval參數指定每幀之間的時間間隔(單位:毫秒),blit=True可以提高動畫性能。

          2. FuncAnimation進階應用

          • 添加標題與坐標軸標簽:在update函數中動態調整。
          def update(frame):
              ...
              ax.set_title(f"Time: {frame / 10.0:.1f} s")
              ax.set_xlabel("X-axis label")
              ax.set_ylabel("Y-axis label")
              ...
          
          • 保存動畫為視頻
          ani.save('sine_wave_animation.mp4', writer='ffmpeg')
          

          繪制復雜動態圖表實例

          1. 動態散點圖:模擬粒子運動

          import random
          
          fig, ax=plt.subplots()
          scat=ax.scatter([], [])
          
          def update(frame):
              N=?
              data=[(random.uniform(-1, 1), random.uniform(-1, 1)) for _ in range(N)]
              scat.set_offsets(data)
              return scat,
          
          ani=FuncAnimation(fig, update, frames=np.arange(100), interval=20, blit=True)
          
          plt.show()
          

          2. 動態條形圖:實時數據更新

          import time
          
          data=[random.randint(0, 100) for _ in range(5)]
          
          fig, ax=plt.subplots()
          bars=ax.bar(range(5), data)
          
          def update(frame):
              for bar, value in zip(bars, (random.randint(0, 100) for _ in range(5))):
                  bar.set_height(value)
              return bars,
          
          ani=FuncAnimation(fig, update, frames=np.arange(100), interval=20, blit=True)
          
          plt.show()
          

          Matplotlib動畫在Python Web項目中的應用

          實時監控系統

          # 假設已連接到實時數據源
          data_stream=get_realtime_data()
          
          fig, ax=plt.subplots()
          line,=ax.plot([], [], lw=2)
          
          def update(frame):
              new_data=next(data_stream)
              line.set_data(new_data['time'], new_data['value'])
              return line,
          
          ani=FuncAnimation(fig, update, frames=np.arange(100), interval=20, blit=True)
          
          start_web_server(ani)
          

          交互式Web應用

          # 假設已搭建Flask環境
          from flask import Flask, render_template, jsonify
          
          app=Flask(__name__)
          
          @app.route('/data')
          def stream_data():
              return jsonify(next(get_realtime_data()))
          
          @app.route('/')
          def index():
              return render_template('index.html')
          
          if __name__=='__main__':
              app.run(debug=True)
          

          templates/index.html中使用JavaScript庫(如D3.js)對接API,動態更新圖表。

          總結與展望

          Matplotlib的動畫功能極大地豐富了數據可視化的表現形式,使復雜的數據演變過程得以生動呈現。通過掌握FuncAnimation的使用方法,您可以輕松創建各類動態圖表,如動態散點圖、條形圖等,以適應不同的數據分析需求。在Python Web項目中,結合實時數據源與Web框架(如Flask),您可以構建實時監控系統、交互式Web應用等,將動態圖表融入到線上服務中,提升用戶體驗與數據洞察力。

          ode環境安裝

          這里以一個Vue3工程為例子

          首先安裝Nodehttps://nodejs.org/zh-cn/download/請根據電腦操作系統安裝對應的安裝包

          步驟 1 : 雙擊下載后的安裝包,如下所示:

          步驟 2 : 點擊上圖的Run(運行),將出現如下界面:

          步驟 3 : 勾選接受協議選項,點擊 next(下一步) 按鈕 :

          步驟 4 : Node.js默認安裝目錄為 C:\Program Files\nodejs\, 你可以修改目錄,并點擊 next(下一步):

          步驟 5 : 點擊樹形圖標來選擇你需要的安裝模式 , 然后點擊下一步 next(下一步)

          步驟 6 :點擊 Install(安裝) 開始安裝Node.js。你也可以點擊 Back(返回)來修改先前的配置。 然后并點擊 next(下一步):

          安裝過程:

          點擊 Finish(完成)按鈕退出安裝向導。

          2.Node安裝完成后需要配置環境變量

          檢測PATH環境變量是否配置了Node.js,點擊開始=》運行=》輸入"cmd"=> 輸入命令"path", 輸出如下結果:

          我們可以看到環境變量中已經包含了 C:\Program Files\nodejs\

          如果沒有,我們就需要把我們前面安裝Node 步驟四中安裝目錄設置為環境變量:

          找到我的電腦=》鼠標右鍵選擇=》 選擇屬性=》 找到高級系統設置=》 環境變量=》 變量path=》 點擊編輯=》將node安裝目錄填上并確定

          最后檢查一下Node.js版本看是否安裝成功

          編輯器 vscode

          也可以是代碼其他編輯器,這里以vscode為例

          1.安裝vscodehttps://code.visualstudio.com/

          2.安裝vetur 插件點擊install安裝

          3.vscode 命令行權限不足的問題: 例如執行vue、yarn等命令報錯 在安裝了@vue/cli提示vue不是內部命令這種情況,應該以管理員身份運行powerell命令行

          4.如果在powerell也無法運行對應的命令就是沒有設置對應的環境變量,比如yarn安裝了,并且用yarn下載了@vue/cli 那么 vue不是內部命令就是yarn或者vue沒有配置對應的環境變量,這里yarn環境配置 默認位置 :C:\Users\Mx\AppData\Local\Yarn\bin

          配置完成后再重新安裝@vue/cli就行了

          執行命令 設置權限

          get-ExecutionPolicy
          set-ExecutionPolicy RemoteSigned

          選擇并輸入Y或者A,然后再重新啟動vscode打開命令行就好。


          項目應用構建

          基于Vue-cli構建Vue單頁面應用程序

          1.打開命令行安裝vue-cli腳手架工具(已安裝跳過此步驟)

          npm install -g @vue/cli
          # OR(或)
          yarn global add @vue/cli
          # 通過查看版本檢查是否安裝成功
          vue --version

          2.命令行運行命名創建新項目

          # 創建名為mxdraw-test-vue3 的一個新Vue項目
          vue create mxdraw-test-vue3
          # 如果選擇default則會直接創建項目,創建項目包括babel\eslin這些工具,比如Router/Vuex等其他依賴需要自己手動安裝
          ? P1ease pick a preset:
            #  默認選項 
            Default (vue 3)([vue 3] babel, eslint) 
            # 手動選擇功能
            Manually select features

          如果選擇Manually select features(手動安裝)則會進入下一步選項:(這里推薦大家進行手動配置)

          ? Check the features needed for your project :
          (*) Choose vue version                    # 選擇vue版本
          (*) Babel                                 # 代碼編譯
          (*) TypeScript                            # ts
          ( ) Progressive Web App (PWA)Support      # 支持漸進式網頁應用程序
          (*) Router                                # vue路由
          ( ) vuex                                  # 狀態管理模式
          ( ) css Pre-processors                    # css預處理
          (*) Linter ; Formatter                    # 代碼風格、格式校驗
          ( ) Unit Testing                          # 單元測試
          ( ) E2E Testing                           # 端對端測試

          TypeScript 選項配置

          # 選擇使用哪個版本的vue框架
          ? Choose a version of Vue.js that you want to start the project with
          2.x # vue2.x
          3.x # vue3.x
          # 詢問的是是否使用class風格的組件語法,如果在項目中想要保持使用TypeScript的class風格的話,建議大家選擇y。
          ? Use class-style component syntax? (Y/n)
          # 使用Babel與TypeScript一起用于自動檢測的填充?這里一定要選擇y
          ? Use Babel alongside TypeScript (required for modern mode, auto-detected polyfills, transpiling JSX)? (Y/n)

          Router 選項配置

          # 路由是否使用history模式?如果項目中存在要求就使用history(即:y),但是一般還是推薦大家使用ha模式,畢竟history模式需要依賴運維。
          ? Use history mode for router? (Requires proper server setup for index fallback in production) (Y/n)

          CSS Pre-processors css 選項配置

          # 選擇一種CSS預處理類型,根據各個項目的要求使用對應css編譯處理
          ? Pick a CSS pre-processor (PostCSS, Autoprefixer and CSS Modules are supported by default): (Use arrow keys)
          > Sass/SCSS (with dart-sass)
            Sass/SCSS (with node-sass)
            Less
            Stylus

          Linter / Formatter 選項配置

          # TSLint只有在選擇TypeScript時才會存在。
          ? Pick a linter / formatter config: (Use arrow keys)
          > ESLint with error prevention only     #  只進行報錯提醒
            ESLint + Airbnb config                #  不嚴謹模式
            ESLint + Standard config              #  正常模式
            ESLint + Prettier                     #  嚴格模式
            TSLint (deprecated)                   #  TypeScript格式驗證工具
          # 選擇校驗時機,一般都會選擇保存時校驗,好及時做出調整
          ? Pick additional lint features: (Press <space> to select, <a> to toggle all, <i> to invert selection)
            (*) Lint on save               # 保存時檢測
            ( ) Lint and fix on commit     # 修復和提交時檢測

          Unit Testing 選項配置

          # 選擇單元測試解決方案,普遍用到最多的是Mocha + chai
          ? Pick a unit testing solution: (Use arrow keys)
          > Mocha + Chai
            Jest

          E2E Testing E2E(End To End)選項配置

          # 選擇端對端測試的類型
          ? Pick a E2E testing solution: (Use arrow keys)
          > Cypress (Chrome only)
            Nightwatch (WebDriver-based)

          額外選項

          # 選擇Babel,PostCSS, ESLint等自定義配置的存放位置。這里建議大家選擇第一個
          ? Where do you prefer placing config for Babel, ESLint, etc.? (Use arrow keys)
          > In dedicated config files     #  存放在專用配置文件中
            In package.json               #  存放在package.json中
          # 是否保存當前選擇的配置項,如果當前配置是經常用到的配置,建議選擇y存儲一下當前配置項
          ? Save this as a preset for future projects? (y/N)
          # 選擇n之后則會直接開始創建項目了,選擇y之后則會輸入一個存儲當前配置項的名稱:
          ? Save preset as:


          3.運行項目

          cd mxdraw-test-vue3
          yarn serve

          詳細說明請參考 [vue-cli文檔指南]

          vue框架使用請參考[Vue.js 中文文檔]

          安裝 npm

          yarn add mxdraw 或 npm install mxdraw

          用法

          1.引入

          import Mx from "mxdraw"

          2.加載

          <canvas id="mxcad">
            </canvas>

          3.javascript

          import Mx from "mxdraw"
          // 動態加載 js庫核心代碼
          Mx.loadCoreCode().then(()=> {
            // Mx.MxFun.setMxServer("ws://localhost:5090") // 開啟socket通信 可編輯圖紙
            // 創建控件對象
            Mx.MxFun.createMxObject({
                canvasId: "mxcad", // canvas元素的id
                cadFile: "/demo/buf/$hhhh.dwg.mxb1.wgh", // http方式(預覽): 加載public/demo文件夾下轉換后的圖紙
                   // cadFile: "test2.dwg", //  socket通信方式請直接提供圖紙名稱 如:text.dwg
                callback: (mxDraw, {
                    canvas,
                    canvasParent
                })=> {
                    // 可以拿到canvas元素和它的父級元素
                    console.log(canvas, canvasParent)
                    console.log(mxDraw)
                    // 拿到圖層數據
                    mxDraw.addEvent('uiSetLayerData', (listLayer)=> {
                        console.log(listLayer)
                    })
                },
                isNewFile: true // 是否新建文件
            })
          })

          如何實現一個畫線的功能命令?

          1.實現畫線功能

          參考資料:

          * [MrxDbgUiPrPoint | getPoint] 構建取點對象

          * [status] MrxDbgUiPrBaseReturn表示對應狀態

          * [McEdGetPointWorldDrawObject | pWorldDraw] 用于構建一個動態繪制回調對象

          * [pt1 | pt2 | lastPt] THREE.Vector3 數據類型


          javascript

          import Mx from "mxdraw"
          // 畫線的函數
          function BR_Line() {
            // 構建取點對象
            const getPoint=new Mx.MrxDbgUiPrPoint();
            // 構建動態繪制對象
            const worldDrawComment=new Mx.McEdGetPointWorldDrawObject();
            // 開始動態拖動 行為: 鼠標點擊畫布時只執行一次回調函數,后續點擊無效
            getPoint.go((status)=> {
              if (status !==0) {
                return;
              }
              // 獲取鼠標在畫布上的第一個點
              const pt1=getPoint.value();
              // 將第一個點作為起始點
              let lastPt=pt1.clone();
              // 設置動態繪制的回調函數
              worldDrawComment.setDraw((currentPoint, pWorldDraw)=> {
                // 繪制當前鼠標移動點到起始點的線段
                pWorldDraw.drawLine(currentPoint, lastPt);
              });
              // 設置取點對象交互過程中的動態繪制調用對象
              getPoint.setUserDraw(worldDrawComment)
              
              // 開啟動態拖動,連續取點,直到ESC退出。 行為: 鼠標點擊一下執行一次回調函數
              getPoint.goWhile((status)=> {
                if (status===0) {
                  // 獲取第二個點的位置
                  const pt2=getPoint.value();
                  // 拿到Three的場景對象
                  let sence=Mx.MxFun.getCurrentDraw().getScene();
                  // 創建一條 從起始點到 當前點擊位置的線段
                  let line=Mx.MxThreeJS.createLine(lastPt, pt2, 0xffffff);
                  
                  // 將線段添加到場景中
                  sence.add(line);
                  // 將第二點作為起始點
                  lastPt=pt2
                }
              });
            });
          }

          2.注冊使用命名

          參考資料:

          * [MxFun.addCommand] 注冊命名方法

          * [MxFun.sendStringToExecute] 執行命名方法

          * [MxFun.isRunningCommand]檢查是否有命令在運行


          javascript

          import Mx from "mxdraw"
          // 注冊命名
          Mx.MxFun.addCommand("BR_Line", ()=> {
            if(Mx.MxFun.isRunningCommand()) {
                return
            }
            BR_Line()
          })
          // 執行命令
          Mx.MxFun.sendStringToExecute("BR_Line")
          

          更多Api使用說明請參考[Mx模塊集]對應模塊中的Api接口說明

          按需引入配置

          使用babel插件babel-plugin-import 實現按需引入

          需要安裝 npm i babel-plugin-import-D 然后找到或創建項目根目錄的 .babelrc文件新增如下內容:

          json

          {
            "plugins": [
              [
                "import", {
                  "libraryName": "mxdraw",
                  "libraryDirectory": "dist/lib/MxModule",
                  "camel2UnderlineComponentName": false,
                  "camel2DaComponentName": false
                }
              ]
            ]
          }

          基于babel-plugin-import 按需引入

          javascript

          import { MxFun } from "mxdraw"

          或者直接通過import MxFun from "mxdraw/dist/lib/MxModule/MxFun" 這樣的方式直接引入對應模塊


          主站蜘蛛池模板: 国产精品亚洲专区一区| 人妻无码一区二区三区| 无码人妻精品一区二区三区东京热| 怡红院AV一区二区三区| 国产成人精品第一区二区| 精品无码人妻一区二区免费蜜桃| 国产精品无码AV一区二区三区 | 无码精品尤物一区二区三区| 精品一区二区ww| aⅴ一区二区三区无卡无码| 亚洲乱码国产一区三区| 日产亚洲一区二区三区| 无码视频免费一区二三区| 亚洲国产精品一区二区第一页免| 成人午夜视频精品一区| 在线精品视频一区二区| 亚洲国产精品成人一区| 中文字幕日韩一区二区不卡 | 91精品国产一区| 黑人一区二区三区中文字幕| 人妻少妇精品一区二区三区| 国产日韩精品视频一区二区三区| 午夜精品一区二区三区在线观看| 亚洲无人区一区二区三区| 韩国资源视频一区二区三区| 国产一区二区在线视频| 国产精品一区二区三区99 | 日韩视频在线一区| 亚洲一区二区电影| 国语对白一区二区三区| 久久精品国产一区| 偷拍精品视频一区二区三区| 国产福利一区二区三区在线观看 | 在线播放精品一区二区啪视频| 亚洲av无码一区二区三区乱子伦| 国产成人一区二区三区免费视频| av无码免费一区二区三区| 日本成人一区二区| 精品久久一区二区三区| 亲子乱AV视频一区二区| 国产成人高清视频一区二区|