• 유튜브와 같은 비디오를 반응형으로 넣을수 있음
  • 기본 선택자는 embed-responsive
  • 화면비율 선택자는 embed-responsive-16by9 or embed-responsive-4by3 을 사용한 내부에 iframe, object, embed, video 태그를 사용한 비디오를 추가하면 됩니다.
  • 유튜브에서 iframe 코드를 복사해 사용할 경우 그대로 붙여넣어도 되며 width, height, frameborder 등의 속성은 필요 없습니다.
  • 화면 너비만 변경하면 가로 세로 비율이 자동으로 바뀝니다.

비디오 사용법

<div class=”embed-responsive embed-responsive-16by9“>
  <video autoplay loop class=”embed-responsive-item“>
    <source src=http://techslides.com/demos/sample-videos/small.mp4 type=video/mp4>
  </video>
</div>

Google ppt 반응형으로 넣기

google ppt 주소 및 공유 링크로 추가하는 경우 text 일부가 깨지는 경우가 발생

web 게시(삽입) 형태로 진행

웹에 게시 선택

'삽입' 메뉴 선택 후, 원하는 옵션으로 조정하고 '게시' 버튼을 클릭

웹 게시 옵션 설정

웹 게시 문서 주소를 확인 ( 아래 형태로 공유됨 )

<iframe src="https://docs.google.com/presentation/XXXXXXXXXXXXX/embed?start=false&loop=false&delayms=3000" frameborder="0" width="1280" height="749" allowfullscreen="true" mozallowfullscreen="true" webkitallowfullscreen="true"></iframe>

웹 게시 문서 주소 확인

웹에 게시(삽입) 사용법

<div class="embed-responsive embed-responsive-16by9">  
  <iframe class="embed-responsive-item" src="https://docs.google.com/presentation/XXXXXXXX/embed?start=false&loop=false&delayms=3000" frameborder="0" allowfullscreen="true" mozallowfullscreen="true" webkitallowfullscreen="true"></iframe>
</div>

 

참고

https://zzznara2.tistory.com/586

배경

telegram으로 DB 성능 및 상태 모니터링을 하는 경우, php, python... 등으로 telegram 대화창에 메시지를 전송하는 경우 일반적으로 callbak_data에 정보를 추가하여 처리함.

callback_data로 처리를 하면 telegram 대화창에는 보이지 않지만, python에서 callbak_data를 받아서 처리 가능한 장점이 있어 많이 사용하는 것으로 보임.

이슈

callback_data에 너무 많은 정보를 전달하는 경우 일부 데이터만 전달됨

원인

callback_data에 최대로 전달할수 있는 정보는 64개의 문자로 제한됨.

 

참고 : https://github.com/nmlorg/metabot/issues/1

설명

textarea에 image 및 tag 적용이 되지 않음

적용이 불가능하지는 않은듯하나 예외 사항이 많아 적용이 쉽지 않음

div contentEditable="true" 형태를 사용하여 image 및 text를 함께 작성

div contentEditable 형태는 form 형태로 전달하기 힘들기 때문에 hidden text를 사용하여 db에 내용을 전달

Page를 불러 올때 hidden 형태의 타입의 값을 div contentEditable 부분에 가져와서 보여줌

 

html

DB 에서 데이터를 조회하여 templates에 result.content_detail 값을 전달하여 처리하는 형태

content_detail은 hidden형태로 값을 전달하는 중간 역할

content_detail_edit는 실제로 데이터(이미지 및 텍스트)를 화면에 출력하는 역할

 

content_detail_image는 file 타입으로 이미지의 정보를 처리

content_img_width는 이미지의 width정보를 전달하기 위한 용도

<div class="form-group col-md-10">
    <div class="input-group">
        <div class="input-group-prepend iw-100" data-toggle="tooltip" data-container="body" title="content 내용">
            <button type="button" class="btn btn-warning iw-100" onclick="expandText()">Content *</button>
        </div>
        <input type="hidden" name="content_detail" id="content_detail" value = "{{ result.content_detail }}"/>
        <div contentEditable="true" style="min-height: 100px;height: 100%;max-width: 100%;white-space: pre-wrap; word-break: break-word;"class="form-control" id="content_detail_edit" required> </div>
    </div>
