(0) 준비 파일

05. Spark 전자정부 프레임워크(eGov 없는거).zip     639MB

05. Spark 전자정부 프레임워크(eGov 3.9.0 포함).zip     2GB

 

(1) 자바 (구드 다운) > 환경설정 해야함(home, path)

 

(2) 전자정부 설정

1 전자정부 원하는 경로에 폴더 복사해서 설치
2 전자정부 안에 있는 이클립스 실행해서 workspace 설정(eGovFrameDev 디렉토리 내에 있는 workspace를 잡는 것이 일반적이다.)

maven, servers, upload 폴더를 만든다

 

window -> perspective -> open perspective -> Other -> eGovFrame

 

window -> show view 에서 하단바
Problems, Tasks, Servers, Console, Javadoc, SQL Results, Query Result

window -> show view 에서 좌측바
Navigator   <- 만약 하단바에 추가되면 좌측바로 끌어다 놓으면 된다. 이클립스, 스프링때 Package Explorer에서 했지만 전자정부는 이 Navigator에서 할거다!!!

 

(3) MariaDB 설정 (데이터베이스 생성)

1 MariaDB 설치

마리아 DB 계정 1234, 비번 1234로 했음. 설치할 때 UTF-8 빼먹지 말 것

포트 3308로 하자

 

2 my.ini 수정

마리아DB 설치 폴더 > data > my.ini 메모장으로 열기

[mysqld]
datadir=C:/Program Files/MariaDB 10.4/data
port=3308
innodb_buffer_pool_size=1535M
character-set-server=utf8
collation-server=utf8_general_ci
init_connect=SET collation_connection=utf8_general_ci
init_connect=SET NAMES utf8
skip-character-set-client-handshake

[client]
port=3308
plugin-dir=C:/Program Files/MariaDB 10.4/lib/plugin
default-character-set=utf8

[mysql]
default-character-set=utf8

이렇게 수정한다. 'innodb_buffer_pool_size=16384M' 여기 용량은 시스템 상황에 따라 적절히 설정... MariaDB 설치시 Buffur pool size 설정하는거랑 같은거다. 

마리아DB가 설치한 원본 소스...

더보기
[mysqld]
datadir=C:/Program Files/MariaDB 10.4/data
port=3308
innodb_buffer_pool_size=1535M
character-set-server=utf8

[client]
port=3308
plugin-dir=C:/Program Files/MariaDB 10.4/lib/plugin

[mysql]
default-character-set=utf8

 

3 데이터베이스랑 테이블 만들기

데이터베이스는 'test' 

테이블은 아래 이름으로 생성

tbl_attach

CREATE TABLE `tbl_attach` (
	`idx` INT(11) NOT NULL COMMENT '게시물아이디',
	`seq` INT(11) NOT NULL COMMENT '순번',
	`filename` VARCHAR(256) NULL DEFAULT NULL COMMENT '파일명',
	`writer` VARCHAR(50) NULL DEFAULT NULL COMMENT '등록자',
	`indate` DATETIME NULL DEFAULT NULL COMMENT '등록일',
	PRIMARY KEY (`idx`, `seq`)
)
COLLATE='utf8_general_ci'
;

 

tbl_board

CREATE TABLE `tbl_board` (
	`idx` INT(11) NOT NULL AUTO_INCREMENT COMMENT '게시물아이디',
	`title` VARCHAR(300) NULL DEFAULT NULL COMMENT '제목',
	`contents` VARCHAR(4000) NULL DEFAULT NULL COMMENT '내용',
	`count` INT(11) NULL DEFAULT NULL COMMENT '조회수',
	`writer` VARCHAR(50) NULL DEFAULT NULL COMMENT '등록자',
	`indate` DATETIME NULL DEFAULT CURRENT_TIMESTAMP COMMENT '등록일',
	PRIMARY KEY (`idx`)
)
COLLATE='utf8_general_ci'
;

 

tbl_reply

CREATE TABLE `tbl_reply` (
	`idx` INT(11) NOT NULL COMMENT '게시물아이디',
	`seq` INT(11) NOT NULL COMMENT '순번',
	`reply` VARCHAR(1000) NULL DEFAULT NULL COMMENT '댓글',
	`writer` VARCHAR(50) NULL DEFAULT NULL COMMENT '작성자',
	`indate` DATETIME NULL DEFAULT NULL COMMENT '작성일',
	PRIMARY KEY (`idx`, `seq`)
)
COLLATE='utf8_general_ci'
;

 

tbl_user

CREATE TABLE `tbl_user` (
	`user_id` VARCHAR(30) NULL DEFAULT NULL COMMENT '아이디',
	`user_name` VARCHAR(50) NULL DEFAULT NULL COMMENT '이름',
	`password` VARCHAR(20) NULL DEFAULT NULL COMMENT '비밀번호',
	`use_yn` VARCHAR(1) NULL DEFAULT NULL COMMENT '사용여부'
)
COLLATE='utf8_general_ci'
;

 

tbl_user에 샘플 데이터 추가

tbl_user 테이블에서 '데이터' 탭에 가서 우클릭 하고 '행 삽입'

INSERT INTO tbl_user VALUES ("admin","관리자","1234","Y");
INSERT INTO tbl_user VALUES ("guest","사용자","1234","Y");

 

(4) Maven 설정

https://www.egovframe.go.kr/wiki/doku.php?id=egovframework:dev3.9:gettingstarted

다운로드

settings.xml에서 다른건 다 주석처리...
주석처리 안 된 건 repository를 바꿔주는거 한 줄이다. (기본 디렉토리는 ~/.m2/repository)

온라인 환경이면 pom.xml에 올려놓은 dependency가 온라인으로 자동 설치된다.
오프라인 환경일 경우는 직접 repository에 파일 추가한다.

1 위에 설치한 전자정부 폴더 안에 maven 폴더 만들기
2 maven 폴더 안에 (4) 링크에서 받은 settings.xml 파일 넣기(디렉토리 수정)

<settings> 
  <!-- localRepository 
   | The path to the local repository maven will use to store artifacts. 
   | 
   | Default: ~/.m2/repository 
  <localRepository>/path/to/local/repo</localRepository> 
  --> 
  <localRepository>C:/eGovFrameDev-3.9.0-64bit/maven/repository</localRepository>

위아래 전부 주석이다... 유일하게 살아있는 코드는 이거다 maven repository(빨간색)를 설정해주면 된다.

3 2에서 만든 settigns를 내 이클립스(전자정부)의 maven settigns로 설정한다.

이런식으로 한다



4 (오프라인 환경일 경우만 한다) maven 폴더 안에 repository 폴더 만들고 (4) 링크에서 받은 'maven_repository_3_9' 폴더 안에 있는거 복사하기(이 repository 경로는 위에 settings.xml이 설정)

 

(5) tomcat 톰캣 서버 설정

톰캣 홈페이지에서 다운로드 하고 서버에(Preferences > Server > Runtime Environments) 추가... 스프링 수업때 하던거 그대로 하면 됨

 

(6) MariaDB 데이터베이스 설정

Data Source Explorer > Database Connections > New

'MySQL' 선택하고 Next

'New' 빨간색 표시 버튼 누르기

'Name/Type' 탭에서 시스템 버전에 맞게 선택(일치하는 버전이 없다면 그 중 최신으로 선택) 

'JAR List' 탭 가서 기존꺼 삭제, 'Add JAR/Zip'

(4) 2에서 설정한 경로에 들어가서 repository 내에 mysql을 찾아 들어가서 connector 안에 jar 파일을 찾아서 선택한다. (만약 repository에 mysql이 없다면 pom.xml dependency에서 mysql을 확인한다.)

C:/eGovFrameDev-3.9.0-64bit/maven/repository/mysql/mysql-connector-java/5.1.31

선택하면 DB 설정으로 넘어간다

cf. jdbc:mysql://[host][,failoverhost...][:port]/[database][?propertyName1][=propertyValue1][&propertyName2][=propertyValue2]...

 

(3)에서 설치할 때 입력한 ID, PW, 포트번호 그리고 (3)에서 만든 Database 이름을 넣고 테스트를 한다.

테스트 후 Finish!!

 

(7) 프로젝트 생성 (게시판 예제)

1 eGovFrame > Start > New Web Project 또는 우클릭 > New > eGovFrame Web Project

'Next' 누르고 다음 화면에서 예제 생성한 다음 'Finish' 누르고 한참 걸림

2 pom.xml 수정

