@value, @reg 같은 사용자 변수가 들어간 쿼리에서 오류가 발생한다.
해결
Connection을 맺을 때 Allow User Variables=True 옵션을 추가해줘야한다.
string conf = "Server=$Server;Port=$port;Database=$DataBase;Uid=$User;Pwd=$Password;Allow User Variables=True";
@value, @reg 같은 사용자 변수가 들어간 쿼리에서 오류가 발생한다.
Connection을 맺을 때 Allow User Variables=True 옵션을 추가해줘야한다.
string conf = "Server=$Server;Port=$port;Database=$DataBase;Uid=$User;Pwd=$Password;Allow User Variables=True";
javascript 의 split 을 생각하고 split 을 사용했다간 예상치 못한 오류를 맞게된다.
일반 Split 함수는 Char 로만(한 글자로만) 자를 수 있다.
string str = "cat__dog__animal__person";
string[] animals = Regex.Split(str, "__");
Regex.Split 을 사용하면 된다.
using MySql.Data.MySqlClient;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Web;
namespace WebApplication.ClassFolder{
public class DBConfig{
private static string Server = "";
private static string Database = "";
private static string ID = "";
private static string PASS = "";
static string conf = "Server=" + Server + ";Database=" + Database + ";Uid=" + ID + ";Pwd=" + PASS;
static MySqlConnection db;
public static MySqlConnection Connection{
get{
if (db == null){
LazyInitializer.EnsureInitialized(ref db, CreateConnection);
}
return db;
}
}
static MySqlConnection CreateConnection(){
var db = new MySqlConnection(conf);
db.Open();
return db;
}
// 강제로 커넥션을 끊어야될 경우가 있을 때
static void CloseConnection(){
if(db != null) {
db.Close();
db.Dispose();
db = null;
}
}
}
}
// get Connection
var db = DBConfig.Connection;
targetFramework가 인식할 수 없다고 페이지가 안 띄워지는 경우가 있다.
IIS의 .NET버전과 프로젝트의 .NET버전이 달라 발생한다.
IIS > 응용프로그램 풀 > 내 프로젝트 클릭 > 기본설정 메뉴에서 .NET Framework 버전 속성을 변경해준다.
d3 와 d3-cloud 를 사용해 R 의 Word Cloud 를 javascript 로 구현해보자.
# npm
$ npm install d3
$ npm install d3.layout.cloud
# bower
$ bower install d3
$ bower install d3-cloud
<script src="/bower_components/d3/d3.min.js"></script>
<script src="/bower_components/d3-cloud/build/d3.layout.cloud.js"></script>
<script>
var fill = function (i) {
return d3.schemeCategory20b[i];
};
var layout = d3.layout
.cloud()
.size([500, 500])
.words(
[
"텍스트",
"마이닝",
"샘플",
"좋아요",
"R",
"Word",
"Cloud",
"text",
"mining",
].map(function (d) {
return { text: d, size: 10 + Math.random() * 90, test: "haha" };
})
)
.padding(5)
.rotate(function () {
return ~~(Math.random() * 2) * 90;
})
.font("Impact")
.fontSize(function (d) {
return d.size;
})
.on("end", draw);
layout.start();
function draw(words) {
d3.select("body")
.append("svg")
.attr("width", layout.size()[0])
.attr("height", layout.size()[1])
.append("g")
.attr(
"transform",
"translate(" + layout.size()[0] / 2 + "," + layout.size()[1] / 2 + ")"
)
.selectAll("text")
.data(words)
.enter()
.append("text")
.style("font-size", function (d) {
return d.size + "px";
})
.style("font-family", "Impact")
.style("fill", function (d, i) {
return fill(i);
})
.attr("text-anchor", "middle")
.attr("transform", function (d) {
return "translate(" + [d.x, d.y] + ")rotate(" + d.rotate + ")";
})
.text(function (d) {
return d.text;
});
}
</script>
d3-cloud의 예제소스는 nodejs 환경에서만 돌릴 수 있어 모든 웹에서 예제를 사용할 수 있게 수정했다.
window.fbAsyncInit = function () {
FB.init({
appId: "앱 키",
xfbml: true,
version: "v2.8",
});
};
(function (d, s, id) {
var js,
fjs = d.getElementsByTagName(s)[0];
if (d.getElementById(id)) {
return;
}
js = d.createElement(s);
js.id = id;
js.src = "//connect.facebook.net/en_US/sdk.js";
fjs.parentNode.insertBefore(js, fjs);
})(document, "script", "facebook-jssdk");
앱공개를 한 뒤 페이스북 개발자 > 앱 검수 에서 publish_pages, manage_pages 권한을 부여해야한다.
FB.login(
function (login_result) {
if (login_result.status === "connected") {
// 여기에 3번 로직을 넣으면 된다.
} else if (login_result.status === "not_authorized") {
alert("페이스북 인증에 실패했습니다");
} else {
alert("페이스북 API 호출에 실패했습니다");
}
},
{ scope: "publish_pages,manage_pages" }
);
// 이 두 권한이 꼭 필요하다
페이지 아이디가 필요한데, 내 페이지로 이동하면 뒤에보이는 주소 번호가 있다. 또는 페이지 아이디를 여기서 주소로 검색해보자
FB.api(
"/나의 페이지 아이디/",
"GET",
{ fields: "access_token" },
function (token_result) {
// token_result.access_token 이 페이지 관리자로 글을 쓰기 위해 필요하다
// 여기에 4번 로직을 넣으면 된다.
}
);
Graph API 를 사용해 피드를 작성한다. 자세한 옵션 설정은 API 문서를 참조하자.
FB.api(
"/my page id/feed",
"POST",
{
access_token: token_result.access_token,
message: "내용",
link: "링크 걸 주소",
picture: "링크 이미지",
name: "링크 제목",
description: "링크 설명",
caption: "링크 하단 캡션",
},
function (page_result) {
if (page_result && !page_result.error) {
// 여기에 성공시 로직을 넣는다.
}
}
);
FB.login(
function (login_result) {
if (login_result.status === "connected") {
getFbAccessToken();
} else if (login_result.status === "not_authorized") {
alert("페이스북 인증에 실패했습니다");
} else {
alert("페이스북 API 호출에 실패했습니다");
}
},
{ scope: "publish_pages,manage_pages" }
);
function getFbAccessToken() {
FB.api(
"/나의 페이지 아이디/",
"GET",
{ fields: "access_token" },
function (token_result) {
postFbPage(token_result);
}
);
}
function postFbPage(token_result) {
FB.api(
"/나의 페이지 아이디/feed",
"POST",
{
access_token: token_result.access_token,
message: "내용",
link: "링크 걸 주소",
picture: "링크 이미지",
name: "링크 제목",
description: "링크 설명",
caption: "링크 하단 캡션",
},
function (page_result) {
if (page_result && !page_result.error) {
alert("성공");
}
}
);
}
OAuth 및 RESTful 의 개념이 잡혔다면 쉽게 접근할 수 있을듯 Graph API 로 모든 페이스북 API 이용이 가능한 것 같다.
공식 문서에 따르면 jsFiddle tag의 사용법은 이렇다.
{% jsfiddle shorttag [tabs] [skin] [width] [height] %}
대괄호로 둘러 쌓인 부분은 생략이 가능하다.
shorttag는 URL 창에서 바로 보여질 수도 있지만 그렇지 않을경우
Save 또는 Update 버튼을 누르면 나오는 Embed 메뉴에서 확인할 수 있다.
https인 github.io에서 http로 jsfiddle을 호출해서 차단된다.
node_module\hexo\lib\plugins\tag\jsfiddle.js 파일의 jsfiddle 치환 함수를 변경한다.
function jsfiddleTag(args, content) {
var id = args[0];
var tabs =
args[1] && args[1] !== "default" ? args[1] : "js,resources,html,css,result";
var skin = args[2] && args[2] !== "default" ? args[2] : "light";
var width = args[3] && args[3] !== "default" ? args[3] : "100%";
var height = args[4] && args[4] !== "default" ? args[4] : "300";
// http://jsfiddle.net > //jsfiddle.net
return (
'<iframe scrolling="no" width="' +
width +
'" height="' +
height +
'" src="//jsfiddle.net/' +
id +
"/embedded/" +
tabs +
"/" +
skin +
'" frameborder="0" allowfullscreen></iframe>'
);
}
D3.js 로 그래프를 만들 수 있지만 더 사용성이 좋은 highchart 로 데이터를 시각화해보자
# npm
$ npm install highcharts --save
# yarn
$ yarn add highcharts
highcharts.min.js와 modules/exporting.js, themes/grid-light.js 를 가져온다. 아니면 CDN을 사용해도 된다.
<script src="/bower_components/highcharts/highcharts.js"></script>
<script src="/bower_components/highcharts/modules/exporting.js"></script>
<script src="/bower_components/highcharts/themes/grid-light.js"></script>
홈페이지에 나와있는 예제는 다음과 같다.
기본 예제로도 차트를 만들 수 있지만 업무에 사용하려면 비동기로 데이터가 갱신될 때마다 차트도 다시 그려져야한다. 세부 옵션은 API 문서를 참조하자.
div#chart에 차트를 그린다고 가정한다.
Highcharts.setOptions({
lang: {
// 전체보기 버튼을 한글로 바꾼다
resetZoom: "전체보기",
},
});
var chartCallback = function (data) {
var chart = $("#chart").highcharts();
if (chart) {
// 차트가 있을경우 제거한다.
chart.destroy();
}
if (data) {
var categoriesData = []; // 여기에 x축 데이터를 넣는다.
var seriesData = {}; // 여기에 data를 파싱해 y축 구조를 만들어준다.
var options = {
chart: {
renderTo: "chart", // 다시 그려질 영역 설정
zoomType: "x", // X축이 줌인이 가능하게 설정
panning: true,
panKey: "shift",
},
title: {
text: null,
},
xAxis: {
categories: categoriesData,
},
yAxis: {
min: 0, // 0이상의 값만 표기
allowDecimals: false, // 정수로만 표기
title: {
text: null,
},
labels: {},
},
credits: {
text: "Graceful Light", // 로고 표시
href: "https://gracefullight.github.io", // 로고 클릭시 URL
},
tooltip: {
// hover시 나오는 tooltip
shared: true, // 하나의 영역을 공유
pointFormatter: function () {
if (this.y >= 0) {
// 표시되는 tooltip을 마음대로 설정
return (
'<span style="color:' +
this.series.color +
';">●</span> ' +
this.series.name +
": " +
"<b>" +
Utils.comma(this.y) +
"</b><br/>"
);
}
},
},
plotOptions: {
column: {
pointPadding: 0.2,
borderWidth: 0,
},
},
legend: {
borderWidth: 0,
},
series: seriesData,
};
chart = new Highcharts.Chart(options);
chart.redraw();
} else {
$("#chart").html("no data");
}
};
redraw 를 이용할 때 new Highcharts.Chart
를 사용해야한다.
categories 와 series 의 모양을 만들어줄 때는 lodash 를 사용해야 편하다.
Windows10 을 쓰다가 어느순간 보면 탐색기에서 Onedrive 메뉴가 생긴 것을 볼 수 있다.
심지어 Windows10 Anniversary Update 가 되어있다면 모르는 사이에 동기화가 연결되어 있을 수도 있다.
동기화는 리소스를 잡아먹고 개인컴퓨터가 아닌 곳에서는 접근하면 안되니 여간 거슬리는 게 아니다.
설정에 들어가도 해제옵션이 없고, MS 도움말에는 기본기능이라 해제가 불가능하다고 나온다.
없애보자.
오픈소스라 믿고 사용해도 된다.