</div>

<div class="form-group col-md-2">
    <div class="input-group">
        <div class="custom-file">
            <input type="file" class="custom-file-input" id="content_detail_image" name="content_detail_image">
            <label class="custom-file-label" for="content_detail_image">Choose file</label>
        </div>
        <div class="input-group-append">
            <span class="input-group-text" onclick="goContent_Detail_Image();">Upload</span>
        </div>
    </div>
    Image Width <input style="width: 75px;" type="text" name="content_img_width" class="form-control"  id="content_img_width" value="800" />
</div>

javascript

function 내부에서 bsCustomFileInput.init();를 호출하여 파일 객체 초기화 진행

function 내부에서 hidden type의 데이터를 contentDeitable 타입의 값에 복사하여 page에 출력시 사용

 

goContent_Detail_Image함수에서

file객체의 정보를 ajax 형태로 python으로 전달

python으로 서버에 이미지 생성 성공시 저장된 위치 및 파일명을 기반으로, templates의 content_detail 및 content_detail_edit에 이미치 tag를 추가하여 출력

이미지는 content_img_width에 설정된 값으로 생성(너무 크게 생성되는것을 방지하기 위해 1024를 max로 처리)

 

goContent_Edit함수에서

content_detail_edit에 수정한 내용을 DB에 저장할 때는 content_detail로 값을 변경하여 전달

<!-- Tempusdominus Bootstrap 4 -->
<link rel="stylesheet" href="/static/plugins/tempusdominus-bootstrap-4/css/tempusdominus-bootstrap-4.min.css">

<!-- jQuery -->
<script src="/static/plugins/jquery/jquery.min.js"></script>
<!-- Bootstrap 4 -->
<script src="/static/plugins/bootstrap/js/bootstrap.bundle.min.js"></script>
<!-- bs-custom-file-input -->
<script src="/static/plugins/bs-custom-file-input/bs-custom-file-input.min.js"></script>


$(function () {
    // File 객체 초기화
    bsCustomFileInput.init();
  
    // hidden type의 데이터를 contentEditable 타입의 값에 복사
    Src_Val = $('#content_detail').val()
    document.getElementById('content_detail_edit').innerHTML = Src_Val;
    document.getElementById("content_detail_edit").focus();
});


function goContent_Detail_Image(){
    
    let content_id = $('#content_id').val()
    let file = $('#content_detail_image')[0].files[0]

    let form_data = new FormData()
    form_data.append("id_give", content_id)
    form_data.append("file_give", file)

    // Image를 서버에 저장
    $.ajax({
        url:'/content/detail_image',
        type:'POST',
        data: form_data,
        cache: false,
        contentType: false,
        processData: false,
        success: function(data){
            showAlert('content detail image insert successful!!!', data.filename, 2, 2000);

            // 이미지 최대 width는 1024로 제한
            img_width = $('#content_img_width').val()
            if ( img_width > 1024 ) img_width = 1024;

            Src_Val = $('#content_detail').val()
            Change_Val = Src_Val + '<br> <img width = "' + img_width + '" src="/static/img/content/' + data.filename + '">' 

            document.getElementById('content_detail').innerHTML = Change_Val;
            document.getElementById('content_detail_edit').innerHTML = Change_Val;

        },
        error: function(xhr, ajaxOptions, thrownError) {
            var fail_title = "content detail img upload Failed!!";
            var fail_msg = '';
            var err_msg = JSON.parse(xhr.responseText);

            if (thrownError == 'UNKNOWN'){
                fail_msg = err_msg.message + ' (' + xhr.status + ')'
            } else {
                fail_msg = err_msg.message + ' (' + thrownError + ',' + xhr.status + ')';
            }

            showAlert(fail_title,fail_msg,3,1500);
        }
    });
    return false;
}