안에 dependency 보면 주석된 부분이 있다. 그 중 가장 하단 ojdbc 오라클만 남기고 주석 해제

        <!-- mysql이나 oracle DB 사용시 아래 설정 추가  
        <dependency>
            <groupId>com.googlecode.log4jdbc</groupId>
            <artifactId>log4jdbc</artifactId>
            <version>1.2</version>
            <exclusions>
                <exclusion>
                    <artifactId>slf4j-api</artifactId>
                    <groupId>org.slf4j</groupId>
                </exclusion>
            </exclusions>
        </dependency>
        
        <dependency>
            <groupId>commons-dbcp</groupId>
            <artifactId>commons-dbcp</artifactId>
            <version>1.4</version>
        </dependency>
        
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.31</version>
        </dependency>

        <dependency>
            <groupId>ojdbc</groupId>
            <artifactId>ojdbc</artifactId>
            <version>14</version>
            <scope>system</scope>
            <systemPath>${basedir}/src/main/webapp/WEB-INF/lib/ojdbc-14.jar</systemPath>
        </dependency>
        -->

이거를

        <dependency>
            <groupId>com.googlecode.log4jdbc</groupId>
            <artifactId>log4jdbc</artifactId>
            <version>1.2</version>
            <exclusions>
                <exclusion>
                    <artifactId>slf4j-api</artifactId>
                    <groupId>org.slf4j</groupId>
                </exclusion>
            </exclusions>
        </dependency>
        
        <dependency>
            <groupId>commons-dbcp</groupId>
            <artifactId>commons-dbcp</artifactId>
            <version>1.4</version>
        </dependency>
        
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.31</version>
        </dependency>

	<!-- 오라클 주석처리
        <dependency>
            <groupId>ojdbc</groupId>
            <artifactId>ojdbc</artifactId>
            <version>14</version>
            <scope>system</scope>
            <systemPath>${basedir}/src/main/webapp/WEB-INF/lib/ojdbc-14.jar</systemPath>
        </dependency>
        -->

이렇게 바꾼다

 

(8) commom component 공통 컴포넌트 추가

프로젝트 우클릭 > New > eGovFrame Common Component

'게시판' 하나만 누르면 나머지 알아서 선택된다 그리고 Next >

아래 표시 순서대로 진행

'OK' 선택

 

(9) resources > egovframwork 공통 컴포넌트 상용자화 1
     globals.properties (DB 접속 정보 수정)

src > main > resources > egovframework > egovProps 안에

globals.properties

#mysql
Globals.mysql.DriverClassName=net.sf.log4jdbc.DriverSpy
Globals.mysql.Url=jdbc:log4jdbc:mysql://127.0.0.1:3306/com
Globals.mysql.UserName =test
Globals.mysql.Password =xz4fmrSdr1vGGl6UtwPLwA%3D%3D

# 파일 업로드 경로(경로 설정은 반드시 절대경로를 사용해야함, 경로 뒤에 /를 붙여 주어야함.)
Globals.fileStorePath =C:/egovframework/upload/
# 업로드 URL 경로 암호화 KEY
#Globals.filePath.Encryption.key = 10자리이상,알파벳 및 숫자 및 특수기호 혼용하여 키를 지정한다. 
# 파일 확장자 화이트리스트(허용목록) : 파일 확장자를 (.)과 함께 연이어서 사용함. 
Globals.fileUpload.Extensions =.gif.jpg.jpeg.png
Globals.fileUpload.maxSize =1048576
Globals.fileDownload.Extensions =.gif.jpg.jpeg.png

이 부분을 수정해야한다.

#mysql
Globals.mysql.DriverClassName=net.sf.log4jdbc.DriverSpy
Globals.mysql.Url=jdbc:log4jdbc:mysql://127.0.0.1:3308/test
Globals.mysql.UserName =root
Globals.mysql.Password =root

# 파일 업로드 경로(경로 설정은 반드시 절대경로를 사용해야함, 경로 뒤에 /를 붙여 주어야함.)
Globals.fileStorePath =C:/eGovFrameDev-3.9.0-64bit/upload/
# 업로드 URL 경로 암호화 KEY
#Globals.filePath.Encryption.key = 10자리이상,알파벳 및 숫자 및 특수기호 혼용하여 키를 지정한다. 
# 파일 확장자 화이트리스트(허용목록) : 파일 확장자를 (.)과 함께 연이어서 사용함. 
Globals.fileUpload.Extensions =.gif.jpg.jpeg.png.zip.mp3.mp4.m4v.m4a.aac.7z.tar
Globals.fileUpload.maxSize =1048576
Globals.fileDownload.Extensions =.gif.jpg.jpeg.png.zip.mp3.mp4.m4v.m4a.aac.7z.tar

cf. jdbc:mysql://[host][,failoverhost...][:port]/[database][?propertyName1][=propertyValue1][&propertyName2][=propertyValue2]...

 

(10) resources > egovframwork 공통 컴포넌트 상용자화 2
    안 쓰는 mapper 맵퍼 삭제

resources > egovframework > mapper가 있다. 여기서 공통 컴포넌트가 자동 생성한 com 하위 디렉토리를 모두 열어 사용 예정인 DB를 제외한 맵퍼는 모두 삭제한다. 해당 예제에서는 mysql을 제외하고 모두 삭제하면 된다.

 

(11) resources > egovframwork 공통 컴포넌트 상용자화 3
      spring 수정 (context-crypto.xml, context-datasource.xml)

 

context-crypto.xml > 'false'로 수정

context-datasource.xml

<property name="password" value="#{egovEnvCryptoService.getPassword()}"/> 를

<property name="password" value="${Globals.mysql.Password}"/> 로 수정.

 

 

(12) webapp > bootstrap 부트스트랩, jQuery 설치

1 부트스트랩 압축 파일 다운 받고 폴더 이름 'bootstrap' 변경

board > src > webapp에 가서

css 안에 'bootstrap' 폴더 복사

js 안에 jQuery 파일 복사

 

 

2020/07/09 - [메모들...] - 전자정부 프레임 시작하기 2 (게시판 예제)

 

전자정부 프레임 시작하기 2 (게시판 예제)

 

greendreamtrre.tistory.com

 

주말에 내내 자바를 했는데 CRUD가 자꾸 에러가 난다... 회원가입, 관리... 이거 하나 완성시키기 왜이렇게 힘들까 ㅠㅠ

오늘은 딥러닝 시각인지를 하고 있다... 무슨 라이브러리인지도 모르는데 자꾸 새로운 라이브러리가 마구 튀어나온다... 대충이라도 뭔지 알고 가고 싶은데 검색할 시간 조차 없다 ㅠㅠ 잘 하고 있는건지 모르겠다... 성장하고 있다는 느낌이 전혀 없다... 그냥 오늘은 불어 듣다... 내일은 독어 듣다... 다음날은 스페인어 듣다... 한국에 왔는데 3일간 많이 배웠죠? 하는 느낌이랄까..

'개발자 > TIL' 카테고리의 다른 글

TIL 20.07.08  (0) 2020.07.08
TIL 20.07.07  (0) 2020.07.08
TIL 20.07.02  (0) 2020.07.04
TIL 20.07.01  (0) 2020.07.02
TIL 20.06.30  (0) 2020.07.01

자꾸만 밀려서 쓰네 ㅠㅠ

자바스크립트 시험을 쳤다.

네이버 주식 정보 real time request주소를 종목별로 따와서 서버에 저장하고, 그것을 이용해 주식 정보를 실시간으로 불러오는 것을 했다.

과거 30초 까지만 보여주며 실시간 갱신되는 것도 마찬가지...

시험이 생각보다 쉬워서 잘 풀었던 것 같다.

'개발자 > TIL' 카테고리의 다른 글

TIL 20.07.07  (0) 2020.07.08
TIL 20.07.06  (0) 2020.07.06
TIL 20.07.01  (0) 2020.07.02
TIL 20.06.30  (0) 2020.07.01
TIL 20.06.29  (0) 2020.06.29

문제

- sql실습
stockInfo 테이블 생성 후
stockName(varchar 100), stockUrl (varchar 500) 컬럼 생성, 선정한 주식 5종목 정보 저장(naver 증권에서 url 추출)

-오픈소스 프로그래밍
80포트 사용
/ 접속시 페이지 로드
/main 접속시 페이지 로드
/getStockInfo API : DB에 저장된 주식 목록 조회
/getStockPrice API : DB에 저장된 해당 주식의 url로 네이버 request를 전송하여 가격을 조회

-웹ui
selectbox에 DB에 저장된 5개 종목을 선택할 수 있게 하여 가격보기 버튼을 클릭 시
현재시점부터 최대 30초까지의 주식 정보를 1초에 한번씩 실시간으로 그래프로 출력

