LoginSignup
29
27

More than 5 years have passed since last update.

vue.jsでcsvファイルのデータ抽出表示とオセロ

Last updated at Posted at 2016-12-02

エクセルなどで使われるCSVファイルをブラウザで表示して見るツール
デモ:http://pie.karou.jp/zf.html

index.png

サンプルとして郵便番号と住所の書いてあるcsvファイルが
ちょうどよいので”郵便番号 csv”で検索してダウンロードする

全国のデータ KEN_ALL_ROME.CSV 10.5MB
"0640941","北海道","札幌市 中央区","旭ケ丘","HOKKAIDO","SAPPORO SHI CHUO KU","ASAHIGAOKA"
1行がこんな感じで 12万行


  1. csvファイルをinput fileで選択する
  2. csvファイルはshiftJISが多くて文字化けするのでライブラリencoding.jsを使って対策する
  3. 12万行も表示できないので30行だけ表示する(ファイルを開くのに5秒くらい)
  4. and検索をするために

    Array.filter(function(v){
    return v.join("").indexOf("東京")>-1);
    }).filter(function(v){
    return v.join("").indexOf("新宿")>-1);
    });
    

    これでデータ抽出すると1秒以下で697件見つけて表示される


<!doctype html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>csvファイル検索ツール</title>
<style>
h1{font-size: 16px;display:inline;}
p{display:inline;}
input[type=number]{width:80px;}
</style>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.4/jquery.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.0.7/vue.min.js"></script>
<script src="folder3/encoding.min.js"></script>
</head>
<body>
<div id="app">
   <h1>csvファイル 検索ツール(簡易オートフィルタ)</h1>
   <input type="file" @change="fileChange">
   <p>列幅調整はセル内でBackspace,←,→キー</p>
   <hr>
   検索文字:<input type="text" id="filter1">and<input type="text" id="filter2">
   行:<input type="number" id="maxGyou" step="10" min="10" value="30">
   <input type="button" @click="filterFn" value="抽出">
   ページ:
   <select v-model="index">
     <option v-for="n in pageLength" v-bind:value="n">{{n}} </option>
   </select> /{{ (pageLength==100)?"over": pageLength}}
   <input type="button" value="←" @click="plus(-1)">
   <input type="button" value="→" @click="plus(1)">
   一致数:{{ matchNum }}
   <hr>
   <div v-for="n in gyouNum" style="white-space: nowrap;">
      <input type="text" v-for="(v,i) in csvData[(index-1)*gyouNum + (n-1)]" :value="v" 
      @keyup.left="css(i,-25)" @keyup.right="css(i,50)" @keyup.delete="css(i,-1000)" 
      :style="{color : (colorArr[i] || 'black'), width: (widthArr[i] || 150) + 'px' }" readonly="readonly">
   </div>
