chartjs/chartjs-chart-financial

chartjs-chart-financial for chartjs 3.0 won't display candlestick and line chart at the same time

aqw0567 opened this issue · 1 comments

Hi, I was previously using chart.js version 2.9.0, the candlestick and line chart displayed pretty well at the time. However, since the update of chart.js version 3.0, the line chart will not displayed with the candlestick chart.

Is there a way of resolving this? Thanks!

*** The OK version - Chart.js 2.9.0 with previous chartjs-chart-financial library:

<head>
	<meta charset="utf-8">
	<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
	<h2>Sample Chart</h2>
	<div style="width:100%;height:60vh;">
		<canvas id="chart"></canvas>
	</div>
	<script src="https://cdn.jsdelivr.net/npm/luxon@1.24.1"></script>
	<script src="https://cdn.jsdelivr.net/npm/chart.js@2.9.0"></script> 
	<script src="https://cdn.jsdelivr.net/npm/chartjs-adapter-luxon@0.2.0"></script>
	<script type="text/javascript">
	// the  Chart.js 2.9.0 compatible chartjs-chart-financial library
	!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(require("chart.js")):"function"==typeof define&&define.amd?define(["chart.js"],t):t((e=e||self).Chart)}(this,function(e){"use strict";const t=(e=e&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e).helpers,a={position:"left",ticks:{callback:e.Ticks.formatters.linear}},l=e.scaleService.getScaleConstructor("linear").extend({_parseValue(e){let t,a,l,n;return void 0!==e.c?(t=+this.getRightValue(e.l),a=+this.getRightValue(e.h),l=Math.min(t,a),n=Math.max(t,a)):(t=void 0,a=e=+this.getRightValue(e.y),l=e,n=e),{min:l,max:n,start:t,end:a}},determineDataLimits(){const e=this,a=e.chart,l=a.data.datasets,n=e.isHorizontal();e.min=null,e.max=null,t.each(l,(l,o)=>{const i=a.getDatasetMeta(o);a.isDatasetVisible(o)&&function(t){return n?t.xAxisID===e.id:t.yAxisID===e.id}(i)&&t.each(l.data,(t,a)=>{const l=e._parseValue(t);isNaN(l.min)||isNaN(l.max)||i.data[a].hidden||((null===e.min||l.min<e.min)&&(e.min=l.min),(null===e.max||e.max<l.max)&&(e.max=l.max))})});const o=.05*(e.max-e.min);e.min-=o,e.max+=o,this.handleTickRangeOptions()}});e.scaleService.registerScaleType("financialLinear",l,a);const n=e.helpers;e.defaults.financial={label:"",hover:{mode:"label"},scales:{xAxes:[{type:"time",distribution:"series",offset:!0,ticks:{major:{enabled:!0,fontStyle:"bold"},source:"data",maxRotation:0,autoSkip:!0,autoSkipPadding:75,sampleSize:100}}],yAxes:[{type:"financialLinear"}]},tooltips:{intersect:!1,mode:"index",callbacks:{label(t,a){const l=a.datasets[t.datasetIndex].data[t.index];if(n.isNullOrUndef(l.y)){return"open: "+l.o+"  high: "+l.h+"  low: "+l.l+"  close: "+l.c}return e.defaults.global.tooltips.callbacks.label(t,a)}}}};const o=e.controllers.bar.extend({dataElementType:e.elements.Financial,_updateElementGeometry(e,t,a,l){const n=this,o=e._model,i=n._getValueScale(),r=i.getBasePixel(),s=i.isHorizontal(),c=n._ruler||n.getRuler(),d=n.calculateBarValuePixels(n.index,t,l),h=n.calculateBarIndexPixels(n.index,t,c,l),u=n.chart.data.datasets[n.index].data[t];o.horizontal=s,o.base=a?r:d.base,o.x=s?a?r:d.head:h.center,o.y=s?h.center:a?r:d.head,o.height=s?h.size:void 0,o.width=s?void 0:h.size,o.candleOpen=i.getPixelForValue(Number(u.o)),o.candleHigh=i.getPixelForValue(Number(u.h)),o.candleLow=i.getPixelForValue(Number(u.l)),o.candleClose=i.getPixelForValue(Number(u.c))},draw(){const t=this.chart.chart.ctx,a=this.getMeta().data,l=this.getDataset(),n=a.length;let o,i=0;for(e.canvasHelpers.clipArea(t,this.chart.chartArea);i<n;++i)null==(o=l.data[i].o)||isNaN(o)||a[i].draw();e.canvasHelpers.unclipArea(t)}}),i=e.helpers;function r(e){const t=e._view,a=t.width/2,l=t.x-a,n=t.x+a;return{left:l,top:t.candleHigh,right:n,bottom:t.candleLow}}e.defaults.global.elements.financial={color:{up:"rgba(215,85,65,1)",down:"rgba(80,160,115,1)",unchanged:"rgba(90, 90, 90, 1)"}};const s=e.Element.extend({height(){const e=this._view;return e.base-e.y},inRange(e,t){let a=!1;if(this._view){const l=r(this);a=e>=l.left&&e<=l.right&&t>=l.top&&t<=l.bottom}return a},inLabelRange(e,t){if(!this._view)return!1;let a=!1;const l=r(this);return a=void 0!==this._view.width?e>=l.left&&e<=l.right:t>=l.top&&t<=l.bottom},inXRange(e){const t=r(this);return e>=t.left&&e<=t.right},inYRange(e){const t=r(this);return e>=t.top&&e<=t.bottom},getCenterPoint(){const e=this._view;return{x:e.x,y:(e.candleHigh+e.candleLow)/2}},getArea(){const e=this._view;return e.width*Math.abs(e.y-e.base)},tooltipPosition(){const e=this._view;return{x:e.x,y:(e.candleOpen+e.candleClose)/2}},hasValue(){const e=this._model;return i.isNumber(e.x)&&i.isNumber(e.candleOpen)&&i.isNumber(e.candleHigh)&&i.isNumber(e.candleLow)&&i.isNumber(e.candleClose)}}),c=e.helpers,d=e.defaults.global;d.elements.candlestick=c.merge({},[d.elements.financial,{borderColor:d.elements.financial.color.unchanged,borderWidth:1}]);const h=s.extend({draw(){const e=this._chart.ctx,t=this._view,a=t.x,l=t.candleOpen,n=t.candleHigh,o=t.candleLow,i=t.candleClose;let r,s=t.borderColor;"string"==typeof s&&(s={up:s,down:s,unchanged:s}),i<l?(r=c.getValueOrDefault(s?s.up:void 0,d.elements.candlestick.borderColor),e.fillStyle=c.getValueOrDefault(t.color?t.color.up:void 0,d.elements.candlestick.color.up)):i>l?(r=c.getValueOrDefault(s?s.down:void 0,d.elements.candlestick.borderColor),e.fillStyle=c.getValueOrDefault(t.color?t.color.down:void 0,d.elements.candlestick.color.down)):(r=c.getValueOrDefault(s?s.unchanged:void 0,d.elements.candlestick.borderColor),e.fillStyle=c.getValueOrDefault(t.color?t.color.unchanged:void 0,d.elements.candlestick.color.unchanged)),e.lineWidth=c.getValueOrDefault(t.borderWidth,d.elements.candlestick.borderWidth),e.strokeStyle=c.getValueOrDefault(r,d.elements.candlestick.borderColor),e.beginPath(),e.moveTo(a,n),e.lineTo(a,Math.min(l,i)),e.moveTo(a,o),e.lineTo(a,Math.max(l,i)),e.stroke(),e.fillRect(a-t.width/2,i,t.width,l-i),e.strokeRect(a-t.width/2,i,t.width,l-i),e.closePath()}});e.defaults.candlestick=e.helpers.merge({},e.defaults.financial),e.defaults._set("global",{datasets:{candlestick:e.defaults.global.datasets.bar}});e.controllers.candlestick=o.extend({dataElementType:h,updateElement(e,t,a){const l=this,n=l.getMeta(),o=l.getDataset(),i=l._resolveDataElementOptions(e,t);e._xScale=l.getScaleForId(n.xAxisID),e._yScale=l.getScaleForId(n.yAxisID),e._datasetIndex=l.index,e._index=t,e._model={datasetLabel:o.label||"",color:o.color,borderColor:o.borderColor,borderWidth:o.borderWidth},l._updateElementGeometry(e,t,a,i),e.pivot()}});const u=e.helpers,m=e.defaults.global;m.elements.ohlc=u.merge({},[m.elements.financial,{lineWidth:2,armLength:null,armLengthRatio:.8}]);const g=s.extend({draw(){const e=this._chart.ctx,t=this._view,a=t.x,l=t.candleOpen,n=t.candleHigh,o=t.candleLow,i=t.candleClose,r=u.getValueOrDefault(t.armLengthRatio,m.elements.ohlc.armLengthRatio);let s=u.getValueOrDefault(t.armLength,m.elements.ohlc.armLength);null===s&&(s=t.width*r*.5),e.strokeStyle=i<l?u.getValueOrDefault(t.color?t.color.up:void 0,m.elements.ohlc.color.up):i>l?u.getValueOrDefault(t.color?t.color.down:void 0,m.elements.ohlc.color.down):u.getValueOrDefault(t.color?t.color.unchanged:void 0,m.elements.ohlc.color.unchanged),e.lineWidth=u.getValueOrDefault(t.lineWidth,m.elements.ohlc.lineWidth),e.beginPath(),e.moveTo(a,n),e.lineTo(a,o),e.moveTo(a-s,l),e.lineTo(a,l),e.moveTo(a+s,i),e.lineTo(a,i),e.stroke()}});e.defaults.ohlc=e.helpers.merge({},e.defaults.financial),e.defaults._set("global",{datasets:{ohlc:{barPercentage:1,categoryPercentage:1}}});e.controllers.ohlc=o.extend({dataElementType:g,updateElement(e,t,a){const l=this,n=l.getMeta(),o=l.getDataset(),i=l._resolveDataElementOptions(e,t);e._xScale=l.getScaleForId(n.xAxisID),e._yScale=l.getScaleForId(n.yAxisID),e._datasetIndex=l.index,e._index=t,e._model={datasetLabel:o.label||"",lineWidth:o.lineWidth,armLength:o.armLength,armLengthRatio:o.armLengthRatio,color:o.color},l._updateElementGeometry(e,t,a,i),e.pivot()}})});
	</script>
	<script type="text/javascript">
		var stock_data = JSON.parse('{"price":[{"t":"2020-02-03","o":88.5,"h":89.15,"l":87.6,"c":89.05},{"t":"2020-02-04","o":89.45,"h":90.95,"l":89.2,"c":90.6},{"t":"2020-02-05","o":91,"h":91.3,"l":90.3,"c":90.85},{"t":"2020-02-06","o":91.65,"h":92.3,"l":91.35,"c":92.3},{"t":"2020-02-07","o":91.65,"h":91.65,"l":90.95,"c":91.2},{"t":"2020-02-10","o":90,"h":91.2,"l":89.6,"c":91},{"t":"2020-02-11","o":91.35,"h":91.95,"l":91.35,"c":91.75},{"t":"2020-02-12","o":92,"h":92.9,"l":92,"c":92.65},{"t":"2020-02-13","o":93,"h":93.25,"l":92.7,"c":92.8},{"t":"2020-02-14","o":92.8,"h":93.25,"l":92.55,"c":92.95},{"t":"2020-02-17","o":92.3,"h":92.55,"l":91.95,"c":92.3},{"t":"2020-02-18","o":91.4,"h":91.6,"l":91,"c":91.05},{"t":"2020-02-19","o":91.15,"h":92.25,"l":91.05,"c":92.1},{"t":"2020-02-20","o":92.35,"h":92.5,"l":91.35,"c":91.7},{"t":"2020-02-21","o":91.65,"h":91.95,"l":90.95,"c":91.25},{"t":"2020-02-24","o":90.25,"h":90.4,"l":89.7,"c":90.1},{"t":"2020-02-25","o":89.5,"h":90.5,"l":89.45,"c":90.35},{"t":"2020-02-26","o":89.15,"h":89.75,"l":88.9,"c":89.45},{"t":"2020-02-27","o":89.35,"h":89.5,"l":88.35,"c":88.65},{"t":"2020-03-02","o":87.5,"h":88.25,"l":86.85,"c":87.35},{"t":"2020-03-03","o":88.85,"h":88.95,"l":88.25,"c":88.6},{"t":"2020-03-04","o":88.8,"h":89.2,"l":88.4,"c":89.2},{"t":"2020-03-05","o":89.8,"h":90.25,"l":89.75,"c":90.2},{"t":"2020-03-06","o":89.65,"h":89.65,"l":88.3,"c":88.35},{"t":"2020-03-09","o":86.8,"h":86.8,"l":85.6,"c":85.85},{"t":"2020-03-10","o":85,"h":86.3,"l":84.9,"c":86.3},{"t":"2020-03-11","o":86.45,"h":86.55,"l":85.05,"c":85.3},{"t":"2020-03-12","o":84.5,"h":84.5,"l":81.15,"c":82.15},{"t":"2020-03-13","o":78,"h":81.4,"l":75.95,"c":81},{"t":"2020-03-16","o":80,"h":80.4,"l":76.95,"c":77.3},{"t":"2020-03-17","o":74.3,"h":76.7,"l":74.3,"c":74.85},{"t":"2020-03-18","o":74.95,"h":75.25,"l":72.8,"c":72.8},{"t":"2020-03-19","o":71,"h":71,"l":67.25,"c":68.55},{"t":"2020-03-20","o":71,"h":74,"l":70.9,"c":74},{"t":"2020-03-23","o":71,"h":72.1,"l":69.55,"c":70.8},{"t":"2020-03-24","o":73.85,"h":75.3,"l":73.7,"c":74.25},{"t":"2020-03-25","o":76.8,"h":77.45,"l":76.1,"c":76.85},{"t":"2020-03-26","o":77.4,"h":77.45,"l":76,"c":77.2},{"t":"2020-03-27","o":78.3,"h":78.7,"l":76.45,"c":76.6},{"t":"2020-03-30","o":74.7,"h":76.15,"l":74.05,"c":75.85},{"t":"2020-03-31","o":76.8,"h":77.2,"l":75.6,"c":76.15},{"t":"2020-04-01","o":76.5,"h":76.65,"l":75.85,"c":75.9},{"t":"2020-04-06","o":76.95,"h":77.1,"l":75.75,"c":77.05},{"t":"2020-04-07","o":78.5,"h":78.9,"l":78.05,"c":78.5},{"t":"2020-04-08","o":78.5,"h":79.7,"l":78.35,"c":79.6},{"t":"2020-04-09","o":79.85,"h":80.1,"l":78.85,"c":79.25},{"t":"2020-04-10","o":79,"h":79.35,"l":78.7,"c":79.3},{"t":"2020-04-13","o":79,"h":79.4,"l":78.55,"c":78.8},{"t":"2020-04-14","o":79.05,"h":80.95,"l":79.05,"c":80.95},{"t":"2020-04-15","o":81.25,"h":81.5,"l":81,"c":81.2},{"t":"2020-04-16","o":80.2,"h":81.1,"l":80.05,"c":80.8},{"t":"2020-04-17","o":83,"h":84,"l":82.7,"c":83.25},{"t":"2020-04-20","o":83.25,"h":83.5,"l":82.8,"c":83},{"t":"2020-04-21","o":82.65,"h":82.65,"l":80.5,"c":80.6},{"t":"2020-04-22","o":80,"h":80.6,"l":79.5,"c":80.6},{"t":"2020-04-23","o":81.15,"h":82,"l":80.3,"c":80.9},{"t":"2020-04-24","o":80.8,"h":81,"l":80.45,"c":80.9},{"t":"2020-04-27","o":82.15,"h":82.6,"l":81.65,"c":82.55},{"t":"2020-04-28","o":82.9,"h":82.9,"l":82,"c":82.55},{"t":"2020-04-29","o":83.05,"h":83.9,"l":82.95,"c":83.7},{"t":"2020-04-30","o":84.45,"h":85.5,"l":84.4,"c":85.5}], "time":[{"t":"2020-02-03"},{"t":"2020-02-04"},{"t":"2020-02-05"},{"t":"2020-02-06"},{"t":"2020-02-07"},{"t":"2020-02-10"},{"t":"2020-02-11"},{"t":"2020-02-12"},{"t":"2020-02-13"},{"t":"2020-02-14"},{"t":"2020-02-17"},{"t":"2020-02-18"},{"t":"2020-02-19"},{"t":"2020-02-20"},{"t":"2020-02-21"},{"t":"2020-02-24"},{"t":"2020-02-25"},{"t":"2020-02-26"},{"t":"2020-02-27"},{"t":"2020-03-02"},{"t":"2020-03-03"},{"t":"2020-03-04"},{"t":"2020-03-05"},{"t":"2020-03-06"},{"t":"2020-03-09"},{"t":"2020-03-10"},{"t":"2020-03-11"},{"t":"2020-03-12"},{"t":"2020-03-13"},{"t":"2020-03-16"},{"t":"2020-03-17"},{"t":"2020-03-18"},{"t":"2020-03-19"},{"t":"2020-03-20"},{"t":"2020-03-23"},{"t":"2020-03-24"},{"t":"2020-03-25"},{"t":"2020-03-26"},{"t":"2020-03-27"},{"t":"2020-03-30"},{"t":"2020-03-31"},{"t":"2020-04-01"},{"t":"2020-04-06"},{"t":"2020-04-07"},{"t":"2020-04-08"},{"t":"2020-04-09"},{"t":"2020-04-10"},{"t":"2020-04-13"},{"t":"2020-04-14"},{"t":"2020-04-15"},{"t":"2020-04-16"},{"t":"2020-04-17"},{"t":"2020-04-20"},{"t":"2020-04-21"},{"t":"2020-04-22"},{"t":"2020-04-23"},{"t":"2020-04-24"},{"t":"2020-04-27"},{"t":"2020-04-28"},{"t":"2020-04-29"},{"t":"2020-04-30"}],"volumn":[15824,8904,6702,10696,9555,7309,5115,5640,5754,4988,6266,12529,7947,6538,5401,13572,8840,15256,24688,27895,11072,8437,9785,17096,27734,23784,15307,44910,53705,33814,51146,46791,68038,40911,22465,26957,32688,19216,21954,13606,9764,9948,12208,15302,15231,15650,5825,7431,13122,17361,12410,34532,12336,21082,10896,13299,5765,13918,7557,11874,18785],"ma20":[96.2725,95.935,95.5775,95.3025,95.015,94.6825,94.3875,94.2,94.035,93.9,93.6675,93.355,93.06,92.715,92.3975,92.0375,91.69,91.2775,91.1025,90.9725,90.95,90.88,90.8475,90.65,90.3825,90.1475,89.825,89.3,88.71,87.9275,87.055,86.1425,84.965,84.08,83.0575,82.265,81.59,80.9775,80.375,79.8,79.1775,78.5125,77.855,77.3625,77.05,76.6975,76.3975,76.23,76.2275,76.4225,76.72,77.2425,77.965,78.295,78.785,79.1175,79.32,79.5875,79.885,80.2775,80.745],"volll_max":680.00}');

		var timee = [stock_data.price.length];
		for (i = 0, ilen = stock_data.price.length; i < ilen; i++) {
			var tick = stock_data.price[i];
			var val = luxon.DateTime.fromISO(tick.t).toMillis();
			stock_data.price[i].t = val;
			timee[i] = val;
		}

		var ctx = document.getElementById('chart').getContext('2d');
		ctx.canvas.width = 1000;
		ctx.canvas.height = 250;

		var chart = new Chart(ctx, {
			type: 'candlestick',
			data: {
				datasets: [{
					label: 'CHRT - Chart.js Corporation',
					data: stock_data.price,
				},{
					type: 'line',
					data: stock_data.ma20,
					label: '20MA',
					fill: false,
					pointRadius: 0,
					borderWidth: 1,
					borderColor: 'black'
				}],
				labels: timee
			},
			options: {
				tooltips: {
					intersect: false,
					mode: 'index',
					callbacks: {
						label(tooltipItem, data) {
							const dataset = data.datasets[tooltipItem.datasetIndex];
							const point = dataset.data[tooltipItem.index];

							if ( point.o == undefined ) {
								return Chart.defaults.global.tooltips.callbacks.label(tooltipItem, data);
							} else {

								const o = point.o;
								const h = point.h;
								const l = point.l;
								const c = point.c;

								return 'open: ' + o + '  high: ' + h + '  low: ' + l + '  close: ' + c;
							}
						}
					}
				},
				legend: {
					display: false
				}
			}
		});

	</script>