- 제출파일
1. heidisql에서 테이블 오른쪽버튼 클릭 -> 데이터베이스를 sql로 내보내기 후 데이터베이스 생성x, 테이블 생성x -> db.sql로 파일 저장
2. app.js 서버파일
3. main.html html파일
제목 : 이름_기말고사
세 파일을 압축 후 파일 첨부해서 870222@hanmail.net 으로 제출

 

방법 1.

app.js

var express = require('express');
var app = express();
var http = require('http');
var server = http.createServer(app).listen(80);
console.log("\n\nServer is running...\n\n")

var mysql = require('mysql');
var request = require('request');

var connection = mysql.createConnection({
  host: 'localhost',
  port: 3308,
  user:'root',
  password: '1234',
  database: 'javascript'
});
var bodyParser = require("body-parser");
app.use(bodyParser.urlencoded({limit: '50mb', extended: false}));
app.use(bodyParser.json({limit: '50mb'}));

app.get('/', function (req, res) {
  res.sendfile("stockList.html");
});
app.get('/main', function (req, res) {
  res.sendfile("stockList.html");
});

app.get('/realTimePrice', function (req, res) {
  res.sendfile("realTimePrice.html");
});

// 메인 페이지 접속시 stockInfo 테이블 정보를 가져오는 라우터
app.get('/getStockInfo', function (req, res) {
  var query = `SELECT * FROM stockInfo`;
  connection.query(query, function (err, rows, fields) {
      if (err) throw err;
      // console.log(rows);
      res.send(rows);
    }
  );
});

// 실시간 주식 정보를 가져오는 라우터
app.get('/getStockPrice', function (req, res) {
  var name = req.query.company;
  var query = `SELECT stockUrl FROM stockInfo WHERE stockName = '${name}'`;
  connection.query(query, function (err, rows, fields){
    if (err) throw err;
    // var response = JSON.stringify(rows); // 이렇게 하면 Object를 [{"stockUrl":"https://polling.finance.naver.com/api/realtime.nhn?query=SERVICE_ITEM:000660|SERVICE_RECENT_ITEM:000660"}] 로 변환해준다.
    var targetUrl = rows[0].stockUrl;
    const options = {
      url:`${targetUrl}`,
      method: 'GET'
    }

    request.get(options, function(err,httpResponse,body){
      response = JSON.parse(httpResponse.body);
      var price = response.result.areas[0].datas[0].nv;
      res.send(''+price);
    });
  });
});


// 서버 기동시 매 초마다 DB에 주식 정보를 기록
const hynix = {
  url:'https://polling.finance.naver.com/api/realtime.nhn?query=SERVICE_ITEM:000660|SERVICE_RECENT_ITEM:000660',
  method: 'GET'
}
const coway = {
  url:'https://polling.finance.naver.com/api/realtime.nhn?query=SERVICE_ITEM:021240|SERVICE_RECENT_ITEM:021240',
  method: 'GET'
}
const lgelectronics = {
  url:'https://polling.finance.naver.com/api/realtime.nhn?query=SERVICE_ITEM:066570|SERVICE_RECENT_ITEM:066570',
  method: 'GET'
}
const cj = {
  url:'https://polling.finance.naver.com/api/realtime.nhn?query=SERVICE_ITEM:001040|SERVICE_RECENT_ITEM:001040',
  method: 'GET'
}
const chongkundang = {
  url:'https://polling.finance.naver.com/api/realtime.nhn?query=SERVICE_ITEM:185750|SERVICE_RECENT_ITEM:185750',
  method: 'GET'
}
setInterval(function () {
  request.get(hynix, function(err,httpResponse,body){
    response = JSON.parse(httpResponse.body);
    var price = response.result.areas[0].datas[0].nv;
    connection.query(`INSERT INTO hynix (price) VALUES('${price}');`)
  });
  request.get(coway, function(err,httpResponse,body){
    response = JSON.parse(httpResponse.body);
    var price = response.result.areas[0].datas[0].nv;
    connection.query(`INSERT INTO coway (price) VALUES('${price}');`)
  });
  request.get(lgelectronics, function(err,httpResponse,body){
    response = JSON.parse(httpResponse.body);
    var price = response.result.areas[0].datas[0].nv;
    connection.query(`INSERT INTO lgelectronics (price) VALUES('${price}');`)
  });
  request.get(cj, function(err,httpResponse,body){
    response = JSON.parse(httpResponse.body);
    var price = response.result.areas[0].datas[0].nv;
    connection.query(`INSERT INTO cj (price) VALUES('${price}');`)
  });
  request.get(chongkundang, function(err,httpResponse,body){
    response = JSON.parse(httpResponse.body);
    var price = response.result.areas[0].datas[0].nv;
    connection.query(`INSERT INTO chongkundang (price) VALUES('${price}');`)
  });
},1000);

 

