반응형

Grafana에서 주식차트를 그리는 방법을 설명드립니다.

데이터 구조만 맞춰주시고 javascript 코드는 그대로 사용하시면 아래와 같은 그래프가 표시됩니다.

 

  • 차트

  • 데이터 구조

  • Javascript 코드입니다.
const rawData = [];
context.panel.data.series.forEach((series) => {
  const event_dates_Field = series.fields.find(f => f.name.toLowerCase().includes("event_date"));	// 날짜
  const openingPrices_Field = series.fields.find(f => f.name.toLowerCase().includes("openingprice"));	// 시가
  const tradePrices_Field = series.fields.find(f => f.name.toLowerCase().includes("tradeprice"));	// 종가
  const lowPrices_Field = series.fields.find(f => f.name.toLowerCase().includes("lowprice"));	// 저가
  const highPrices_Field = series.fields.find(f => f.name.toLowerCase().includes("highprice"));	// 고가
  if (!event_dates_Field || !openingPrices_Field || !tradePrices_Field || !lowPrices_Field || !highPrices_Field) return;

  const event_dates = event_dates_Field.values;
  const openingPrices = openingPrices_Field.values;
  const tradePrices = tradePrices_Field.values;
  const lowPrices = lowPrices_Field.values;
  const highPrices = highPrices_Field.values;

  for (let i = 0; i < event_dates.length; i++) {
    rawData.push([
      event_dates.get(i).toString(),
      openingPrices.get(i).toString(),
      tradePrices.get(i).toString(),
      lowPrices.get(i).toString(),
      highPrices.get(i).toString()
    ]);
  }
});
// console.log(rawData);
function calculateMA(dayCount, data) {
  var result = [];
  for (var i = 0, len = data.length; i < len; i++) {
    if (i < dayCount) {
      result.push('-');
      continue;
    }
    var sum = 0;
    for (var j = 0; j < dayCount; j++) {
      sum += +data[i - j][1];
    }
    result.push(sum / dayCount);
  }
  return result;
}
const dates = rawData.map(function (item) {
  return item[0];	// 날짜
});
const values = rawData.map(function (item) {
  return [+item[1], +item[2], +item[3], +item[4]];	// 시가(1), 종가(2), 저가(3), 고가(4)
});

return {
  legend: {
    data: ['日K', 'MA5', 'MA10', 'MA20', 'MA30'],
    inactiveColor: '#777'
  },
  tooltip: {
    trigger: 'axis',
    axisPointer: {
      animation: false,
      type: 'cross',
      lineStyle: {
        color: '#376df4',
        width: 2,
        opacity: 1
      }
    }
  },
  xAxis: {
    type: 'category',
    data: dates,
    axisLine: { lineStyle: { color: '#8392A5' } }
  },
  yAxis: {
    scale: true,
    axisLine: { lineStyle: { color: '#8392A5' } },
    splitLine: { show: false }
  },
  grid: {
    bottom: 80
  },
  dataZoom: [
    {
      textStyle: {
        color: '#8392A5'
      },
      handleIcon:
        'path://M10.7,11.9v-1.3H9.3v1.3c-4.9,0.3-8.8,4.4-8.8,9.4c0,5,3.9,9.1,8.8,9.4v1.3h1.3v-1.3c4.9-0.3,8.8-4.4,8.8-9.4C19.5,16.3,15.6,12.2,10.7,11.9z M13.3,24.4H6.7V23h6.6V24.4z M13.3,19.6H6.7v-1.4h6.6V19.6z',
      dataBackground: {
        areaStyle: {
          color: '#8392A5'
        },
        lineStyle: {
          opacity: 0.8,
          color: '#8392A5'
        }
      },
      brushSelect: true
    },
    {
      type: 'inside'
    }
  ],
  series: [
    {
      type: 'candlestick',
      name: 'Day',
      data: values,
      itemStyle: {
        color: '#FD1050',
        color0: '#0CF49B',
        borderColor: '#FD1050',
        borderColor0: '#0CF49B'
      }
    },
    {
      name: 'MA5',
      type: 'line',
      data: calculateMA(5, values),
      smooth: true,
      showSymbol: false,
      lineStyle: {
        width: 1
      }
    },
    {
      name: 'MA10',
      type: 'line',
      data: calculateMA(10, values),
      smooth: true,
      showSymbol: false,
      lineStyle: {
        width: 1
      }
    },
    {
      name: 'MA20',
      type: 'line',
      data: calculateMA(20, values),
      smooth: true,
      showSymbol: false,
      lineStyle: {
        width: 1
      }
    },
    {
      name: 'MA30',
      type: 'line',
      data: calculateMA(30, values),
      smooth: true,
      showSymbol: false,
      lineStyle: {
        width: 1
      }
    }
  ]
};

 

 

 

반응형

+ Recent posts