</div>
<script>
var vm = new Vue({
   el: '#app',
   data: {
      index: 1,
      gyouNum: 30,
      fileData: [],
      csvData: [],
      widthArr: [],
      colorArr: [],
      matchNum: 0,
   },
   computed: {
      pageLength: function() {
         return Math.ceil(this.csvData.length / this.gyouNum);
      },
   },
   methods: {
      fileChange: function(e) {
         $("#filter1,#filter2").val("");
         var file = e.target.files[0];
         var reader = new FileReader();
         reader.onload = function(e) {
            var codes = new Uint8Array(e.target.result);
            var encoding = Encoding.detect(codes);
            var unicodeString = Encoding.convert(codes, {
               to: 'unicode',
               from: encoding,
               type: 'string'
            });
            var arr = unicodeString.trim().replace(/\"/g, "").split("\n");
            vm.fileData = arr.map(v => v.split(","));
            vm.filterFn();
         };
         reader.readAsArrayBuffer(file);
      },
      plus: function(x) {
         if (this.index + x <= 0 || this.index + x > this.pageLength) return;
         this.index += x;
      },
      css: function(x, y) {
         this.widthArr[x] = this.widthArr[x] || 150;
         this.widthArr[x] += y;
         if (this.widthArr[x] < 15) {
            this.widthArr[x] = 10;
            this.colorArr[x] = "white";
         } else {
            this.colorArr[x] = "black";
         }
         this.colorArr.push();
         this.widthArr.push();
      },
      filterFn: function() {
         this.index = 1;
         this.gyouNum = $("#maxGyou").val() - 0;
         var filter1 = $("#filter1").val().toLowerCase();
         var filter2 = $("#filter2").val().toLowerCase();
         var arr = this.fileData.filter(function(v) {
            return v.join("").toLowerCase().indexOf(filter1) > -1;
         }).filter(function(v, i) {
            return v.join("").toLowerCase().indexOf(filter2) > -1;
         });
         this.matchNum = arr.length;
         this.csvData = arr.filter(function(v, i) {
            return i < vm.gyouNum * 100;
         });
      },
   },
});
</script>
</body>
</html>


vue.jsで書いたオセロ
https://jsfiddle.net/af9b4bq3/

<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.0.7/vue.min.js"></script>
<p>オセロ</p>
<div id="app">
  <p>白:{{ w }}, 黒:{{ b }}</p>
  <p>{{ ["白","黒"][wb] }}の手番</p>
  <div v-for="i in 8" class="container">
    <div v-for="j in 8" class="waku">
      <div :class="{ 'white': xy[i][j]==0, 'black': xy[i][j]==1 }" @click="oku(i, j)"></div>
    </div>
  </div>
  <p>
    <button @click="pass">pass</button>
  </p>
</div>
p {
  text-align: center;
}
div {
  min-width: 35px;
  min-height: 35px;
}
.container {
  display: flex;
  justify-content: center;
}
.waku {
  border: 1px solid black;
  background-color: green;
}
.white {
  border-radius: 35px;
  background-color: white;
}
.black {
  border-radius: 35px;
  background-color: black;
}
var vm = new Vue({
  el: '#app',
  data: {
    wb: 1,
    xy: [
      [3, 3, 3, 3, 3, 3, 3, 3, 3, 3],
      [3, 2, 2, 2, 2, 2, 2, 2, 2, 3],
      [3, 2, 2, 2, 2, 2, 2, 2, 2, 3],
      [3, 2, 2, 2, 2, 2, 2, 2, 2, 3],
      [3, 2, 2, 2, 0, 1, 2, 2, 2, 3],
      [3, 2, 2, 2, 1, 0, 2, 2, 2, 3],
      [3, 2, 2, 2, 2, 2, 2, 2, 2, 3],
      [3, 2, 2, 2, 2, 2, 2, 2, 2, 3],
      [3, 2, 2, 2, 2, 2, 2, 2, 2, 3],
      [3, 3, 3, 3, 3, 3, 3, 3, 3, 3],
    ],
  },
  computed: {
    w: function() {
      return (this.xy.join('').match(/0/g) || []).length;
    },
    b: function() {
      return (this.xy.join('').match(/1/g) || []).length;
    },
  },
  methods: {
    oku: function(x, y) {
      if (this.xy[x][y] != 2) return;
      var flag = false;
      for (var dx = -1; dx <= 1; dx++) {
        for (var dy = -1; dy <= 1; dy++) {
          if (dx == 0 && dy == 0) continue;
          var k = 1;
          while (this.xy[x + k * dx][y + k * dy] <= 1) {
            if (this.xy[x + k * dx][y + k * dy] == this.wb) {
              k = 1;
              while (this.xy[x + k * dx][y + k * dy] == 1 - this.wb) {
                flag = true;
                this.xy[x + k * dx][y + k * dy] = this.wb;
                k++;
              }
              break;
            }
            k++;
          }
        }
      }
      if (flag == false) return;
      this.xy[x][y] = this.wb;
      this.wb = 1 - this.wb;
      this.xy.push();
    },
    pass: function() {
      this.wb = 1 - this.wb;
    },
  },
});
29
27
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
29
27