function goContent_Edit(){
// ** Content 수정 ** //

    // content detail text 전환
    Src_Val = document.getElementById('content_detail_edit').innerHTML;
    $('#content_detail').val(Src_Val);

    var param = $('#content_form').serialize();

    // content 수정 요청
    $.ajax({
        url:'/content/edit',
        type:'POST',
        data: param,
        success: function(data){
            showAlert('content Edit Successful!!!', data.message, 2, 2000);
        },
        error: function(xhr, ajaxOptions, thrownError) {
            var fail_title = "content edit Failed!!";
            var fail_msg = '';
            var err_msg = JSON.parse(xhr.responseText);

            if (thrownError == 'UNKNOWN'){
                fail_msg = err_msg.message + ' (' + xhr.status + ')'
            } else {
                fail_msg = err_msg.message + ' (' + thrownError + ',' + xhr.status + ')';
            }

            showAlert(fail_title,fail_msg,3,1500);
        }
    });
    return false;
};

python

이미지 파일명은 content_id + prefix_date + filename을 조합하여, 이미지 content별 구분과 등록 순서를 확인 가능하도록 네이밍 처리함

이미지를 서버에 저장한 이후 화면에 이미지를 출력하기 위해 파일명을 리턴

from werkzeug import secure_filename

@bts_blueprint.route('content/detail_image', methods=['POST'])
def content_detail_image():

    print("##  content_detail_image  ##")

    try:
        file = request.files['file_give']
        content_id = request.form['id_give']
        #extention = file.filename.split('.')[-1]

        UploadPath = 'static/img/content/'
        
        now_date = datetime.datetime.now()
        prefix_date = now_date.strftime('_%Y%m%d_%H%M%S_')
        
        ImgFullname = UploadPath + content_id + prefix_date + file.filename
        
        #file.save(UploadPath, secure_filename(file.filename))
        file.save(ImgFullname)

        return jsonify(filename=content_id + prefix_date + file.filename), 200

    except (RuntimeError, TypeError, NameError, SQLAlchemyError) as e:
        print("#### content detail img upload Failed !! " + str(e))

        return jsonify(message=str(e)), 1002

참고

https://velog.io/@wrs0707/%EB%82%98%ED%99%80%EB%A1%9C%EC%9D%BC%EA%B8%B0%EC%9E%A5-%EB%A7%8C%EB%93%A4%EA%B8%B0

 

https://blog.naver.com/ynskoh/221064660966

기능

- 라인 다중 차트(line multiple chart)

- 다중 차트 클릭 이벤트 제어(multiple chart click event control)

- 상시 레이블 출력( show label without mouseover)

html

canvas에 cMultiLineChart 생성

<canvas id="cMultiLineChart" style="min-height: 400px; height: 400px; max-height: 1000px; width: 700px; max-width: 100%;"></canvas>

javascript

chart.min.js : chart.js 3.x 사용을 위해 추가

chartjs-plugin-datalabels@2.0.0 : 마우스 오버없이 레이블을 항상 표시하기 위해 추가 ( chart.js 3.x 버전 부터는 2.0.0 사용)

 

[상시 레이블 출력 로직]

chart.js 3.x 버전에서 datalabels을 사용하기 위해서 반드시 chart config에 plugins: [ChartDataLabels] 추가 (중요)

plugins: [ChartDataLabels]를 추가하지 않는 경우, CDN을 추가하더라도 datalabels 인식이 되지 않음

 

data의 labels를 외부에서 입력 하는 경우

MultiLineChart.data.labels.push('월');

MultiLineChart.data.labels.push('화');

...

MultiLineChart.data.labels.push('일');

MultiLineChart.update();

 

group별 datasets의 data는 일반적으로 외부(DB)에서 조회 후 아래 형태로 입력

Chart_config.data.datasets[0].data.push(11);

Chart_config.data.datasets[0].data.push(22);

Chart_config.data.datasets[1].data.push(33);

Chart_config.data.datasets[1].data.push(44);

Chart_config.data.datasets[2].data.push(55);

