728x90

Web.config 파일에 해당 설정 추가

<configuration>
  <system.web.extensions>
    <scripting>
      <webServices>
        <jsonSerialization maxJsonLength="2147483647" />
      </webServices>
    </scripting>
  </system.web.extensions>
</configuration>

 

'IT > ASP.NET' 카테고리의 다른 글

에러처리  (0) 2022.07.01
[C#] Compute SHA256 Hash with Salt  (0) 2021.11.01
[MVC5] Email Send (office365 메일 서버)  (0) 2021.08.08
[C#]SQL to Linq 변환 - "IN"절 사용  (0) 2021.01.11
728x90

초등학교때 PC 게임으로 즐긴 랑그릿사가 모바일로 나온다고 해서 오픈부터 시작했는데,

 

벌써 518일째 하고있다.

 

서버는 티스라오 서버

 

고인물의 상징인 '구름 위의 성' 프로필 배경이다.

 

서밋은 오픈 때 3시즌 내내 골드 찍먹을 하고

 

시간이 없다는 핑계로 골드만 유지중이다.

 

 

영웅 컬랙션

 

랑그릿사 모바일 Chapter1
랑그릿사 모바일 Chapter2
랑그릿사 1
랑글릿사 2
랑그릿사 3
랑그릿사 4
랑그릿사 5
랑그릿사 리인카네이션

콜라보 진영을 제외하고 나열했는데도 많이 뽑은것 같다.

 

유대인질 때문에 거의 명함뽑기를 했었는데,

 

이후 케릭터들은 유대인질이 많이없어서

 

명함뽑기는 멈추고 뽑고싶은것만 뽑는거로 컨셉을 바꾸었다.

 

리코리스는 간만보고 다음은 린, 아리안로드!

 

 

따끈따끈한 아레스 5성, 윌러6성 기념

 

이번주 토요일 서밋아레나 시즌 4에 맞춰서 잘된것 같다.

 

아레스 6성, 디드리트 6성, 기자로프 6성 달리고 뭘 올릴지 고민해봐야겠다.

 

이번 서밋아레나 시즌4는 꼭 원더 달성을...!!

 

 

728x90

android 2.0 버전 때 java로 안드로이드 앱 개발을 해본적이 있었는데, 요새 다시 앱개발이 해보고 싶어졌다.

 

안드로이드 공식 언어인 Kotlin으로 개발을 해보려고 이리저리 찾아보았다.

 

온라인 CodeLab을 지원해줘서 하나씩 따라해보면서 Android Kotlin 앱 개발을 시작해보려고 한다.

 

 

아래 링크에서 Lesson1 부터 시작하면 된다.

https://developer.android.com/courses/kotlin-android-fundamentals/overview

 

Android Kotlin Fundamentals  |  Training Courses  |  Android Developers

The Android Kotlin Fundamentals course was created by the Google Developers Training team. In the course, you learn Android Kotlin programming concepts and build a variety of apps. The Android Kotlin Fundamentals course materials include: Prerequisites Thi

developer.android.com

 

개발 툴은 안드로이드 스튜디오를 사용한다.

(아래는 다운로드 링크)

https://developer.android.com/studio/

 

Download Android Studio and SDK tools  |  Android 스튜디오

developer.android.com

 

 

Install Android Studio, Get started 챕터는

 

안드로이드 스튜디오 다운로드, 애뮬레이터를 생성, 프로젝트 생성하는 방법인데

 

따라해보면 쉽게 할 수 있다.

(그림으로 상세하게 설명되어 있음)

 

실질적인 실습은 01.2 챕터부터다.

 

 

앱 실행 버튼

안드로이드 스튜디오 UI가 익숙치 않아서 실행하는데 헤매었다.

 

해당 버튼을 클릭하면 앱이 실행되는데 애뮬레이터(가상머신)이 실행되어 있지 않다면 

 

가상머신 실행후에 앱을 실행한다.

 

실행결과

Kotlin으로 처음만들어 본 DiceRoller 앱 ROLL 버튼을 누르면 랜덤으로 주사위 값을  표시해주는 간단한 기능을 가진 앱이다.

 

 

Kotlin은 처음 접해보는 언어라서 변수를 지정하는 선언문에서 좀 헷갈린게 있었는데, 

 

예제에서는 val 키워드로만 변수들이 선언되어 있었다. 

 

예제 이외의 기능을 추가하는 Coding Challenge에서는 변수에 값을 할당해서 구현해야 하는데, 

 

값이 할당이 안되서 찾아보니 변수 선언에는 val/var 두가지 키워드가 있었다.

val/var 키워드의 차이점

val로 선언된 변수는 읽기만 가능하고, var로 선언된 변수는 읽기/쓰기가 가능하다.

 

Code Lab에 있는 예제에 COUNT UP이라는 기능을 추가해보았다.

 

아래는 COUNT UP 기능에 대한 조건이다.

- "COUNT UP" 버튼을 ROLL 버튼 아래에 추가, 클릭시 숫자를 1씩 증가
- result text가 default로 "Hello Wolrd"일 경우 result text에 1을 할당
- 숫자가 6이라면, 숫자 증가는 이루어 지지 않음
실행결과

COUNT UP 기능을 추가 구현한 DiceRoller 앱 

 

아래는 COUNT UP 추가 기능까지 구현한 소스코드이다.

 

소스코드
MainActivity.kt
package com.example.android.diceroller

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.Button
import android.widget.TextView

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val rollButton: Button = findViewById(R.id.roll_button);
        rollButton.setOnClickListener{ rollDice() }; //roll_button 버튼에 onclick 이벤트 할당

        val countUpButton: Button = findViewById(R.id.count_up);
        countUpButton.setOnClickListener{ countUp() }; //count_up 버튼에 onclick 이벤트 할당

        //result text가 Default로 String일 경우 result text에 1을 할당
        val resultText: TextView = findViewById(R.id.result_text);
        var text = resultText.toString().toIntOrNull(); //Int형이 아니면 Null
        if(text == null) resultText.text = "1";
    }

    private fun rollDice(){
        val resultText: TextView = findViewById(R.id.result_text);
        val randomInt = (1..6).random(); //1~6 랜덤함수
        resultText.text = randomInt.toString();
    }

    private fun countUp(){
        val resultText: TextView = findViewById(R.id.result_text);
        var num =  resultText.text.toString().toInt();
        if(num != 6) num += 1;
        resultText.text = num.toString();

    }
}
소스코드
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    android:layout_gravity="center_vertical"
    tools:context=".MainActivity" >

    <TextView
        android:id="@+id/result_text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:textSize="30sp"
        android:text="Hello World!" />
    <Button
        android:id="@+id/roll_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:text="@string/roll_label">

    </Button>

    <Button
        android:id="@+id/count_up"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:text="@string/count_up_label">

    </Button>
