For AI agents: the complete documentation index is available at https://docs.dataplatform.ovh.net/ja/llms.txt, the full documentation bundle is available at https://docs.dataplatform.ovh.net/ja/llms-full.txt, and this page is available as Markdown at https://docs.dataplatform.ovh.net/ja/sdk/app-custom-chart.md.
  • 🇯🇵 日本語
  • カスタムチャートの作成

    Warning

    再作業が保留中で、納期は未定です。 Front App SDK(ReactJS)とFront API SDK(NodeJS)の両方が置き換えられています。このページは現在のリリースを文書化し、置き換えが出荷されるまで正確であり、維持されます。これに対して書かれたコードは引き続き動作します。

    Data Platformでは、独自のチャートテンプレートを作成できます。

    再確認のため、チャートの設定例を以下に示します:

    { 
      "type": "chart",
      "col": 0,
      "row": 1,
      "sizeX": 12,
      "sizeY": 12,
      "title": "",
      "chart": {
        "component": "my-component",
        "options": {
          "title": "My component"
        },
        "request": {
          "data": {
            "fields": {
              "quantity": [
                "sum"
              ]
            }
          },
          "filter": {},
          "scale": {
            "fields": [
              "city"
            ]
          }
        },
        "dynamic-parameters": [
          "dp-datepicker",
          "dp-city"
        ],
        "not-nullable-dynamic-parameters": [
          "dp-datepicker"
        ]
      }
    }

    この形式は、アプリ開発のさらに深い部分で詳細に説明されており、Data Platformが提供する異なるテンプレート(echart、table、jvectormapなど)をリストしています。

    ステップ1:Hello Worldコンポーネントの作成

    import React from 'react'
    import PropTypes from 'prop-types'
    
    class ChartMyComponent extends React.Component {
      render () {
        return (
          <div className='chart-my-component'>
            Hello World
          </div>
        )
      }
    }
    
    ChartMyComponent.propTypes = {
      chart: PropTypes.object
    }
    
    export default ChartMyComponent

    これは、単に「Hello World」を表示するReactJSコンポーネントを宣言します。この例では、src/MyComponent.jsxに保存してください。 最後に、プロジェクトにインポートするには、ファイルsrc/index.jsxに強調表示された行を追加する必要があります:

    FpSdk.start()
      .then(() => {
        var FpAppTemplate = FpSdk.modules.sdk.templates.default
        FpSdk.modules['chart-my-component'] = require('./MyComponent.jsx')
        render(<FpAppTemplate />, document.getElementById('root'))
      })

    完了したら、チャートに「Hello World」が表示されるはずです。

    Warning

    表示されない場合は、リクエストに結果が含まれていない可能性があります。


    ステップ2:チャートにデータを表示

    テンプレートはData Platform SDKによって呼び出されます。ReactJSコンポーネントのpropsを介してアクセスできます。これは、次の情報を含むチャートオブジェクトを保持しています。

    • this.props.chart.request:チャートによって実行されたクエリのコピー
    • this.props.chart.options:チャートに関連付けたオプションのリスト
    • this.props.chart.dataAnalytics Managerに送信されたクエリの結果

    この例では、HelloWorldは単純なテーブルに置き換えられます:

    import React from 'react'
    import PropTypes from 'prop-types'
    
    class ChartMyComponent extends React.Component {
      render () {
        return (
          <div className='chart-my-component'>
            <h1>{this.props.chart.options.title}</h1>
            <table>
              {this.props.chart.data.results.map((result, i) => {
                return (
                  <tr key={i}>
                    <td>{JSON.stringify(result)}</td>
                  </tr>
                )
              })}
            </table>
          </div>
        )
      }
    }
    
    ChartMyComponent.propTypes = {
      chart: PropTypes.object
    }
    
    export default ChartMyComponent

    このコードのおかげで、結果ごとに1行のテーブルを持つことができます。

    次に、表示されるJSONを実際のデータ行に変換してみましょう。

    import React from 'react'
    import PropTypes from 'prop-types'
    
    class ChartMyComponent extends React.Component {
      render () {
        return (
          <div className='chart-my-component'>
            <h1>{this.props.chart.options.title}</h1>
            <table>
              <tr>
                <th>City</th>
                <th>Data</th>
              </tr>
              {this.props.chart.data.results.map((result, i) => {
                return <tr key={i}>
                  <td>{result.scales.city}</td>
                  <td>{result.data.quantity.sum[0].value}</td>
                </tr>
              })}
            </table>
          </div>
        )
      }
    }
    
    ChartMyComponent.propTypes = {
      chart: PropTypes.object
    }
    
    export default ChartMyComponent
    Warning

    この例では、ハードコードされた行がいくつかあります。 したがって、関連するJSONのクエリを変更した場合、チャートは動作しません。

    <td>{result.scales.city}</td>
    <td>{result.data.quantity.sum[0].value}</td>

    次に、グラフのスケールデータを動的に検索する関数を作成します:

    import React from 'react'
    import PropTypes from 'prop-types'
    
    class ChartMyComponent extends React.Component {
      renderLine (result, i) {
        let values = []
        // Here we give a sample of loop that parses automatically a query result
        // You have 3 levels:
        // - data : It's the data you wan't to analyse, like turnover, quantity, etc....
        // - computeMode : It's a compute mode like sum, count, avg ...
        // - evol : You will always have 0 for 'now', but if you set an evol parameter like 'year', the previous year will be in 1
        // Here you just need to convert QueryBuilder values to an easier format (an array)
        for (let field in result.data) {
          for (let computeMode in result.data[field]) {
            for (let evol in result.data[field][computeMode]) {
              values.push(result.data[field][computeMode][evol].value)
            }
          }
        }
    
        return (
          <tr key={i}>
            {/* Here we get the scales from the result (in this case 'city' */}
            {Object.values(result.scales).map((scale, j) => {
              return <td key={j}>{scale}</td>
            })}
            {/* Here we display our values */}
            {values.map((d, j) => {
              return <td key={j}>{d}</td>
            })}
          </tr>
        )
      }
    
      render () {
        return (
          <div className='chart-my-component'>
            <h1>{this.props.chart.options.title}</h1>
            <table>
              {this.props.chart.data.results.map(this.renderLine.bind(this))}
            </table>
          </div>
        )
      }
    }
    
    ChartMyComponent.propTypes = {
      chart: PropTypes.object
    }
    
    export default ChartMyComponent

    最後に、クエリからテーブルのヘッダー行を動的に設定できます:

    import React from 'react'
    import PropTypes from 'prop-types'
    
    class ChartMyComponent extends React.Component {
      renderHeader () {
        let values = []
        // Here I loop over the request to create the column header
        let request = this.props.chart.request
        for (let field in request.data.fields) {
          for (let computeMode of request.data.fields[field]) {
            values.push(field + '-' + computeMode)
            if (request.evol && request.evol.scale) {
              values.push(field + '-' + computeMode + '-1')
            }
          }
        }
        return (
          <tr>
            {(request.scale.fields).map((scale, j) => {
              return <th key={j}>{scale}</th>
            })}
            {values.map((d, j) => {
              return <td key={j}>{d}</td>
            })}
          </tr>
        )
      }
    
      renderLine (result, i) {
        let values = []
        // Here I give a sample of loop for parsing automatically a query result
        // You have 3 level :
        // - data : It's the data you wan't to analyse, like ca, qte, etc....
        // - computeMode : Its a compute mode like sum, count, avg ...
        // - evol : You will always have 0 for 'now', but if you set an evol parameter like 'year', the last year will be in 1
        // Here we just need to convert QueryBuilder values to an easier format (an array)
        for (let field in result.data) {
          for (let computeMode in result.data[field]) {
            for (let evol in result.data[field][computeMode]) {
              values.push(result.data[field][computeMode][evol].value)
            }
          }
        }
    
        return (
          <tr key={i}>
            {/* Here we get the scales from the result (like in my case the 'siege_social' */}
            {Object.values(result.scales).map((scale, j) => {
              return <td key={i}>{scale}</td>
            })}
            {/* Here we display our values */}
            {values.map((d, j) => {
              return <td key={i}>{d}</td>
            })}
          </tr>
        )
      }
    
      render () {
        return (
          <div className='chart-my-component'>
            <h1>{this.props.chart.options.title}</h1>
            <table>
              {this.renderHeader.bind(this)()}
              {this.props.chart.data.results.map(this.renderLine.bind(this))}
            </table>
          </div>
        )
      }
    }
    
    ChartMyComponent.propTypes = {
      chart: PropTypes.object
    }
    
    export default ChartMyComponent

    コードの視覚的な結果は次のとおりです:

    代替テキスト


    ステップ3:D3.js、Chart.jsなどのグラフィックスライブラリを使用する

    最初の2つのステップでは、単純なテーブルを表示する方法を説明しました。

    次に、D3.jsのようなライブラリを使用して結果を接続する方法を見てみましょう。 この例では、以前の結果がhttp://bl.ocks.org/phuonghuynh/54a2f97950feadb45b07に接続されています。

    まず、プラグインによって要求される依存関係をindex.htmlに追加します(Webpackと互換性がないようなので、単に<body>タグに追加します)

    <!DOCTYPE html>
    <html>
      <head>
        <link rel="icon" type="image/png" href="assets/favicon.png" sizes="32x32">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <meta charset="utf-8">
        <title>Data Platform dashboard</title>
      </head>
      <body>
        <div id="root"></div>
        <script src="http://phuonghuynh.github.io/js/bower_components/jquery/dist/jquery.min.js"></script>
        <script src="http://phuonghuynh.github.io/js/bower_components/d3/d3.min.js"></script>
        <script src="http://phuonghuynh.github.io/js/bower_components/d3-transform/src/d3-transform.js"></script>
        <script src="http://phuonghuynh.github.io/js/bower_components/cafej/src/extarray.js"></script>
        <script src="http://phuonghuynh.github.io/js/bower_components/cafej/src/misc.js"></script>
        <script src="http://phuonghuynh.github.io/js/bower_components/cafej/src/micro-observer.js"></script>
        <script src="http://phuonghuynh.github.io/js/bower_components/microplugin/src/microplugin.js"></script>
        <script src="http://phuonghuynh.github.io/js/bower_components/bubble-chart/src/bubble-chart.js"></script>
        <script src="http://phuonghuynh.github.io/js/bower_components/bubble-chart/src/plugins/central-click/central-click.js"></script>
        <script src="http://phuonghuynh.github.io/js/bower_components/bubble-chart/src/plugins/lines/lines.js"></script>
      </body>
    </html>

    次に、リンク先の例をcomponentDidMountメソッドにコピーして貼り付けます。 いくつかの変更が必要です:

    • jQueryから$(document).readyを削除する、ReactJSでは使用されません
    • containerプロパティを使用して、DOMノードをd3.jsに渡し、render関数にあるdivに描画できるようにします。
    import React from 'react'
    import PropTypes from 'prop-types'
    
    class ChartMyComponent extends React.Component {
      componentDidMount () {
        new window.d3.svg.BubbleChart({
          supportResponsive: true,
          container: this.refs.chart,
          size: 600,
          innerRadius: 600 / 3.5,
          radiusMin: 50,
          data: {
            items: [
              { text: 'Java', count: '236' },
              { text: '.Net', count: '382' },
              { text: 'Php', count: '170' },
              { text: 'Ruby', count: '123' },
              { text: 'D', count: '12' },
              { text: 'Python', count: '170' },
              { text: 'C/C++', count: '382' },
              { text: 'Pascal', count: '10' },
              { text: 'Something', count: '170' }
            ],
            eval: function (item) { return item.count },
            classed: function (item) { return item.text.split(' ').join('') }
          },
          plugins: [
            {
              name: 'central-click',
              options: {
                text: '(See more detail)',
                style: {
                  'font-size': '12px',
                  'font-style': 'italic',
                  'font-family': 'Source Sans Pro, sans-serif',
                  'text-anchor': 'middle',
                  'fill': 'white'
                },
                attr: { dy: '65px' },
                centralClick: function () {
                  alert('Here is more details!!')
                }
              }
            },
            {
              name: 'lines',
              options: {
                format: [
                  {// Line #0
                    textField: 'count',
                    classed: { count: true },
                    style: {
                      'font-size': '28px',
                      'font-family': 'Source Sans Pro, sans-serif',
                      'text-anchor': 'middle',
                      fill: 'white'
                    },
                    attr: {
                      dy: '0px',
                      x: function (d) { return d.cx },
                      y: function (d) { return d.cy }
                    }
                  },
                  {// Line #1
                    textField: 'text',
                    classed: { text: true },
                    style: {
                      'font-size': '14px',
                      'font-family': 'Source Sans Pro, sans-serif',
                      'text-anchor': 'middle',
                      fill: 'white'
                    },
                    attr: {
                      dy: '20px',
                      x: function (d) { return d.cx },
                      y: function (d) { return d.cy }
                    }
                  }
                ],
                centralFormat: [
                  {// Line #0
                    style: { 'font-size': '50px' },
                    attr: {}
                  },
                  {// Line #1
                    style: { 'font-size': '30px' },
                    attr: { dy: '40px' }
                  }
                ]
              }
            }]
        })
      }
    
      render () {
        return <div ref='chart' />
      }
    }
    
    ChartMyComponent.propTypes = {
      chart: PropTypes.object
    }
    
    export default ChartMyComponent

    これまでのところ、オンラインで見つかった例と同じグラフが表示されます。

    独自のデータを表示するには、チャートによって要求される形式にthis.props.chart.dataオブジェクトを変換します。

    getItemsメソッドを追加します:

    getItems () {
      return this.props.chart.data.results.map(item => {
        return {
          text: item.scales.city,
          count: item.data.quantity.sum[0].value
        }
      })
    }

    チャート設定で呼び出します:

    radiusMin: 50,
    data: {
      items: this.getItems(),
      eval: function (item) { return item.count },
      classed: function (item) { return item.text.split(' ').join('') }
    },
    plugins: [

    これが最終結果です:

    代替テキスト

    さらに深く掘り下げる

    ソリューションの実装に関するトレーニングや技術サポートが必要な場合は、営業担当者にお問い合わせください、またはこのリンクをクリックして見積もりを受け取り、プロフェッショナルサービスの専門家にプロジェクトのカスタム分析を依頼してください。

    Data Platformを構築するチームと直接質問し、フィードバックを共有し、相互作用するには、専用のDiscordチャネルにアクセスしてください。

    OVHcloudサービスについてサポートが必要な場合は、ヘルプセンターでリクエストを作成してください。

    ユーザーコミュニティに参加してください。