Chart_config.data.datasets[2].data.push(66);

MultiLineChart.update();

 

datasets의 datalabels Color는 function을 사용하여 ctx값 추출하여 처리

예제는 value가 5 이상인 경우만 Color를 적용

function(ctx) {
    var value = ctx.dataset.data[ctx.dataIndex];
    return value > 5 ? ctx.dataset.backgroundColor : null;
}

color : label의 색상

backgroundColor : label 배경 색상

formatter : label 출력값

 

[클릭 이벤트 로직]

이벤트 발생 정보 조회

chart.js 3.x 이후 버전부터 getElementsAtEventForMode를 사용

var activePoints = C_Issue_analysis_range.getElementsAtEventForMode(evt, 'point', C_Issue_analysis_range.options);

chart.js 공식 가이드

 

클릭한 Chart의 그룹 인덱스 정보 ( 예제 에서는 Group 1, Group 2, Group 3 의 인덱스)
var datasetIndex = activePoints[0].datasetIndex

 

클릭한 그룹의 Value를 참조하기 위한 Index
var index = activePoints[0].index

 

Group label 정보

var label = MultiLineChart.data.datasets[datasetIndex].label;

 

클릭한 x좌표의 값 정보

var xlavel = MultiLineChart.scales["x"]._labelItems[index].label;

 

클릭한 Group의 Value값

var value = MultiLineChart.data.datasets[datasetIndex].data[index];

<script src="https://cdn.jsdelivr.net/npm/chart.js@3.0.0/dist/chart.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chartjs-plugin-datalabels@2.0.0"></script>

// Chart ctx Create
var Chart_ctx = document.getElementById('cMultiLineChart').getContext('2d');

// Chart Config Set
Chart_config = {
    plugins: [ChartDataLabels],
    type: 'line',
    data: {
        labels: ['월','화','수','목','금','토','일'],
        datasets: [
            {
                label: 'Group 1',
                data: [1,1,2,2,3,3,4],
                backgroundColor: 'rgba(255, 99, 132, 0.2)',
                borderColor: 'rgba(255, 99, 132, 1)',
                borderWidth: 3,
                datalabels: {
                    labels: {
                        value: {
                            align: 'top',
                            backgroundColor: function(ctx) {
                                var value = ctx.dataset.data[ctx.dataIndex];
                                return value > 0 ? ctx.dataset.backgroundColor : null;
                            },
                            borderWidth: 2,
                            borderRadius: 4,
                            color: function(ctx) {
                                var value = ctx.dataset.data[ctx.dataIndex];
                                return value > 0 ? 'black' : null;
                            },
                            padding: 4
                        }
                    }
                }
            },
            {
                label: 'Group 2',
                data: [4,4,5,5,0,0,1],
                backgroundColor: 'rgba(54, 162, 235, 0.2)',
                borderColor: 'rgba(54, 162, 235, 1)',
                borderWidth: 3,
                datalabels: {
                    labels: {
                        value: {
                            align: 'top',
                            backgroundColor: function(ctx) {
                                var value = ctx.dataset.data[ctx.dataIndex];
                                return value > 0 ? ctx.dataset.backgroundColor : null;
                            },
                            borderWidth: 2,
                            borderRadius: 4,
                            color: function(ctx) {
                                var value = ctx.dataset.data[ctx.dataIndex];
                                return value > 0 ? 'black' : null;
                            },
                            padding: 4
                        }
                    }
                }
            },
            {
                label: 'Group 3',
                data: [0,0,7,8,9,4,1],
                backgroundColor: 'rgba(50, 220, 20, 0.2)',
                borderColor: 'rgba(50, 220, 20, 1)',
                borderWidth: 3,
                datalabels: {
                    labels: {
                        value: {
                            align: 'top',
                            backgroundColor: function(ctx) {
                                var value = ctx.dataset.data[ctx.dataIndex];
                                return value > 5 ? ctx.dataset.backgroundColor : null;
                            },
                            borderWidth: 2,
                            borderRadius: 4,
                            color: function(ctx) {
                                var value = ctx.dataset.data[ctx.dataIndex];
                                return value > 5 ? 'black' : null;
                            },
                            padding: 4
                        }
                    }
                }
            }
        ]
    },
    options: {
        responsive: true,
        scales: {
            y: { 
                beginAtZero: true
            }
        },
        plugins: {
            legend: {
                position: 'left',
            },
            title: {
                display: true,
                text: '그룹별 주간 카운트',
                font: {
                    size: 30
                }
            }
       }
    }
};