</LinearLayout>
소스코드
strings.xml
<resources>
    <string name="app_name">DiceRoller</string>
    <string name="roll_label">Roll</string>
    <string name="count_up_label">Count Up</string>
</resources>

 

'IT > Android' 카테고리의 다른 글

[Kotlin]문법 - Log  (0) 2021.02.26
[Layout]Constraint Layout  (0) 2021.02.22
728x90

프로젝트를 하면서 하이차트 (Highcharts)를 처음 써보게 되었다.

 

Engine RPM을 표현해야 하는데,

 

구글링해도 100% 원하는 스타일의 게이지 차트 (Gauge Chart)가 없어서 직접 구현해보았다.

 

실행결과

 

게이지 차트

 

소스코드

 

var gaugeChartOption = {
    chart: {
      plotBackgroundColor: null,
      plotBackgroundImage: null,
      plotBorderWidth: 0,
      plotShadow: false,
      backgroundColor: '#2d3039',
      animation: true
    },
    title: {
      text: null
    },
    tooltip: {
      enabled: false
    },
    pane: {
      startAngle: -90,
      endAngle: 90,
      background: {
        backgroundColor: 'black',
        borderWidth: 0,
        shape: 'arc',
        innerRadius: '85%',
        outerRadius: '95%'
      },
      size: 230,
      center : ["50%", "80%"] //Center Position
    },
    yAxis: {
      stops: [
        [1, '#1DDB16'] // red
      ],
      min: 0,
      max: 900,
      minorTickLength: 0,
      lineWidth: 0,
      tickPixelInterval: 30,
      tickWidth: 2,
      tickPosition: 'inside',
      tickLength: 5,
      tickColor: '#FFFFFF',
      tickPositions: [0, 500, 700, 800, 900],
      labels: {
        distance: 10,
        style: {
          color: "#FFFFFF"
        }
      }
    },
    series: [
    {
      type: 'gauge',
      data: [0],
      pivot: {
        backgroundColor: "#1DDB16",
        borderColor: "#1DDB16",
        borderWidth: 0,
        radius: 7
      }, //Guage 가운데
      dataLabels: {
        y: 50,
        borderWidth: 0,
        style: {
          fontSize: '20px',
          color: "#FFFFFF",
          textOutline: false
        }
      },
      dial: {
        radius: '95%',
        backgroundColor: '#1DDB16',
        borderWidth: 0,
        baseWidth: 3,
        topWidth: 3,
        baseLength: '100%', // of radius
        rearLength: '0%'
      }
    },
    {
      type: 'solidgauge',
      data: [0],
      radius: '95%',
      innerRadius: '85%',
      dataLabels: {
        borderWidth: 0
      }
    },
    {
      type: 'solidgauge',
      data: [0],
      radius: '95%',
      innerRadius: '85%',
      dataLabels: {
        borderWidth: 0
      }
    }
  ],
  navigation: {
    buttonOptions: {
      enabled: false
    }
  },
  credits: {
    style: {
      'display': 'none'
    }
  },
  plotOptions: {
    series: {
      animation: false
    }
  },
};