stockList.html (http://localhost/)

<!DOCTYPE html>
<html lang="en" dir="ltr">
  <head>
    <meta charset="utf-8">
    <title>주식 리스트</title>
  </head>
  <body>
    <h>주식 리스트 페이지입니다</h>
    <input type="button" value="실시간 주식 정보 조회하러 가기" id="mainBtn" onclick = "goToRealTimePrice()">
    <br><br>
    <span id="stockList"></span>

  </body>
  <script src="http://code.jquery.com/jquery-latest.min.js"></script>
  <script>
  $.ajax({
    url : 'getStockInfo',
    data : {
    },
    success : function(res){
      $("#stockList").append(`저장된 주식 리스트는 다음과 같습니다.<br>`);
      for (var i=0; i<res.length; i++) {
        var name = res[i].stockName;
        $("#stockList").append(`${name}<br>`);
      }
    }
  });

  function goToRealTimePrice() {
    location.href = "/realTimePrice"
  }
</script>
</html>

 

realTimePrice.html (http://localhost/realTimePrice)

<!DOCTYPE html>
<html lang="en" dir="ltr">
  <head>
    <meta charset="utf-8">
    <title>실시간 주식 정보</title>
  </head>
  <body>
    <h>실시간 주식 정보 페이지입니다</h>
    <input type="button" value="주식 리스트 보러 가기" id="mainBtn" onclick = "goToStockList()">
    <br>
    <select name="company" id="company">
      <option value="hynix">하이닉스</option>
      <option value="coway">코웨이</option>
      <option value="lgelectronics">LG전자</option>
      <option value="cj">CJ</option>
      <option value="chongkundang">종근당</option>
    </select>
    <input type="button" value="가격보기" onclick="sendRequest()">
    <br><br>
    <script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
    <div id="chart_div"></div>
  </body>
  <script  src="http://code.jquery.com/jquery-latest.min.js"></script>
  <script>
  function goToStockList() {
    location.href = "/"
  }

  var time;
  var stockPrice;
  var graphValue = [];
  var myGraph;
  // var graphValue = new Array(30);

  function sendRequest() {
    // 버튼 누를 때 초기화
    time = 0;
    graphValue = [];
    clearInterval(myGraph);
    var company = $("#company option:selected").val();
    // 버튼 누른 후 반복되는 부분
    myGraph = setInterval(function () {
         $.ajax({
           url : '/getStockPrice',
           type : 'GET',
           data : {
             company : `${company}`
           },
           success : function(res) {
             stockPrice = res;
             // console.log(res);
             graphValue.push([time,Number(stockPrice)])
             if (graphValue.length > 30) {
               graphValue.shift();
             }
             time++;
             drawCurveTypes(graphValue);   // 구글 차트를 그려주는 함수를 호출한다.
           }
         });
     },1000);
  };

  google.charts.load('current', {packages: ['corechart', 'line']});
  google.charts.setOnLoadCallback(drawCurveTypes);

  function drawCurveTypes() {
    var data = new google.visualization.DataTable();
    data.addColumn('number', '시간(초)');
    data.addColumn('number', '가격');
    // data.addColumn('number', `${company}`);

    data.addRows(graphValue);

    var options = {
      hAxis: {
        title: '시간(초)'
      },
      vAxis: {
        title: '가격(원)'
      },
      series: {
        1: {curveType: 'function'}
      }
    };

    var chart = new google.visualization.LineChart(document.getElementById('chart_div'));
    chart.draw(data, options);
  }

  </script>
</html>

방법 1은 realTImePrice.html이 서버에 요청을 보내면 /getStockPrice 라우터가 매 초 요청이 들어올 때마다 DB에서 URL을 새로 가져왔다. 그래서 방법 2에서 버튼을 누르면 setInterval이 시작되기 전에 /getStockInfo 라우터에 한 번 가서 URL을 가져오고 그것을 변수에 담아 /getStockPrice에 요청을 보내도록 수정했다. (방법 2가 방법 1보다 서버 부하를 줄이기 위해 개선되었음)

하지만 방법 1에서 배울 부분DB가 주는 response는 언제나

[
    { Key1 : Value1,
      Key2 : Value2,
      Key3 : Value3
    }
]

형태의 객체라는 것이다.

자바에서 DB가 보내주는 response를 ResultSet으로 받아서 객체의 i번째의 Key로 Value를 가져와 String으로 변환했던 것을 생각하자.

 

자바스크립트에서도 마찬가지로 객체의 i번째의 Key에 접근해서 Value를 가져와야한다.

첫 번째 방법은,

var response = JSON.stringify(rows);    이렇게 하면 Object를

[{"stockUrl":"https://polling.finance.naver.com/api/realtime.nhn?query=SERVICE_ITEM:000660|SERVICE_RECENT_ITEM:000660"}]

로 변환해준다. Object에서 이제 우리가 볼 수 있는 자료의 모습으로 바꿔주었고, 그 다음 response[0].stockUrl을 하면 된다.

 

두 번째 방법은 자바스크립트는 관대한 언어라 바로 이렇게만 해도 꺼내올 수 있다.

var targetUrl = rows[0].stockUrl;

 

 

방법 2.

app.js와 realTimePrice.html 2개만 바뀌었다.

app.js

var express = require('express');
var app = express();
var http = require('http');
var server = http.createServer(app).listen(80);
console.log("\n\nServer is running...\n\n")

var mysql = require('mysql');
var request = require('request');

var connection = mysql.createConnection({
  host: 'localhost',
  port: 3308,
  user:'root',
  password: '1234',
  database: 'javascript'
});
var bodyParser = require("body-parser");
app.use(bodyParser.urlencoded({limit: '50mb', extended: false}));
app.use(bodyParser.json({limit: '50mb'}));

app.get('/', function (req, res) {
  res.sendfile("stockList.html");
});
app.get('/main', function (req, res) {
  res.sendfile("stockList.html");
});

app.get('/realTimePrice', function (req, res) {
  res.sendfile("realTimePrice.html");
});

// 메인 페이지 접속시 stockInfo 테이블 정보를 가져오는 라우터, 실시간 주식 정보 페이지에서 '가격보기' 버튼 클릭시 해당 기업 주식 URL 정보 가져오는 라우터
app.get('/getStockInfo', function (req, res) {
  var query = `SELECT * FROM stockInfo`;
  connection.query(query, function (err, rows, fields) {
      if (err) throw err;
      // console.log(rows);
      res.send(rows);
    }
  );
});

// 실시간 주식 정보 페이지에서 '가격보기' 버튼 클릭시 주식 정보 읽어오는 라우터
app.get('/getStockPrice', function (req, res) {
  var stockUrl = req.query.stockUrl;
  const options = {
    url:`${stockUrl}`,
    method: 'GET'
  }
  request.get(options, function(err,httpResponse,body){
    response = JSON.parse(httpResponse.body);
    var price = response.result.areas[0].datas[0].nv;
    res.send(''+price);
  });
});

// 서버 기동시 매 초마다 DB에 주식 정보를 기록
const hynix = {
  url:'https://polling.finance.naver.com/api/realtime.nhn?query=SERVICE_ITEM:000660|SERVICE_RECENT_ITEM:000660',
  method: 'GET'
}
const coway = {
  url:'https://polling.finance.naver.com/api/realtime.nhn?query=SERVICE_ITEM:021240|SERVICE_RECENT_ITEM:021240',
  method: 'GET'
}
const lgelectronics = {
  url:'https://polling.finance.naver.com/api/realtime.nhn?query=SERVICE_ITEM:066570|SERVICE_RECENT_ITEM:066570',
  method: 'GET'
}
const cj = {
  url:'https://polling.finance.naver.com/api/realtime.nhn?query=SERVICE_ITEM:001040|SERVICE_RECENT_ITEM:001040',
  method: 'GET'
}
const chongkundang = {
  url:'https://polling.finance.naver.com/api/realtime.nhn?query=SERVICE_ITEM:185750|SERVICE_RECENT_ITEM:185750',
  method: 'GET'
}
setInterval(function () {
  request.get(hynix, function(err,httpResponse,body){
    response = JSON.parse(httpResponse.body);
    var price = response.result.areas[0].datas[0].nv;
    connection.query(`INSERT INTO hynix (price) VALUES('${price}');`)
  });
  request.get(coway, function(err,httpResponse,body){
    response = JSON.parse(httpResponse.body);
    var price = response.result.areas[0].datas[0].nv;
    connection.query(`INSERT INTO coway (price) VALUES('${price}');`)
  });
  request.get(lgelectronics, function(err,httpResponse,body){
    response = JSON.parse(httpResponse.body);
    var price = response.result.areas[0].datas[0].nv;
    connection.query(`INSERT INTO lgelectronics (price) VALUES('${price}');`)
  });
  request.get(cj, function(err,httpResponse,body){
    response = JSON.parse(httpResponse.body);
    var price = response.result.areas[0].datas[0].nv;
    connection.query(`INSERT INTO cj (price) VALUES('${price}');`)
  });
  request.get(chongkundang, function(err,httpResponse,body){
    response = JSON.parse(httpResponse.body);
    var price = response.result.areas[0].datas[0].nv;
    connection.query(`INSERT INTO chongkundang (price) VALUES('${price}');`)
  });
},1000);

 

realTimePrice.html (http://localhost/realTimePrice)

<!DOCTYPE html>
<html lang="en" dir="ltr">
  <head>
    <meta charset="utf-8">
    <title>실시간 주식 정보</title>
  </head>
  <body>
    <h>실시간 주식 정보 페이지입니다</h>
    <input type="button" value="주식 리스트 보러 가기" id="mainBtn" onclick = "goToStockList()">
    <br>
    <select name="company" id="company">
      <option value="hynix">하이닉스</option>
      <option value="coway">코웨이</option>
      <option value="lgelectronics">LG전자</option>
      <option value="cj">CJ</option>
      <option value="chongkundang">종근당</option>
    </select>
    <input type="button" value="가격보기" onclick="sendRequest()">
    <br><br>
    <script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
    <div id="chart_div"></div>
  </body>
  <script  src="http://code.jquery.com/jquery-latest.min.js"></script>
  <script>
  function goToStockList() {
    location.href = "/"
  }

  var time;
  var stockPrice;
  var graphValue = [];
  var myGraph;
  // var graphValue = new Array(30);

  function sendRequest() {
    // 버튼 누를 때 초기화
    time = 0;
    graphValue = [];
    clearInterval(myGraph);
    var company = $("#company option:selected").val();
    var stockUrl;
    $.ajax({
      url : 'getStockInfo',
      data : {
      },
      success : function(res){
        for (var i=0; i<res.length; i++) {
          if (company == res[i].stockName) {
            stockUrl = res[i].stockUrl;
            return;
          }
        }
      }
    });

    // 버튼 누른 후 반복되는 부분
    myGraph = setInterval(function () {
         $.ajax({
           url : '/getStockPrice',
           type : 'GET',
           data : {
             stockUrl : `${stockUrl}`
           },
           success : function(res) {
             stockPrice = res;
             // console.log(res);
             graphValue.push([time,Number(stockPrice)])
             if (graphValue.length > 30) {
               graphValue.shift();
             }
             time++;
             drawCurveTypes(graphValue);   // 구글 차트를 그려주는 함수를 호출한다.
           }
         });
     },1000);
  };

  google.charts.load('current', {packages: ['corechart', 'line']});
  google.charts.setOnLoadCallback(drawCurveTypes);

  function drawCurveTypes() {
    var data = new google.visualization.DataTable();
    data.addColumn('number', '시간(초)');
    data.addColumn('number', '가격');
    // data.addColumn('number', `${company}`);

    data.addRows(graphValue);

    var options = {
      hAxis: {
        title: '시간(초)'
      },
      vAxis: {
        title: '가격(원)'
      },
      series: {
        1: {curveType: 'function'}
      }
    };

    var chart = new google.visualization.LineChart(document.getElementById('chart_div'));
    chart.draw(data, options);
  }

  </script>
</html>

방법 1은 realTImePrice.html이 서버에 요청을 보내면 /getStockPrice 라우터가 매 초 요청이 들어올 때마다 DB에서 URL을 새로 가져왔다. 그래서 방법 2에서 버튼을 누르면 setInterval이 시작되기 전에 /getStockInfo 라우터에 한 번 가서 URL을 가져오고 그것을 변수에 담아 /getStockPrice에 요청을 보내도록 수정했다. 수정을 위해 app.js realTimePrice.html이 바뀌었다.

 

 

 

DB

더보기

stockInfo

CREATE TABLE javascript.stockInfo (
	stockName varchar(100) NULL,
	stockUrl varchar(500) NULL
)
ENGINE=InnoDB
DEFAULT CHARSET=utf8
COLLATE=utf8_general_ci;

 

hynix

CREATE TABLE javascript.hynix (
	price varchar(100) NULL,
	`timestamp` TIMESTAMP DEFAULT CURRENT_TIMESTAMP NULL
)
ENGINE=InnoDB
DEFAULT CHARSET=utf8
COLLATE=utf8_general_ci;

 

coway

CREATE TABLE javascript.coway (
	price varchar(100) NULL,
	`timestamp` TIMESTAMP DEFAULT CURRENT_TIMESTAMP NULL
)
ENGINE=InnoDB
DEFAULT CHARSET=utf8
COLLATE=utf8_general_ci;

 

lgelectronics

CREATE TABLE javascript.lgelectronics (
	price varchar(100) NULL,
	`timestamp` TIMESTAMP DEFAULT CURRENT_TIMESTAMP NULL
)
ENGINE=InnoDB
DEFAULT CHARSET=utf8
COLLATE=utf8_general_ci;

 

cj

CREATE TABLE javascript.cj (
	price varchar(100) NULL,
	`timestamp` TIMESTAMP DEFAULT CURRENT_TIMESTAMP NULL
)
ENGINE=InnoDB
DEFAULT CHARSET=utf8
COLLATE=utf8_general_ci;

 

chongkundang

CREATE TABLE javascript.chongkundang (
	price varchar(100) NULL,
	`timestamp` TIMESTAMP DEFAULT CURRENT_TIMESTAMP NULL
)
ENGINE=InnoDB
DEFAULT CHARSET=utf8
COLLATE=utf8_general_ci;

 

 

네이버 주식 real time 기본 폼

더보기

기말고사 제출본.7z
0.04MB

딥러닝 수업을 듣고 나머지 시간에는 전부 내일 시험을 보는 자바스크립트를 공부했다

내일은 시험 치고 또 다른 팀프로젝트 회의하고, CRUD 만들어서 도커에 올려 제출하는거 마무리 해야겠다.

'개발자 > TIL' 카테고리의 다른 글

TIL 20.07.06  (0) 2020.07.06
TIL 20.07.02  (0) 2020.07.04
TIL 20.06.30  (0) 2020.07.01
TIL 20.06.29  (0) 2020.06.29
TIL 20.06.26  (0) 2020.06.28

1. 서버에서 req 보내고, res 받아서 DB에 값 저장하기 (setInterval 사용) (라우터, 웹 X)

 

그대로 보내면

https://polling.finance.naver.com/api/realtime.nhn?query=SERVICE_ITEM:068270|SERVICE_RECENT_ITEM:068270&_callback=window.__jindo2_callback._9294

response가

window.__jindo2_callback._9294({"resultCode":"success","result":{"pollingInterval":8000,"areas":[{"datas":[{"nv":316500,"eps":2514,"bps":21666.12270,"cnsEps":3770,"ov":315500,"sv":319000,"cv":2500,"nav":null,"aq":415720,"aa":132587111500,"cd":"068270","cr":0.78,"hv":323000,"nm":"셀트리온","rf":"5","mt":"1","pcv":319000,"tyn":"N","ul":414500,"ll":223500,"keps":2236,"dv":null,"ms":"OPEN","lv":315500}],"name":"SERVICE_ITEM"},{"datas":[{"nv":316500,"eps":2514,"bps":21666.12270,"cnsEps":3770,"ov":315500,"sv":319000,"cv":2500,"nav":null,"aq":415720,"aa":132587111500,"cd":"068270","cr":0.78,"hv":323000,"nm":"셀트리온","rf":"5","mt":"1","pcv":319000,"tyn":"N","ul":414500,"ll":223500,"keps":2236,"dv":null,"ms":"OPEN","lv":315500}],"name":"SERVICE_RECENT_ITEM"}],"time":1593048845938}})

 

콜백 잘라서 보내면

https://polling.finance.naver.com/api/realtime.nhn?query=SERVICE_ITEM:068270|SERVICE_RECENT_ITEM:068270

response가

{"resultCode":"success","result":{"pollingInterval":8000,"areas":[{"datas":[{"cd":"068270","nv":316000,"eps":2514,"bps":21666.12270,"cnsEps":3770,"ov":315500,"sv":319000,"cv":3000,"nav":null,"aq":419598,"aa":133814248000,"hv":323000,"lv":315500,"cr":0.94,"ms":"OPEN","nm":"셀트리온","rf":"5","mt":"1","pcv":319000,"tyn":"N","ul":414500,"ll":223500,"keps":2236,"dv":null}],"name":"SERVICE_RECENT_ITEM"},{"datas":[{"cd":"068270","nv":316000,"eps":2514,"bps":21666.12270,"cnsEps":3770,"ov":315500,"sv":319000,"cv":3000,"nav":null,"aq":419598,"aa":133814248000,"hv":323000,"lv":315500,"cr":0.94,"ms":"OPEN","nm":"셀트리온","rf":"5","mt":"1","pcv":319000,"tyn":"N","ul":414500,"ll":223500,"keps":2236,"dv":null}],"name":"SERVICE_ITEM"}],"time":1593048946733}}

로 온다.

DB에 기본값으로 CURRENT_TIMESTAMP()를 넣고 테이블을 만들면 값을 저장할 때마다 DB가 알아서 DB 서버의 시간을 저장한다.

이것을 이용해 DB에 매 초마다 주식 정보를 가져와 저장하도록 해보자.

app.js

var express = require('express');
var app = express();
var http = require('http');
var server = http.createServer(app).listen(80);
console.log("server is running...")


var mysql = require('mysql');
var request = require('request');

var connection = mysql.createConnection({
  host: 'localhost',
  port: 3308,
  user:'root',
  password: '1234',
  database: 'javascript'  // test라는 데이터베이스에 접속
});
var bodyParser = require("body-parser");
app.use(bodyParser.urlencoded({limit: '50mb', extended: false}));
app.use(bodyParser.json({limit: '50mb'}));

// 1. 라우터 없이 서버에서 긁어서 바로 DB에 저장하는 방법.
const options = {
  url:'https://polling.finance.naver.com/api/realtime.nhn?query=SERVICE_ITEM:068270|SERVICE_RECENT_ITEM:068270',
  method: 'GET'
}

setInterval(function () {
  request.get(options, function(err,httpResponse,body){
    // console.log(JSON.parse(httpResponse.body));
    response = JSON.parse(httpResponse.body);
    console.log("방법1: " + response["result"]["areas"][0]["datas"][0]["nv"]);
    console.log("방법2: " + response.result.areas[0].datas[0].nv);
    var price = response.result.areas[0].datas[0].nv;
    var unixTimeStamp = response.result.time;

    function timeConverter(UNIX_timestamp){
      var a = new Date(UNIX_timestamp); // 보통 1000을 곱하라고 되어 있는데 이는 13자리를 맞춰주기 위해 곱하거나 떨구는거. 네이버는 기본으로 13자리를 주어 따로 처리 할 필요가 없다.
      var months = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'];
      var year = a.getFullYear();
      var month = months[a.getMonth()];
      var date = a.getDate();
      var hour = a.getHours();
      var min = a.getMinutes();
      var sec = a.getSeconds();
      var time = date + ' ' + month + ' ' + year + ' ' + hour + ':' + min + ':' + sec ;
      return time;
    }
    var time = timeConverter(unixTimeStamp)
    console.log(time);  // timeConverter 함수 인풋 파라미터로 유닉스타임스탬프를 넣는다.

    // INSERT 쿼리 보내기
    connection.query(`INSERT INTO celltrion (price, navertime) VALUES('${price}','${time}');`)
  });
},1000);

});

timestamp 컬럼은 DB 테이블에 default value로 CURRENT_TIMESTAMP를 넣어서 DB 서버가 직접 기록한 시간

navertime 컬럼네이버에서 받아온 response에 있는 unix timestamp를 직접 바꿔서 쿼리로 string 타입으로 쏴서 넣어준 시간

 

2. 라우터 사용

네이버 주식 정보 가져와 매 초마다
(1) DB에 저장하고,
(2) mail.html에 response 보내기 (main.html에서는 DB에서 읽어와 그래프를 그리지 않고 실시간 response를 배열에 누적해서 그래프를 그린다.)

app.js

var express = require('express');
var app = express();
var http = require('http');
var server = http.createServer(app).listen(80);
console.log("server is running...")


var mysql = require('mysql');
var request = require('request');

var connection = mysql.createConnection({
  host: 'localhost',
  port: 3308,
  user:'root',
  password: '1234',
  database: 'javascript'  // test라는 데이터베이스에 접속
});
var bodyParser = require("body-parser");
app.use(bodyParser.urlencoded({limit: '50mb', extended: false}));
app.use(bodyParser.json({limit: '50mb'}));


// 2. 라우터 사용 : 네이버 주식 정보 가져와 매 초마다 (1) DB에 저장하고, (2) main.html에 response 보내기 (main.html에서는 DB에서 읽어와 그래프를 그리지 않고 실시간 response를 배열에 누적해서 그래프를 그린다.)
app.get('/', function (req, res) {
  res.sendfile("main.html");
});
app.get('/main', function (req, res) {
  res.sendfile("main.html");
});
app.get('/getNaver', function (req, res) {
  // var price = getPrice();
  // res.send(price);

  const options = {
    url:'https://polling.finance.naver.com/api/realtime.nhn?query=SERVICE_ITEM:035720|SERVICE_RECENT_ITEM:035720',
    method: 'GET'
  }

  request.get(options, function(err,httpResponse,body){
    // console.log(JSON.parse(httpResponse.body));
    response = JSON.parse(httpResponse.body);
    console.log("방법1: " + response["result"]["areas"][0]["datas"][0]["nv"]);
    console.log("방법2: " + response.result.areas[0].datas[0].nv);
    var price = response.result.areas[0].datas[0].nv;
    var unixTimeStamp = response.result.time;

    function timeConverter(UNIX_timestamp){
      var a = new Date(UNIX_timestamp); // 보통 1000을 곱하라고 되어 있는데 이는 13자리를 맞춰주기 위해 곱하거나 떨구는거. 네이버는 기본으로 13자리를 주어 따로 처리 할 필요가 없다.
      var months = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'];
      var year = a.getFullYear();
      var month = months[a.getMonth()];
      var date = a.getDate();
      var hour = a.getHours();
      var min = a.getMinutes();
      var sec = a.getSeconds();
      var time = date + ' ' + month + ' ' + year + ' ' + hour + ':' + min + ':' + sec ;
      return time;
    }
    var time = timeConverter(unixTimeStamp)
    console.log(time);  // timeConverter 함수 인풋 파라미터로 유닉스타임스탬프를 넣는다.

    // 쿼리 보내기
    connection.query(`INSERT INTO kakao (price, navertime) VALUES('${price}','${time}');`)

    res.send(""+price);   // 숫자만 response로 보낼 경우 23530이라는 값을 response 보내면 HTTP Response 코드로 인식해 응답코드 23530 이라고 낭게 된다. 따라서 문자로 바꿔준다. (2개 이상을 response로 보내 배열로 만들어 보내는 경우는 무관하다.)
  });
});

// const options = {
//   url:'https://polling.finance.naver.com/api/realtime.nhn?query=SERVICE_ITEM:068270|SERVICE_RECENT_ITEM:068270',
//   method: 'GET'
// }

// 함수를 따로 뺐는데 위에 함수 호출한 곳에 return이 되지 않는다. promise 개념이 들어가야한다 함.
// function getPrice() {
//     request.get(options, function(err,httpResponse,body){
//       // console.log(JSON.parse(httpResponse.body));
//       response = JSON.parse(httpResponse.body);
//       console.log("방법1: " + response["result"]["areas"][0]["datas"][0]["nv"]);
//       console.log("방법2: " + response.result.areas[0].datas[0].nv);
//       var price = response.result.areas[0].datas[0].nv;
//       var unixTimeStamp = response.result.time;
//
//       function timeConverter(UNIX_timestamp){
//         var a = new Date(UNIX_timestamp); // 보통 1000을 곱하라고 되어 있는데 이는 13자리를 맞춰주기 위해 곱하거나 떨구는거. 네이버는 기본으로 13자리를 주어 따로 처리 할 필요가 없다.
//         var months = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'];
//         var year = a.getFullYear();
//         var month = months[a.getMonth()];
//         var date = a.getDate();
//         var hour = a.getHours();
//         var min = a.getMinutes();
//         var sec = a.getSeconds();
//         var time = date + ' ' + month + ' ' + year + ' ' + hour + ':' + min + ':' + sec ;
//         return time;
//       }
//       var time = timeConverter(unixTimeStamp)
//       console.log(time);  // timeConverter 함수 인풋 파라미터로 유닉스타임스탬프를 넣는다.
//
//       // 쿼리 보내기
//       connection.query(`INSERT INTO celltrion (price, navertime) VALUES('${price}','${time}');`)
//       console.log("나나난나"+price);
//       return price;
//     });
// };

// {"resultCode":"success",
// "result":{"pollingInterval":8000,
//           "areas":[
//                   {"datas":[{"ll":223500,"ms":"OPEN","nv":316000,"cd":"068270","eps":2514,"bps":21666.1227,"cnsEps":3770,"ov":315500,"sv":319000,"cv":3000,"nav":null,"aq":531756,"aa":169225844500,"dv":null,"keps":2236,"nm":"��Ʈ����","rf":"5","mt":"1","pcv":319000,"tyn":"N","ul":414500,"lv":314500,"hv":323000,"cr":0.94}],
//                     "name":"SERVICE_ITEM"},
//                   {"datas":[{"ll":223500,"ms":"OPEN","nv":316000,"cd":"068270","eps":2514,"bps":21666.1227,"cnsEps":3770,"ov":315500,"sv":319000,"cv":3000,"nav":null,"aq":531756,"aa":169225844500,"dv":null,"keps":2236,"nm":"��Ʈ����","rf":"5","mt":"1","pcv":319000,"tyn":"N","ul":414500,"lv":314500,"hv":323000,"cr":0.94}],
//                     "name":"SERVICE_RECENT_ITEM"}],
// "time":1593051026214}}

});