// Chart Create
var MultiLineChart = new Chart(Chart_ctx, Chart_config);

// Chart Click Event
document.getElementById("cMultiLineChart").onclick = function(evt) {

    var activePoints = MultiLineChart.getElementsAtEventForMode(evt, 'point', MultiLineChart.options);

    var datasetIndex = activePoints[0].datasetIndex
    var index = activePoints[0].index

    var label = C_Issue_analysis_interval.data.datasets[datasetIndex].label;
    var xlavel = C_Issue_analysis_interval.scales["x"]._labelItems[index].label
    var value = C_Issue_analysis_interval.data.datasets[datasetIndex].data[index]
    
    //alert(label + "  :  " + value + "  :  " + xlavel);

    //Process
};

참고

https://v2_0_0--chartjs-plugin-datalabels.netlify.app/guide/getting-started.html#installation

 

Getting Started | chartjs-plugin-datalabels

Getting Started Installation npm (opens new window) (opens new window) CDN (opens new window) (opens new window) By default, https://cdn.jsdelivr.net/npm/chartjs-plugin-datalabels returns the latest (minified) version, however it's highly recommended (open

v2_0_0--chartjs-plugin-datalabels.netlify.app

https://www.chartjs.org/docs/3.2.1/samples/tooltip/interactions.html

https://www.chartjs.org/docs/latest/getting-started/v3-migration.html

https://www.chartjs.org/docs/latest/developers/api.html

https://stackoverflow.com/questions/50515985/get-ylabel-value-onclick-chart-js

현재 Page에서 열기

var OpenURL = 'https://openurl.co.kr';

window.location = OpenURL;

새탭에서 Page 열기

var OpenURL = 'https://openurl.co.kr';

window.open(OpenURL);

<a>~</a> 태그의 속성

_blank: 새 탭, 창

_self: 현재 탭, 창

_parent: 부모 탭, 창
_top: 최상위 탭, 창

<a href="http://tistory.com/" target="_blank">새 창, 탭 열기</a>
<a href="http://tistory.com/" target="_self">현재 창, 탭 열기</a>
<a href="http://tistory.com/" target="_parent">부모 탭, 창</a>
<a href="http://tistory.com/" target="_top">최상위 탭, 창</a>

today, tomorrow 날짜구하기

const today = new Date();
const tomorrow = new Date();

// Add 1 Day
tomorrow.setDate(today.getDate() + 1);

입력한 날짜(yyyyMMdd)가 유효한 날짜인지 검사

function is_valid_date(date_str)
{
    var yyyyMMdd = String(date_str);
    var year = yyyyMMdd.substring(0,4);
    var month = yyyyMMdd.substring(4,6);
    var day = yyyyMMdd.substring(6,8);

    if (!is_number(date_str) || date_str.length!=8)
        return false;

    if (Number(month)>12 || Number(month)<1)
        return false;

    if (Number(last_day(date_str))<day)
        return false;

    return true;
}

yyyy-MM-dd 날짜 문자열을 Date형으로 반환

function to_date2(date_str)
{
    var yyyyMMdd = String(date_str);
    var sYear = yyyyMMdd.substring(0,4);
    var sMonth = yyyyMMdd.substring(5,7);
    var sDate = yyyyMMdd.substring(8,10);

    //alert("sYear :"+sYear +"   sMonth :"+sMonth + "   sDate :"+sDate);
    return new Date(Number(sYear), Number(sMonth)-1, Number(sDate));
}