</body>



*** When I use the Chart.js version 3.0, it won't do the same thing...

	<head>
	<meta charset="utf-8">
	<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
	<h2>Sample Chart</h2>
	<div style="width:100%;height:60vh;">
		<canvas id="chart"></canvas>
	</div>
	<script src="https://cdn.jsdelivr.net/npm/luxon@1.24.1"></script>
	<script src="https://cdn.jsdelivr.net/npm/chart.js@3.0.0-beta.3/dist/chart.js"></script>
	<script src="https://cdn.jsdelivr.net/npm/chartjs-adapter-luxon@0.2.1"></script>
	<script>
	// the  Chart.js 3.0 compatible chartjs-chart-financial library
	!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(require("chart.js")):"function"==typeof define&&define.amd?define(["chart.js"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).Chart)}(this,function(e){"use strict";function t(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var o=t(e);function n(e){if(Array.isArray&&Array.isArray(e))return!0;const t=Object.prototype.toString.call(e);return"[object"===t.substr(0,7)&&"Array]"===t.substr(-6)}function l(e){return null!==e&&"[object Object]"===Object.prototype.toString.call(e)}function a(e,t){return void 0===e?t:e}function r(e){if(n(e))return e.map(r);if(l(e)){const t={},o=Object.keys(e),n=o.length;let l=0;for(;l<n;++l)t[o[l]]=r(e[o[l]]);return t}return e}function i(e,t,o,n){const a=t[e],i=o[e];l(a)&&l(i)?s(a,i,n):t[e]=r(i)}function s(e,t,o){const a=n(t)?t:[t],r=a.length;if(!l(e))return e;const s=(o=o||{}).merger||i;for(let n=0;n<r;++n){if(!l(t=a[n]))continue;const r=Object.keys(t);for(let n=0,l=r.length;n<l;++n)s(r[n],e,t,o)}return e}!function(){let e=!1;try{const t={get passive(){return e=!0,!1}};window.addEventListener("test",null,t),window.removeEventListener("test",null,t)}catch(e){}}();e.defaults.financial={label:"",parsing:!1,hover:{mode:"label"},datasets:{categoryPercentage:.8,barPercentage:.9,animation:{numbers:{type:"number",properties:["x","y","base","width","open","high","low","close"]}}},scales:{x:{type:"timeseries",offset:!0,ticks:{major:{enabled:!0},fontStyle:e=>e.tick.major?"bold":void 0,source:"data",maxRotation:0,autoSkip:!0,autoSkipPadding:75,sampleSize:100},afterBuildTicks:e=>{const t=window&&window.luxon&&window.luxon.DateTime;if(!t)return;const o=e._majorUnit,n=e.ticks,l=n[0];let a=t.fromMillis(n[0].value);"minute"===o&&0===a.second||"hour"===o&&0===a.minute||"day"===o&&9===a.hour||"month"===o&&a.day<=3&&1===a.weekday||"year"===o&&1===a.month?l.major=!0:l.major=!1;let r=a.get(o);for(let e=1;e<n.length;e++){const l=n[e],i=(a=t.fromMillis(l.value)).get(o);l.major=i!==r,r=i}e.ticks=n}},y:{type:"linear"}},tooltips:{intersect:!1,mode:"index",callbacks:{label(t){const o=t.dataPoint;if(null!=o.y)return e.Chart.defaults.tooltips.callbacks.label(t);const{o:n,h:l,l:a,c:r}=o;return`O: ${n}  H: ${l}  L: ${a}  C: ${r}`}}}};class c extends e.BarController{getLabelAndValue(e){const t=this.getParsed(e),{o:o,h:n,l:l,c:a}=t,r=`O: ${o}  H: ${n}  L: ${l}  C: ${a}`;return{label:`${this._cachedMeta.iScale.getLabelForValue(t.t)}`,value:r}}getAllParsedValues(){const e=this._cachedMeta._parsed,t=[];for(let o=0;o<e.length;++o)t.push(e[o].t);return t}getMinMax(e){const t=this._cachedMeta,o=t._parsed;if(o.length<2)return{min:0,max:1};if(e===t.iScale)return{min:o[0].t,max:o[o.length-1].t};let n=Number.POSITIVE_INFINITY,l=Number.NEGATIVE_INFINITY;for(let e=0;e<o.length;e++){const t=o[e];n=Math.min(n,t.l),l=Math.max(l,t.h)}return{min:n,max:l}}_getRuler(){const e=this,t=e._cachedMeta,o=t.iScale,n=[];for(let l=0;l<t.data.length;++l)n.push(o.getPixelForValue(e.getParsed(l).t));return{min:function(e,t){let o,n,l,a,r=e._length;for(l=1,a=t.length;l<a;++l)r=Math.min(r,Math.abs(t[l]-t[l-1]));for(l=0,a=e.ticks.length;l<a;++l)n=e.getPixelForTick(l),r=l>0?Math.min(r,Math.abs(n-o)):r,o=n;return r}(o,n),pixels:n,start:o._startPixel,end:o._endPixel,stackCount:e._getStackCount(),scale:o}}calculateElementProperties(e,t,o,n){const l=this._cachedMeta.vScale,a=l.getBasePixel(),r=this._calculateBarIndexPixels(e,t,n),i=this.chart.data.datasets[this.index].data[e],s=l.getPixelForValue(i.o),c=l.getPixelForValue(i.h),d=l.getPixelForValue(i.l),h=l.getPixelForValue(i.c);return{base:o?a:d,x:r.center,y:(d+c)/2,width:r.size,open:s,high:c,low:d,close:h}}draw(){const e=this,t=e.chart,o=e._cachedMeta.data;var n,l;n=t.ctx,l=t.chartArea,n.save(),n.beginPath(),n.rect(l.left,l.top,l.right-l.left,l.bottom-l.top),n.clip();for(let t=0;t<o.length;++t)o[t].draw(e._ctx);!function(e){e.restore()}(t.ctx)}}function d(e,t,o,n){const l=null===t,a=null===o,r=!(!e||l&&a)&&function(e,t){const{x:o,y:n,base:l,width:a,height:r}=e.getProps(["x","low","high","width","height"],t);let i,s,c,d,h;return e.horizontal?(h=r/2,i=Math.min(o,l),s=Math.max(o,l),c=n-h,d=n+h):(i=o-(h=a/2),s=o+h,c=Math.min(n,l),d=Math.max(n,l)),{left:i,top:c,right:s,bottom:d}}(e,n);return r&&(l||t>=r.left&&t<=r.right)&&(a||o>=r.top&&o<=r.bottom)}o.default.defaults.elements.financial={color:{up:"rgba(80, 160, 115, 1)",down:"rgba(215, 85, 65, 1)",unchanged:"rgba(90, 90, 90, 1)"}};class h extends o.default.Element{height(){return this.base-this.y}inRange(e,t,o){return d(this,e,t,o)}inXRange(e,t){return d(this,e,null,t)}inYRange(e,t){return d(this,null,e,t)}getRange(e){return"x"===e?this.width/2:this.height/2}getCenterPoint(e){const{x:t,low:o,high:n}=this.getProps(["x","low","high"],e);return{x:t,y:(n+o)/2}}tooltipPosition(e){const{x:t,open:o,close:n}=this.getProps(["x","open","close"],e);return{x:t,y:(o+n)/2}}}const u=o.default.defaults;class g extends h{draw(e){const t=this,{x:o,open:n,high:l,low:r,close:i}=t;let s,c=t.borderColor;"string"==typeof c&&(c={up:c,down:c,unchanged:c}),i<n?(s=a(c?c.up:void 0,u.elements.candlestick.borderColor),e.fillStyle=a(t.color?t.color.up:void 0,u.elements.candlestick.color.up)):i>n?(s=a(c?c.down:void 0,u.elements.candlestick.borderColor),e.fillStyle=a(t.color?t.color.down:void 0,u.elements.candlestick.color.down)):(s=a(c?c.unchanged:void 0,u.elements.candlestick.borderColor),e.fillStyle=a(t.color?t.color.unchanged:void 0,u.elements.candlestick.color.unchanged)),e.lineWidth=a(t.borderWidth,u.elements.candlestick.borderWidth),e.strokeStyle=a(s,u.elements.candlestick.borderColor),e.beginPath(),e.moveTo(o,l),e.lineTo(o,Math.min(n,i)),e.moveTo(o,r),e.lineTo(o,Math.max(n,i)),e.stroke(),e.fillRect(o-t.width/2,i,t.width,n-i),e.strokeRect(o-t.width/2,i,t.width,n-i),e.closePath()}}g.id="candlestick",g.defaults=s({},[u.elements.financial,{borderColor:u.elements.financial.color.unchanged,borderWidth:1}]);class m extends c{updateElements(e,t,o,n){const l=this,a=l.getDataset(),r=l._ruler||l._getRuler(),i=l.resolveDataElementOptions(t,n),s=l.getSharedOptions(i),c=l.includeOptions(n,s);l.updateSharedOptions(s,n,i);for(let i=t;i<o;i++){const t=s||l.resolveDataElementOptions(i,n),o={...l.calculateElementProperties(i,r,"reset"===n,t),datasetLabel:a.label||"",color:a.color,borderColor:a.borderColor,borderWidth:a.borderWidth};c&&(o.options=t),l.updateElement(e[i],i,o,n)}}}m.id="candlestick",m.defaults=s({dataElementType:g.id},o.default.defaults.financial);const f=o.default.defaults;class p extends h{draw(e){const t=this,{x:o,open:n,high:l,low:r,close:i}=t,s=a(t.armLengthRatio,f.elements.ohlc.armLengthRatio);let c=a(t.armLength,f.elements.ohlc.armLength);null===c&&(c=t.width*s*.5),e.strokeStyle=i<n?a(t.color?t.color.up:void 0,f.elements.ohlc.color.up):i>n?a(t.color?t.color.down:void 0,f.elements.ohlc.color.down):a(t.color?t.color.unchanged:void 0,f.elements.ohlc.color.unchanged),e.lineWidth=a(t.lineWidth,f.elements.ohlc.lineWidth),e.beginPath(),e.moveTo(o,l),e.lineTo(o,r),e.moveTo(o-c,n),e.lineTo(o,n),e.moveTo(o+c,i),e.lineTo(o,i),e.stroke()}}p.id="ohlc",p.defaults=s({},[f.elements.financial,{lineWidth:2,armLength:null,armLengthRatio:.8}]);class b extends c{updateElements(e,t,o,n){const l=this,a=l.getDataset(),r=l._ruler||l._getRuler(),i=l.resolveDataElementOptions(t,n),s=l.getSharedOptions(i),c=l.includeOptions(n,s);for(let t=0;t<o;t++){const o=s||l.resolveDataElementOptions(t,n),i={...l.calculateElementProperties(t,r,"reset"===n,o),datasetLabel:a.label||"",lineWidth:a.lineWidth,armLength:a.armLength,armLengthRatio:a.armLengthRatio,color:a.color};c&&(i.options=o),l.updateElement(e[t],t,i,n)}}}b.id="ohlc",b.defaults=s({dataElementType:p.id,datasets:{barPercentage:1,categoryPercentage:1}},o.default.defaults.financial),e.Chart.register(m,b,g,p)});
	</script>
	<script type="text/javascript">
		var stock_data = JSON.parse('{"price":[{"t":"2020-02-03","o":88.5,"h":89.15,"l":87.6,"c":89.05},{"t":"2020-02-04","o":89.45,"h":90.95,"l":89.2,"c":90.6},{"t":"2020-02-05","o":91,"h":91.3,"l":90.3,"c":90.85},{"t":"2020-02-06","o":91.65,"h":92.3,"l":91.35,"c":92.3},{"t":"2020-02-07","o":91.65,"h":91.65,"l":90.95,"c":91.2},{"t":"2020-02-10","o":90,"h":91.2,"l":89.6,"c":91},{"t":"2020-02-11","o":91.35,"h":91.95,"l":91.35,"c":91.75},{"t":"2020-02-12","o":92,"h":92.9,"l":92,"c":92.65},{"t":"2020-02-13","o":93,"h":93.25,"l":92.7,"c":92.8},{"t":"2020-02-14","o":92.8,"h":93.25,"l":92.55,"c":92.95},{"t":"2020-02-17","o":92.3,"h":92.55,"l":91.95,"c":92.3},{"t":"2020-02-18","o":91.4,"h":91.6,"l":91,"c":91.05},{"t":"2020-02-19","o":91.15,"h":92.25,"l":91.05,"c":92.1},{"t":"2020-02-20","o":92.35,"h":92.5,"l":91.35,"c":91.7},{"t":"2020-02-21","o":91.65,"h":91.95,"l":90.95,"c":91.25},{"t":"2020-02-24","o":90.25,"h":90.4,"l":89.7,"c":90.1},{"t":"2020-02-25","o":89.5,"h":90.5,"l":89.45,"c":90.35},{"t":"2020-02-26","o":89.15,"h":89.75,"l":88.9,"c":89.45},{"t":"2020-02-27","o":89.35,"h":89.5,"l":88.35,"c":88.65},{"t":"2020-03-02","o":87.5,"h":88.25,"l":86.85,"c":87.35},{"t":"2020-03-03","o":88.85,"h":88.95,"l":88.25,"c":88.6},{"t":"2020-03-04","o":88.8,"h":89.2,"l":88.4,"c":89.2},{"t":"2020-03-05","o":89.8,"h":90.25,"l":89.75,"c":90.2},{"t":"2020-03-06","o":89.65,"h":89.65,"l":88.3,"c":88.35},{"t":"2020-03-09","o":86.8,"h":86.8,"l":85.6,"c":85.85},{"t":"2020-03-10","o":85,"h":86.3,"l":84.9,"c":86.3},{"t":"2020-03-11","o":86.45,"h":86.55,"l":85.05,"c":85.3},{"t":"2020-03-12","o":84.5,"h":84.5,"l":81.15,"c":82.15},{"t":"2020-03-13","o":78,"h":81.4,"l":75.95,"c":81},{"t":"2020-03-16","o":80,"h":80.4,"l":76.95,"c":77.3},{"t":"2020-03-17","o":74.3,"h":76.7,"l":74.3,"c":74.85},{"t":"2020-03-18","o":74.95,"h":75.25,"l":72.8,"c":72.8},{"t":"2020-03-19","o":71,"h":71,"l":67.25,"c":68.55},{"t":"2020-03-20","o":71,"h":74,"l":70.9,"c":74},{"t":"2020-03-23","o":71,"h":72.1,"l":69.55,"c":70.8},{"t":"2020-03-24","o":73.85,"h":75.3,"l":73.7,"c":74.25},{"t":"2020-03-25","o":76.8,"h":77.45,"l":76.1,"c":76.85},{"t":"2020-03-26","o":77.4,"h":77.45,"l":76,"c":77.2},{"t":"2020-03-27","o":78.3,"h":78.7,"l":76.45,"c":76.6},{"t":"2020-03-30","o":74.7,"h":76.15,"l":74.05,"c":75.85},{"t":"2020-03-31","o":76.8,"h":77.2,"l":75.6,"c":76.15},{"t":"2020-04-01","o":76.5,"h":76.65,"l":75.85,"c":75.9},{"t":"2020-04-06","o":76.95,"h":77.1,"l":75.75,"c":77.05},{"t":"2020-04-07","o":78.5,"h":78.9,"l":78.05,"c":78.5},{"t":"2020-04-08","o":78.5,"h":79.7,"l":78.35,"c":79.6},{"t":"2020-04-09","o":79.85,"h":80.1,"l":78.85,"c":79.25},{"t":"2020-04-10","o":79,"h":79.35,"l":78.7,"c":79.3},{"t":"2020-04-13","o":79,"h":79.4,"l":78.55,"c":78.8},{"t":"2020-04-14","o":79.05,"h":80.95,"l":79.05,"c":80.95},{"t":"2020-04-15","o":81.25,"h":81.5,"l":81,"c":81.2},{"t":"2020-04-16","o":80.2,"h":81.1,"l":80.05,"c":80.8},{"t":"2020-04-17","o":83,"h":84,"l":82.7,"c":83.25},{"t":"2020-04-20","o":83.25,"h":83.5,"l":82.8,"c":83},{"t":"2020-04-21","o":82.65,"h":82.65,"l":80.5,"c":80.6},{"t":"2020-04-22","o":80,"h":80.6,"l":79.5,"c":80.6},{"t":"2020-04-23","o":81.15,"h":82,"l":80.3,"c":80.9},{"t":"2020-04-24","o":80.8,"h":81,"l":80.45,"c":80.9},{"t":"2020-04-27","o":82.15,"h":82.6,"l":81.65,"c":82.55},{"t":"2020-04-28","o":82.9,"h":82.9,"l":82,"c":82.55},{"t":"2020-04-29","o":83.05,"h":83.9,"l":82.95,"c":83.7},{"t":"2020-04-30","o":84.45,"h":85.5,"l":84.4,"c":85.5}], "time":[{"t":"2020-02-03"},{"t":"2020-02-04"},{"t":"2020-02-05"},{"t":"2020-02-06"},{"t":"2020-02-07"},{"t":"2020-02-10"},{"t":"2020-02-11"},{"t":"2020-02-12"},{"t":"2020-02-13"},{"t":"2020-02-14"},{"t":"2020-02-17"},{"t":"2020-02-18"},{"t":"2020-02-19"},{"t":"2020-02-20"},{"t":"2020-02-21"},{"t":"2020-02-24"},{"t":"2020-02-25"},{"t":"2020-02-26"},{"t":"2020-02-27"},{"t":"2020-03-02"},{"t":"2020-03-03"},{"t":"2020-03-04"},{"t":"2020-03-05"},{"t":"2020-03-06"},{"t":"2020-03-09"},{"t":"2020-03-10"},{"t":"2020-03-11"},{"t":"2020-03-12"},{"t":"2020-03-13"},{"t":"2020-03-16"},{"t":"2020-03-17"},{"t":"2020-03-18"},{"t":"2020-03-19"},{"t":"2020-03-20"},{"t":"2020-03-23"},{"t":"2020-03-24"},{"t":"2020-03-25"},{"t":"2020-03-26"},{"t":"2020-03-27"},{"t":"2020-03-30"},{"t":"2020-03-31"},{"t":"2020-04-01"},{"t":"2020-04-06"},{"t":"2020-04-07"},{"t":"2020-04-08"},{"t":"2020-04-09"},{"t":"2020-04-10"},{"t":"2020-04-13"},{"t":"2020-04-14"},{"t":"2020-04-15"},{"t":"2020-04-16"},{"t":"2020-04-17"},{"t":"2020-04-20"},{"t":"2020-04-21"},{"t":"2020-04-22"},{"t":"2020-04-23"},{"t":"2020-04-24"},{"t":"2020-04-27"},{"t":"2020-04-28"},{"t":"2020-04-29"},{"t":"2020-04-30"}],"volumn":[15824,8904,6702,10696,9555,7309,5115,5640,5754,4988,6266,12529,7947,6538,5401,13572,8840,15256,24688,27895,11072,8437,9785,17096,27734,23784,15307,44910,53705,33814,51146,46791,68038,40911,22465,26957,32688,19216,21954,13606,9764,9948,12208,15302,15231,15650,5825,7431,13122,17361,12410,34532,12336,21082,10896,13299,5765,13918,7557,11874,18785],"ma20":[96.2725,95.935,95.5775,95.3025,95.015,94.6825,94.3875,94.2,94.035,93.9,93.6675,93.355,93.06,92.715,92.3975,92.0375,91.69,91.2775,91.1025,90.9725,90.95,90.88,90.8475,90.65,90.3825,90.1475,89.825,89.3,88.71,87.9275,87.055,86.1425,84.965,84.08,83.0575,82.265,81.59,80.9775,80.375,79.8,79.1775,78.5125,77.855,77.3625,77.05,76.6975,76.3975,76.23,76.2275,76.4225,76.72,77.2425,77.965,78.295,78.785,79.1175,79.32,79.5875,79.885,80.2775,80.745],"volll_max":680.00}');

		var timee = [stock_data.price.length];
		for (i = 0, ilen = stock_data.price.length; i < ilen; i++) {
			var tick = stock_data.price[i];
			var val = luxon.DateTime.fromISO(tick.t).toMillis();
			stock_data.price[i].t = val;
			timee[i] = val;
		}

		var ctx = document.getElementById('chart').getContext('2d');
		ctx.canvas.width = 1000;
		ctx.canvas.height = 250;

		var chart = new Chart(ctx, {
			type: 'candlestick',
			data: {
				datasets: [{
					label: 'CHRT - Chart.js Corporation',
					data: stock_data.price,
				},{
					type: 'line',
					data: stock_data.ma20,
					label: '20MA',
					fill: false,
					pointRadius: 0,
					borderWidth: 1,
					borderColor: 'black'
				}],
				labels: timee
			},
			options: {
				tooltips: {
					intersect: false,
					mode: 'index',
					callbacks: {
						label(tooltipItem, data) {
							const dataset = data.datasets[tooltipItem.datasetIndex];
							const point = dataset.data[tooltipItem.index];

							if ( point.o == undefined ) {
								return Chart.defaults.global.tooltips.callbacks.label(tooltipItem, data);
							} else {

								const o = point.o;
								const h = point.h;
								const l = point.l;
								const c = point.c;

								return 'open: ' + o + '  high: ' + h + '  low: ' + l + '  close: ' + c;
							}
						}
					}
				},
				legend: {
					display: false
				}
			}
		});

	</script>
</body>



PLEASE HELP! THANKS!!!!~