var chartRpm = Highcharts.chart('container-rpm', gaugeChartOption);

setInterval(function(){
  var maxRPM = 120;
  var engRPM = getRandomArbitrary(maxRPM, maxRPM);

  var stops;
  if (engRPM > 0) {
    stops = [
      [0.5, '#000000'],
      [(maxRPM + engRPM) / (maxRPM * 2), '#1DDB16']
    ];
  }
  else if (engRPM == 0) {
    stops = [
      [0.5, '#000000'],
      [0.5, '#1DDB16']
    ];
  }
  else if (engRPM < 0) {
    stops = [
      [(maxRPM + engRPM) / (maxRPM * 2), '#000000'],
      [0.5, '#1DDB16']
    ];
  }
  else {
    stops = [
      [0.5, '#000000'],
      [0.5, '#1DDB16']
    ];
  }

  chartRpm.yAxis[0].update({
    min: -maxRPM,
    max: maxRPM,
    tickPositions: [ 
      -maxRPM, 
      -(maxRPM * 0.7), 
      -(maxRPM * 0.5), 
      -(maxRPM * 0.3), 
      0, 
      maxRPM * 0.3, 
      maxRPM * 0.5, 
      maxRPM * 0.7, maxRPM],
    stops: stops
  });

  //Gauge Chart Point
  var point = chartRpm.series[0].points[0];
  var point2 = chartRpm.series[1].points[0];
  var point3 = chartRpm.series[2].points[0];

  if (engRPM > 0) {
    point.update(engRPM, false);
    point2.update(engRPM + 0.5);
    point3.update(0);
    chartRpm.series[2].update({
      radius: '96%',
      innerRadius: '84%'
    });
  }
  else if (engRPM == 0) {
    point.update(engRPM, false);
    point2.update(engRPM - 1.5);
    point3.update(engRPM - 1.5);
  }
  else if (engRPM < 0) {
    point.update(engRPM, false);
    point2.update(0);
    point3.update(engRPM - 1);
    chartRpm.series[2].update({
      radius: '96%',
      innerRadius: '84%'
    });
  }
  else if (isNaN(engRPM)) {
    point.update(0, false);
    point2.update(-1.5);
    point3.update(-1.5);
  }
}, 2000);

function getRandomArbitrary(pos, neg) {

  var result;

  result = Math.floor(Math.random() * (pos + neg)) - neg;
  result = result < 0 ? result : result + 1;

  return result;
}

 

Dial표현은 gauge chart로

 

영역의 표현은 2개의 solidgauge chart로 구현했다.

 

아래는 jsfiddle로 구현한 예제이다.

 

https://jsfiddle.net/GeunChoi/q7gc2h9L/latest/

 

RPM Gauge Chart - JSFiddle - Code Playground

 

jsfiddle.net

+ Recent posts