Date형을 yyyyMMdd형의 문자열로 변환

function get_date_str(date)
{
    var sYear = date.getFullYear();
    var sMonth = date.getMonth() + 1;
    var sDate = date.getDate();

    sMonth = sMonth > 9 ? sMonth : "0" + sMonth;
    sDate  = sDate > 9 ? sDate : "0" + sDate;
    return sYear + sMonth + sDate;
}

주어진 날짜가 윤년인지를 검사

function is_leap_year(date_str)
{
    var year = date_str.substring(0,4);
    if (year%4 == 0)
    {
        if (year%100 == 0)
            return (year%400 == 0);
        else
            return true;
    }
    else
        return false;
}

주어진 날짜(yyyyMMdd, yyyyMM) 그 달의 마지막 날짜를 반환

function last_day(date_str)
{
    var yyyyMMdd = String(date_str);
    var days = "31";
    var year = yyyyMMdd.substring(0,4);
    var month = yyyyMMdd.substring(4,6);

    if (Number(month) == 2)
    {
        if (is_leap_year(year+month+"01"))
            days = "29";
        else
            days = "28";
    }
else if (Number(month) == 4 || Number(month) == 6 || Number(month) == 9 || Number(month) == 11)
        days = "30";

    return days;
}

오늘 날짜 중 연도 반환

function get_today_year()
{
    var today = new Date();
    return today.getYear();
}

오늘 날짜 중 Month반환. format: MM

function get_today_month()
{
    var today = new Date();
    return (today.getMonth()+1) > 9 ?  (today.getMonth()+1) : "0" + (today.getMonth()+1)
}

참고

https://java119.tistory.com/76

 

[JavaScript] 날짜 관련 유용 함수 총 정리(feat.String to Date)

