MySqlとGolangとVue.jsで株価チャートを表示する。(APEXCHARTS)

以前の記事[[Vue.jsで株価チャートを表示する良さげなツールを紹介(APEXCHARTS)]](https://qiita.com/_kyamasan/items/44079d4b5a9c9c913521)をさらに実践的にしてみました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/466621/636accb7-fc0c-9a18-e9ae-f8add107b08e.png)

##やりたい事
①.Golang(バックエンド)で必要なデータ("x"に日付、"y"に株価データ(始値,高値,安値,終値))をMySqlから取得する。※データの構造については[前回記事](https://qiita.com/_kyamasan/items/44079d4b5a9c9c913521)参照
②.①のデータをVue.js(フロントエンド)で受け取り、チャートとして表示する。



##①Golang(バックエンド)で必要なデータをMySqlから取得する。

main.goとdata.goの2ファイルを用意。

>r.FormValue("cd")

表示したい銘柄コードはフロント側から受け取れるようにしておきます。

>allowedOrigins := handlers.AllowedOrigins([]string{""})

地味にハマった点ですが、CORSの設定を正しく行わないとVue側でデータを受け取れません。この部分については[po3rinさんの記事](https://qiita.com/po3rin/items/c70105f684e6816621d2)が参考になりました！感謝！

```main.go
package main

import (
	"encoding/json"
	"net/http"
	"os"
	"stockcoder/server/db"

	"github.com/gorilla/handlers"
	"github.com/gorilla/mux"
	"github.com/joho/godotenv"
)

func dataHandler(w http.ResponseWriter, r *http.Request) {
//表示したい銘柄コードはGolang側で受け取る。
	cd := r.FormValue("cd")
	df, _ := db.GetData(cd)
	json.NewEncoder(w).Encode(df)
}

//CORSの設定を行う
func main() {
	allowedOrigins := handlers.AllowedOrigins([]string{""})
	allowedMethods := handlers.AllowedMethods([]string{"GET", "HEAD", "POST", "PUT", "OPTIONS"})
	allowedHeaders := handlers.AllowedHeaders([]string{"X-Requested-With"})

	godotenv.Load()
	router := mux.NewRouter()
	port := os.Getenv("SERVER_PORT")
	router.HandleFunc("/data/", dataHandler)
	http.ListenAndServe(":"+port, handlers.CORS(allowedOrigins, allowedMethods, allowedHeaders)(router))
}

```

MySqlへの接続方法は以前の記事[[GolangでMySql(GCP)に接続する方法]](https://qiita.com/_kyamasan/items/51f7abb43e976ed07f5a)を参照。


>type Price struct {
	Date        string `json:"x"`
	PriceRecord string `json:"y"`
}

jsonの列名は上記のようにすれば上書きできます。APEXCHARTSでxとyという列名が必要だった為、ここで上書き。


>strings.Replace((strings.Replace(string(jsonBytes), `"[`, `[`, -1)), `]"`, `]`, -1)

json整形の為に、strings.Replaceで不要な”やら[やらを消したりしていたのですが、もっと良い方法がある、という方は教えていただきたいです。(みんなどうやってるんだろう？？)

```data.go
package db

import (
	"encoding/json"
	"log"
	"os"
	"strings"

	"github.com/GoogleCloudPlatform/cloudsql-proxy/proxy/dialers/mysql"
)

//銘柄コードと株価情報の配列を使用
type StockData struct {
	cd     string
	Prices []Price
}

//ApexChartsでデータ表示する為にjson列名をxとyに上書き
type Price struct {
	Date        string `json:"x"`
	PriceRecord string `json:"y"`
}

func GetData(cd string) (data string, e error) {
	//MySqlへの接続方法は前回記事参照

	cmd :=
		`SELECT
		Date,
		CONCAT('[',CAST(OpeningPrice AS CHAR(50)),',',
		CAST(HighPrice AS CHAR(50)),',',
		CAST(LowPrice AS CHAR(50)),',',
		CAST(ClosingPrice AS CHAR(50)),']') AS PriceRecord
		FROM StockData
		WHERE CD = ` + cd + `
		ORDER BY Date`

	rows, err := db.Query(cmd)
	if err != nil {
		log.Fatal("Wrong Query")
	}

	var prices []Price
	var date string
	var priceRecord string

	for rows.Next() {
		err := rows.Scan(&date, &priceRecord)
		if err != nil {
			log.Fatal("Scan Failure")
		}

		price := Price{
			Date:        date,
			PriceRecord: priceRecord,
		}
		prices = append(prices, price)
	}

	jsonBytes, _ := json.Marshal(prices)

	//JsonDataをVue側で受け取れるように整形
	jsonData := strings.Replace((strings.Replace(string(jsonBytes), `"[`, `[`, -1)), `]"`, `]`, -1)

	return jsonData, nil
}
```

##②.①のデータをVue.js(フロントエンド)で受け取り、チャートとして表示する。

>getData: async function () {
    const newData = await axios.get('http://localhost:8080/data/', {params: {'cd' : this.cd}})
      this.series = [{
        data: JSON.parse(newData.data)
      }]

axiosでGolangから受け取ったデータをJSON.parseで変換するだけです。意外と簡単でした。

```Chart.vue
<template>
  <div class="main">
    <label>銘柄コード(例 ソフトバンクグループ:9984、キーエンス:6861)</label>
    <div class="field center">
        <input type="number" v-model="cd" placeholder="9984">
        <button class="btn purple lighten-1" width=900px @click="getData">Show Chart</button>
    </div>
    <div class="field chart center">
        <apexchart type="candlestick" :options="chartOptions" :series="series"></apexchart>
    </div>
  </div>
</template>

<script>
import axios from 'axios'
import ApexCharts from 'apexcharts'

export default {
  methods: {
    getData: async function () {
    const newData = await axios.get('http://localhost:8080/data/', {params: {'cd' : this.cd}})
      this.series = [{
        data: JSON.parse(newData.data)
      }]
    }
  },

  data: function() {
    return {
      chartOptions: {
        title: {
          text: '',
          align: 'left'
        },
        xaxis: {
          type: 'datetime'
        },
        yaxis: {
          tooltip: {
            enabled: false
          }
        }
      },
      
      series: [{
        data: ""
      }],
    }
  },
};
</script>
```

##まとめ
今回、GolangとVue.jsで初めてのアプリを作ってみました。
私の検索スキルが低すぎて、作っていく中で何度も壁にぶつかりましたが、新しい技術を勉強するのは楽しいですね。
記事やソースで修正、改善すべき点があれば、ぜひコメントしていただけると幸いです。
お読みいただき、ありがとうございました。