res.send(""+price); 에 주목하자

숫자만 response로 보낼 경우 23530이라는 값을 response 보내면 HTTP Response 코드로 인식해 응답코드 23530 이라고 낭게 된다. 따라서 문자로 바꿔준다. (2개 이상을 response로 보내 배열로 만들어 보내는 경우는 무관하다.)

 

main.html (http://localhost/)

<!DOCTYPE html>
<html lang="en" dir="ltr">
  <head>
    <meta charset="utf-8">
    <title></title>
  </head>
  <body>
    <span id="result"></span>
    <br><br>
    <script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
    <div id="chart_div"></div>
  </body>
  <script  src="http://code.jquery.com/jquery-latest.min.js"></script>
  <script>
    var time=0;
    var graphValue = [];
    var stockPrice;

    setInterval(function () {
        $.ajax({
          url : '/getNaver',
          type : 'GET',
          data : {

          },
          success : function(res) {
            stockPrice = res; // 크롬에서 콘솔에서 stockPrice를 찍어보면 보기 좋게 나온다.
            // console.log(res);
            graphValue.push([time,Number(stockPrice)])
            time++;
            drawCurveTypes(graphValue);   // 구글 차트를 그려주는 함수를 호출한다.
          }
        });
    },1000);


    google.charts.load('current', {packages: ['corechart', 'line']});
    google.charts.setOnLoadCallback(drawCurveTypes);

    function drawCurveTypes() {
      var data = new google.visualization.DataTable();
      data.addColumn('number', '시간(초)');
      data.addColumn('number', '카카오');

      data.addRows(graphValue);

      var options = {
        hAxis: {
          title: '시간(초)'
        },
        vAxis: {
          title: '가격(원)'
        },
        series: {
          1: {curveType: 'function'}
        }
      };

      var chart = new google.visualization.LineChart(document.getElementById('chart_div'));
      chart.draw(data, options);
    }

  </script>
</html>

 

DB

더보기

Database : MySQL / Database Name : javascript / Table Name : celltrion

timestamp의 'Data Type'를 더블클릭하고 들어가서 default value 설정하기

 

 

Database : MySQL / Database Name : javascript / Table Name : kakao 

  

 

2개 동시에 그리기

app2.js  (navertime은 코드가 길어져서 뺐음)

var express = require('express');
var app = express();
var http = require('http');
var server = http.createServer(app).listen(80);
console.log("Server is running...")


var mysql = require('mysql');
var request = require('request');

var connection = mysql.createConnection({
  host: 'localhost',
  port: 3308,
  user:'root',
  password: '1234',
  database: 'javascript'  // test라는 데이터베이스에 접속
});

var bodyParser = require("body-parser");
app.use(bodyParser.urlencoded({limit: '50mb', extended: false}));
app.use(bodyParser.json({limit: '50mb'}));

app.get('/', function (req, res) {
  res.sendfile("newMain.html");
});
app.get('/main', function (req, res) {
  res.sendfile("newMain.html");
});
app.get('/getNaver', function (req, res) {
  const kakao = {
    url:'https://polling.finance.naver.com/api/realtime.nhn?query=SERVICE_ITEM:035720|SERVICE_RECENT_ITEM:035720',
    method: 'GET'
  }

  const naver = {
    url:'https://polling.finance.naver.com/api/realtime.nhn?query=SERVICE_ITEM:035420|SERVICE_RECENT_ITEM:035420',
    method: 'GET'
  }

  request.get(kakao, function(err,httpResponse,body){
    response = JSON.parse(httpResponse.body);
    var kakaoPrice = response.result.areas[0].datas[0].nv;
    // connection.query(`INSERT INTO kakao (price, navertime) VALUES('${kakaoPrice}','time');`)
    connection.query(`INSERT INTO kakao (price) VALUES('${kakaoPrice}');`)

    request.get(naver, function(err,httpResponse,body){
      response = JSON.parse(httpResponse.body);
      var naverPrice = response.result.areas[0].datas[0].nv;
      // connection.query(`INSERT INTO naver (price, navertime) VALUES('${naverPrice}','time');`)
      connection.query(`INSERT INTO naver (price) VALUES('${naverPrice}');`)
      console.log([kakaoPrice,naverPrice]);
      res.send([kakaoPrice,naverPrice]);  // 배열로 보내기 때문에 문자로 바꿔서 보낼 필요가 없다.
    });

  });
});

 

newMain.html

<!DOCTYPE html>
<html lang="en" dir="ltr">
  <head>
    <meta charset="utf-8">
    <title></title>
  </head>
  <body>
    <span id="result"></span>
    <br><br>
    <script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
    <div id="chart_div"></div>
  </body>
  <script  src="http://code.jquery.com/jquery-latest.min.js"></script>
  <script>
    var time=0;
    var graphValue = [];
    var kakaoPrice;
    var naverPrice;

    setInterval(function () {
        $.ajax({
          url : '/getNaver',
          type : 'GET',
          data : {

          },
          success : function(res) {
            kakaoPrice = res[0];
            naverPrice = res[1];
            // graphValue.push([time,Number(kakaoPrice),Number(naverPrice)])
            graphValue.push([time,kakaoPrice,naverPrice]) // 배열로 넘어와 문자로 변경하지 않았기 때문에 다시 숫자로 형변환 할 필요가 없다.
            time++;
            drawCurveTypes(graphValue);   // 구글 차트를 그려주는 함수를 호출한다.
          }
        });
    },1000);


    google.charts.load('current', {packages: ['corechart', 'line']});
    google.charts.setOnLoadCallback(drawCurveTypes);

    function drawCurveTypes() {
      var data = new google.visualization.DataTable();
      data.addColumn('number', '시간(초)');
      data.addColumn('number', '카카오');
      data.addColumn('number', 'Naver');

      data.addRows(graphValue);

      var options = {
        hAxis: {
          title: '시간(초)'
        },
        vAxis: {
          title: '가격(원)'
        },
        series: {
          1: {curveType: 'function'}
        }
      };

      var chart = new google.visualization.LineChart(document.getElementById('chart_div'));
      chart.draw(data, options);
    }

  </script>
</html>

 

 

 

DB

 

 

 

 

3. 버튼을 누르면 내부망 서버에 접속해 받아온 response로 각각의 그래프를 갱신하라.

app.js

var express = require('express');
var app = express();
var http = require('http');
var server = http.createServer(app).listen(80);
console.log("server is running...")


var mysql = require('mysql');
var request = require('request');

var connection = mysql.createConnection({
  host: 'localhost',
  port: 3308,
  user:'root',
  password: '1234',
  database: 'javascript'  // test라는 데이터베이스에 접속
});
var bodyParser = require("body-parser");
app.use(bodyParser.urlencoded({limit: '50mb', extended: false}));
app.use(bodyParser.json({limit: '50mb'}));

// 3. 버튼을 누르면 내부망 서버에 접속해 받아온 response로 각각의 그래프를 갱신하라.
app.get('/main2', function (req, res) {
  res.sendfile("main2.html");
});

app.get('/findprice', function (req, res) {
  var priceUrl = req.query.priceUrl;

  const options = {
    url: `${priceUrl}`,
    method: 'GET'
  }

  request.get(options, function(err,httpResponse,body){
    console.log(JSON.parse(httpResponse.body));
    response = JSON.parse(httpResponse.body);

    res.send(response);
  });
});

 

main2.html

<!DOCTYPE html>
<html lang="en" dir="ltr">
  <head>
    <meta charset="utf-8">
    <title></title>
  </head>
  <body>
    <select name="cars" id="cars">
      <option value="http://192.168.110.26/price1">price1</option>
      <option value="http://192.168.110.26/price2">price2</option>
      <option value="http://192.168.110.26/price3">price3</option>
    </select>
    <input type="button" value="시작" onclick="sendRequest()">
    <br><br>
    <script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
    <div id="chart_div"></div>

  </body>
  <script  src="http://code.jquery.com/jquery-latest.min.js"></script>
  <script>
  var graphValue = [];

  function sendRequest() {
    // $("#cars > option:nth-child(1).val()")
    // console.log(`${$("#cars option:selected").val()}`);

    $.ajax({
      url : '/findprice',
      type : 'GET',
      data : {
        priceUrl: `${$("#cars option:selected").val()}`
      },
      success : function(res) {
        // 배열 초기화
        graphValue = [];
        // 배열에 값 담기
        for(var i=0; i<res.length; i++) {
          graphValue.push([Number(res[i].no),Number(res[i].price)]);
          google.charts.load('current', {packages: ['corechart', 'line']});
          google.charts.setOnLoadCallback(drawCurveTypes);

          function drawCurveTypes() {
            var data = new google.visualization.DataTable();
            data.addColumn('number', '시간(초)');
            data.addColumn('number', '가격');

            data.addRows(graphValue);

            var options = {
              hAxis: {
                title: '시간(초)'
              },
              vAxis: {
                title: '가격(원)'
              },
              series: {
                1: {curveType: 'function'}
              }
            };

            var chart = new google.visualization.LineChart(document.getElementById('chart_div'));
            chart.draw(data, options);
          }
        }
      }
    });
  };

  </script>
</html>

 

price 3에 접속할 때 받아오는 값

[{"no":1,"price":10},{"no":2,"price":9},{"no":3,"price":8},{"no":4,"price":6},{"no":5,"price":8},{"no":6,"price":8},{"no":7,"price":9},{"no":8,"price":7},{"no":9,"price":2},{"no":10,"price":8}]

 

'시작'버튼을 누르면 아래와 같은 그래프를 그린다.

ajax에서 success에 graphValue=[]; 로 초기화 해주는 과정이 없다면 price 1~3을 계속 req, res 할 때마다 그래프가 누적되기 때문에 반드시 초기화를 해줘야한다.

<!DOCTYPE html>
<html lang="en" dir="ltr">
  <head>
    <meta charset="utf-8">
    <title></title>
    <style type="text/css">
    table {
      width:80%; margin: auto;
    }
    </style>
  </head>
  <body>
    <h1><center> 이력서 </h1>
    <table border="0">
      <tr>
        <td style="text-align: left; font-weight: bold;">1. 인적사항</td>
      </tr>
    </table>
    <table border="1">
      <tr>
        <td rowspan="2" style="background-color: #CCCCCC; font-weight: bold; text-align: center; width: 15%;"><img src="https://encrypted-tbn0.gstatic.com/images?q=tbn%3AANd9GcQwIq3eqwx-6i-Q6dfy-KNXQZD7PRsY9qU2eqOwsFqR0VFFk3Wn&usqp=CAU" width="150" height="170"></td>
        <td style="background-color: #78DFFF; font-weight: bold; text-align: center; width: 13%">한글이름</td>
        <td></td>
        <td style="background-color: #78DFFF; font-weight: bold; text-align: center; width: 13%">주민등록번호</td>
        <td></td>
      </tr>
      <tr>
        <td style="background-color: #78DFFF; font-weight: bold; text-align: center;">영문이름</td>
        <td></td>
        <td style="background-color: #78DFFF; font-weight: bold; text-align: center;">생년월일</td>
        <td></td>
      </tr>
      <tr height=100>
        <td style="background-color: #78DFFF; font-weight: bold; text-align: center;">주소</td>
        <td colspan="4"></td>
      </tr>
    </table>
    <br /><br />
    <table border="0">
      <tr>
        <td style="text-align: left; font-weight: bold;">2. 학력사항</td>
      </tr>
    </table>
    <table border="1" width=1200 height=300>
    <thead>
      <tr>
        <th style="background-color: #FFC3FA; width: 25%">학교명</th>
        <th style="background-color: #FFC3FA; width: 35%">전공</th>
        <th style="background-color: #FFC3FA; width: 20%">입학일자</th>
        <th style="background-color: #FFC3FA; width: 20%">졸업일자</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
      </tr>
      <tr>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
      </tr>
      <tr>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
      </tr>
    </tbody>
    </table>
    <br /><br />
    <table border="0">
      <tr>
        <td style="text-align: left; font-weight: bold;">3. 자격사항</td>
      </tr>
    </table>
    <table border="1" width=1200 height=300>
    <thead>
      <tr>
        <th style="background-color: #F4A460; width: 25%">자격증명</th>
        <th style="background-color: #F4A460; width: 10%">등급</th>
        <th style="background-color: #F4A460; width: 25%">취득일</th>
        <th style="background-color: #F4A460; width: 40%">발급기관</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
      </tr>
      <tr>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
      </tr>
      <tr>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
      </tr>
    </tbody>
    </table>
  </body>
</html>

 

'개발자 > HTML' 카테고리의 다른 글

HTML 화면 좌우 분할  (0) 2020.11.17
HTML input 태그 button으로 페이지 이동하기  (0) 2020.11.12
HTML 테이블 생성기  (0) 2020.06.18
자바 HTML  (0) 2020.05.29
HTML 테이블 구조 (Python 웹크롤링)  (0) 2020.05.04

1. app.js

var express = require('express');
var app = express();
var http = require('http');
var server = http.createServer(app).listen(80);
console.log("Server is running...")

// 1. 서버 접속시 쿼리 실행해서 DB에서 데이터 읽어오기.
var mysql = require('mysql');
// npm install mysql

var connection = mysql.createConnection({
  host: 'localhost',
  port: 3308,
  user:'root',
  password: '1234',
  database: 'javascript'  // test라는 데이터베이스에 접속
});

app.get('/', function (req, res) {
  res.sendfile("view.html");
});
app.get('/home', function (req, res) {
  res.sendfile("view.html");
});
app.get('/main', function (req, res) {
  res.sendfile("view.html");
});
app.get('/inputValue', function (req, res) {
  res.sendfile("input.html");
});

var bodyParser = require("body-parser");
app.use(bodyParser.urlencoded({limit: '50mb', extended: false}));
app.use(bodyParser.json({limit: '50mb'}));



app.get('/view', function (req, res) {
  // connection.query(`select * from inputvalue`,
  connection.query(`SELECT * FROM inputvalue ORDER BY idx DESC LIMIT 1`,
    function (err, rows, fields) {
      if (err) throw err;
      res.send(rows);
    }
  );
});

app.post('/input', function (req, res) {
  var myVal = req.body.myVal;
  connection.query(`insert into inputvalue (myvalue) values('${myVal}')`,
    function (err, rows, fields) {
      if (err) throw err;
      res.send();
    }
  );
});

 

 

2. view.html (http://localhost/)

<!DOCTYPE html>
<html lang="en" dir="ltr">
  <head>
    <meta charset="utf-8">
    <title></title>
  </head>
  <body>
    <input type="button" value="입력 페이지로" onclick="goToInput()"></button>
    <br><br>
    값 : <span id="result"></span>
  </body>
  <script  src="http://code.jquery.com/jquery-latest.min.js"></script>
  <script>
  var time = 1;  // second로 입력

  setInterval(function () {
    $.ajax({
      url : 'http://localhost/view',
      type : 'GET',
      data : {
      },
      success:function(res){   // 받아온 response는 [{Key:Value},{Key:Value},{Key:Value}]로 리스트 안에 딕셔너리 형태로 받아온다.
        // var table = res[res.length-1];
        var table = res[0];
        $('#result').html(`${table.myvalue} <br>`)
      }
    });
  }, time * 1000);

  function goToInput() {
    location.href = "/inputValue";
  }

  </script>
</html>

setInterval에 의해 주기적(1000ms->1초)으로 localhost/view(DB에 select 쿼리를 날리는 라우터)에 request를 보내고, 값을 받아와 뿌려준다.

 

 

3. input.html (http://localhost/inputValue)

<!DOCTYPE html>
<html lang="en" dir="ltr">
  <head>
    <meta charset="utf-8">
    <title></title>
  </head>
  <body>
    <input type="text" placeholder="서버에 입력하고 싶은것은?" id="value" style="width:200px"><br><br>
    <input type="button" value="입력!!" id="putBnt"></button>
    <input type="button" value="홈으로" onclick="goToHome()"></button>
    <br /><br />
    <span id="result"></span>
  </body>
  <script  src="http://code.jquery.com/jquery-latest.min.js"></script>
  <script>

  $('#putBnt').click(function() {
    var myVal = $('#value').val();
    $.ajax({
      url : 'http://localhost/input',
      type : 'POST',
      data : {
        myVal : myVal
      },
      success:function(res) {
        alert("Success!");
      }
    });
  });

  function goToHome() {
    location.href = "/";
  }

  </script>
</html>

메인 페이지 (setInterval에 의해 1초마다 DB에 접속해 뿌려준다)

4. time.html

라우터 안 만들었다... 만들어서 실행해도 되고 파일로 실행해도 되고...

배수증가 버튼 : 클릭 3초 후 아래로 입력한 숫자의 배수씩 증가하며 출력  -> setTimeout + setInterval
타이머 버튼 : 클릭 3초 후 버튼 옆에 1초씩 1씩 증가하는 숫자 출력 -> setTimeout + setInterval
타이머 종료 : 클릭 3초 후 타이머 종료  -> clearInterval

<!DOCTYPE html>
<html lang="en" dir="ltr">
  <head>
    <meta charset="utf-8">
    <title></title>
  </head>
  <body>
    <!-- 배수증가 버튼 : 클릭 3초 후 아래로 입력한 숫자의 배수씩 증가하며 출력
         타이머 버튼 : 클릭 3초 후 버튼 옆에 1초씩 1씩 증가하는 숫자 출력
         타이머 종료 : 클릭 3초 후 타이머 종료 -->

    <input type="text" id="inputNumber">
    <input type="button" value="배수증가" id="tMultiple">
    <input type="button" value="타이머 시작" id="tStart">
    <input type="button" value="타이머 종료" id="tStop">
    타이머 : <span id="timer"></span>
    <br>
    출력 : <span id="result"></span>

  </body>
  <script  src="http://code.jquery.com/jquery-latest.min.js"></script>
  <script>
  console.log("start");
  var btnCount1 = 0;
  $("#tMultiple").click(function() {
    if (btnCount1 > 0) {
      alert("버튼은 1번만 눌러주세요.\n여러번 누르면 setInterval이 여러번 돌아가서 버튼 클릭을 막습니다.");
      return;
    }
    btnCount1++;
    setTimeout(function () {
      var count = 1;
      var multiplier = $("#inputNumber").val();
      setInterval(function () {
        $("#result").append("<br>" + count * multiplier);
        count += 1;
      }, 1000);
    }, 3000);
  });

  var myTimer;
  var btnCount2 = 0;
  $("#tStart").click(function() {
    if (btnCount2 > 0) {
      alert("버튼은 1번만 눌러주세요.\n여러번 누르면 setInterval이 여러번 돌아가서 버튼 클릭을 막습니다.");
      return;
    }
    btnCount2++;
    setTimeout(function () {
      var count = 0;
      myTimer = setInterval(function () {
        $("#timer").html(count);
        count += 1;
      }, 1000);
    }, 3000);
  });

  $("#tStop").click(function() {
    setTimeout(function () {
      clearInterval(myTimer);
    }, 3000);
  });

  </script>
</html>

 

 

 

DB

더보기

Database : MySQL / Database Name : javascript / Table Name : inputValue

CREATE TABLE javascript.inputvalue (
	idx INT auto_increment NOT NULL,
	myvalue varchar(100) NULL,
	CONSTRAINT inputvalue_PK PRIMARY KEY (idx)
)
ENGINE=InnoDB
DEFAULT CHARSET=utf8
COLLATE=utf8_general_ci;

 

 

+ Recent posts