입력한 날짜(yyyyMMdd)가 유효한 날짜인지 검사 function is_valid_date(date_str) { var yyyyMMdd = String(date_str); var year = yyyyMMdd.substring(0,4); var month = yyyyMMdd.substring(4,6); var day = yy..

java119.tistory.com

html

<table id="factory_table" class="table" style="margin-top: 20px;">
	<colgroup>
		<col width="20%"/>
		<col width="10%"/>
		<col width="30%"/>
		<col width="30%"/>
		<col width="10%"/>
	</colgroup>
	
	<thead>
		<tr>
			<th>이름(설비)</th>
			<th>대수</th>
			<th>기계 및 컨트롤러 정보</th>
			<th>공정명</th>
			<th></th>
		</tr>
	</thead>

	<tbody id="factory_tbody">
		<tr>
			<td> <input type="text" class="form-control" placeholder="설비명">  </td>
			<td> <input type="number" class="form-control" placeholder="설치 대수" onkeypress="return event.charCode >= 48 && event.charCode <= 57">  </td>
			<td> <input type="text" class="form-control" placeholder="기계 및 컨트롤러 정보">  </td>
			<td> <input type="text" class="form-control" placeholder="공정명">  </td>
			<td></td>
		</tr>
	</tbody>
</table>

Table 행 추가

// 하나의 Row 입력
var rowItem = "<tr>"
rowItem += "<td> <input type='text' class='form-control' placeholder='설비명'> </td>"
rowItem += "<td> <input type='number' class='form-control' placeholder='설치 대수' onkeypress='return event.charCode >= 48 && event.charCode <= 57'> </td>"
rowItem += "<td> <input type='email' class='form-control' placeholder='기계 및 컨트롤러 정보'> </td>"
rowItem += "<td> <input type='text' class='form-control' placeholder='공정명'> </td>"
rowItem += "<td> <button type='button' class='btn btn-danger'> <i class='fa fa-minus'></i> </button> </td>"
rowItem += "</tr>"
$('#factory_table').append(rowItem)




// Table 행을 모두 삭제 후 리스트 형식 입력 ( 예제와 별도 형식 )
var TableRowsList = ["'a','b','c','d','e'","'1','2','3','4','5'",,,,]  <-- Table rows list가 들어 있다는 가정..

$('#factory_table').remove();

var rowItem = '<tr>'
rowItem += '<th>이름(설비)</th>'
rowItem += '<th>대수</th>'
rowItem += '<th>기계 및 컨트롤러 정보</th>'
rowItem += '<th>공정명</th>'
rowItem += '<th></th>'
rowItem += '</tr>'
$('#factory_table').append(rowItem)
            
for(key in TableRowsList ){
    RowList = TableRowsList[key].split(',')
    var rowItem = '<tr>'
    rowItem += '<td> ' + RowList[1] + ' </td>'
    rowItem += '<td> ' + RowList[2] + ' </td>'
    rowItem += '<td> ' + RowList[3] + ' </td>'
    rowItem += '<td> ' + RowList[4] + ' </td>'
    rowItem += '<td> ' + RowList[5] + ' </td>'
    rowItem += '</tr>'
    $('#factory_table').append(rowItem)
}

Table 행 삭제

$('#factory_table').on("click", "button", function() {
    $(this).closest("tr").remove()
});

입력된 Table 행 데이터 가져오기

$('#factory_tbody tr').each(function () {
	var cellItem = $(this).find(":input")
	var itemObj = new Object()
	itemObj.title = cellItem.eq(0).val()
	itemObj.count = cellItem.eq(1).val()
	itemObj.info = cellItem.eq(2).val()
	itemObj.name = cellItem.eq(3).val()
})

참고

https://elfinlas.github.io/2017/12/25/devnote01/

 

12월 18일 개발일지 (HTML Table의 행을 동적으로 처리하기 with jQuery)

HTML에서 Table 요소 처리이번에 제가 만드는 사내정보시스템을 이번에 저희 회사에도 도입을 하게 되면서, 회사에 특화된 기능을 개발하게 되었습니다.그런데 이번에 Html의 테이블 요소를 다루게

elfinlas.github.io

 

[PHP] php test page

http://phptester.net/

 

PHPTESTER - Test PHP code online

This application is free so please don't break it! Contact :phptester.net@gmail.com Dear Hacker you don't need to hack this free website to prove that you are very good!!!! Updates: I'm trying a new approche, PHP 7.1 to 7.4 version added but still in test

phptester.net

 

문자열에 특정 문자가 포함되어 있는지 확인

# Check 함수
function strpos_array($haystack, $needle) {
    $pos = FALSE;
    if (!is_array($needle)) $needle = array($needle);
    foreach ($needle as $what) {
        if (($pos = strpos($haystack, $what)) !== FALSE) {
            return $pos;
        }
    }
    return FALSE;
}

$filters = array("TEST", "test", "Pass", "PASS");
$strText = "The TEST Code !!"
if (strpos_array($strText, $filters) !== false) {
    // nothing to do
    echo json_encode("Text has been filtered");
    return;
}

기능

chart에 value를 동적으로 추가

backgroundColor를 랜덤하게 설정 ( 결과가 Fix 되지않은 chart 리스트를 추가 할때 사용 )

 

// html
<canvas id="cChart"></canvas>

// javascript
var Chart_ctx = document.getElementById('cChart').getContext('2d');

// Chart Config
Chart_config = {
    type: 'pie',
    data: ..........
}

// Chart Create
var Chart = new Chart(Chart_ctx, Chart_config);


// Chart Data 동적 추가
Chart_config.data.datasets[0].data.push(1);

// Set backgroundColor 랜덤하게 값 추가 ( 투명도 30% )
var RGB_1 = Math.floor(Math.random() * (255 + 1))
var RGB_2 = Math.floor(Math.random() * (255 + 1))
var RGB_3 = Math.floor(Math.random() * (255 + 1))
var strRGBA = 'rgba(' + RGB_1 + ',' + RGB_2 + ',' + RGB_3 + ',0.3)'
Chart_config.data.datasets[0].backgroundColor.push(strRGBA);

참고

https://stackoverflow.com/questions/23095637/how-do-you-get-random-rgb-in-javascript


to Top