Edit in JSFiddle

import { CIQ } from "https://jsfiddle.chartiq.com/chart/js/advanced.js";
import "https://jsfiddle.chartiq.com/chart/js/addOns.js";

// Activate the License Key
import getLicenseKey from "https://jsfiddle.chartiq.com/chart/key.js";
getLicenseKey(CIQ);


// example animation code for reference
/*CIQ.Animation =
	function (config) {
		if (!config) throw new Error("Invalid constructor arguments.");
		var stx, animationParameters, easeMachine;
		if (config instanceof CIQ.ChartEngine) {
			// legacy constructor
			stx = arguments[0];
			animationParameters = arguments[1];
			easeMachine = arguments[2];
		} else {
			stx = config.stx;
			animationParameters = config.animationParameters;
			easeMachine = config.easeMachine;
		}
		if (!stx)
			return console.warn(
				"No CIQ.ChartEngine provided. Cannot properly create CIQ.Animation instance"
			);
		var params = {
			stayPut: false,
			ticksFromEdgeOfScreen: 5,
			granularity: 1000000
		};
		animationParameters = CIQ.extend(params, animationParameters);

		if (params.tension) stx.chart.tension = animationParameters.tension;
		stx.tickAnimator =
			easeMachine || new CIQ.EaseMachine(Math.easeOutCubic, 1000);
		var scrollAnimator = new CIQ.EaseMachine(Math.easeInOutCubic, 1000);

		var flashingColors = ["#0298d3", "#19bcfc", "#5dcffc", "#9ee3ff"];
		var flashingColorIndex = 0;
		var flashingColorThrottle = 20;
		var flashingColorThrottleCounter = 0;

		var filterSession = false;
		var nextBoundary = null;

		function initMarketSessionFlags() {
			filterSession = false;
			nextBoundary = null;
		}

		stx.addEventListener(["symbolChange", "layout"], function (obj) {
			initMarketSessionFlags();
		});

		stx.prepend("updateCurrentMarketData", function (
			data,
			chart,
			symbol,
			params
		) {
			if (!chart) chart = this.chart;
			if (
				params &&
				params.fromTrade &&
				(chart.closePendingAnimation || chart.closePendingAnimation === 0)
			) {
				params.finalClose = chart.closePendingAnimation;
			}
		});

		stx.prepend("updateChartData", function (appendQuotes, chart, params) {
			var self = this;
			if (!chart) {
				chart = self.chart;
			}
			if (
				!chart ||
				!chart.defaultChartStyleConfig ||
				chart.defaultChartStyleConfig == "none"
			)
				return;

			if (params !== undefined) {
				if (params.animationEntry || params.secondarySeries) return;
			}

			if (!chart.dataSegment) return;

			function completeLastBar(record) {
				if (!chart.masterData) return;
				for (var md = chart.masterData.length - 1; md >= 0; md--) {
					var bar = chart.masterData[md];
					if (bar.Close || bar.Close === 0) {
						bar.Close = record.Close;
						if (record.LastSize) bar.LastSize = record.LastSize;
						if (record.LastTime) bar.LastTime = record.LastTime;
						self.updateCurrentMarketData({
							Close: bar.Close,
							DT: bar.DT,
							LastSize: bar.LastSize,
							LastTime: bar.LastTime
						});
						self.createDataSet(null, null, { appending: true });
						return;
					}
				}
			}
			function unanimateScroll() {
				if (chart.animatingHorizontalScroll) {
					chart.animatingHorizontalScroll = false;
					self.micropixels = self.nextMicroPixels = self.previousMicroPixels; // <-- Reset self.nextMicroPixels here
					chart.lastTickOffset = 0;
				}
				if (chart.closePendingAnimation !== null) {
					var close = chart.closePendingAnimation;
					chart.closePendingAnimation = null;
					completeLastBar({ Close: close });
				}
			}
			var tickAnimator = self.tickAnimator;
			// These chart types are the only types supported by animation
			var supportedChartType =
				this.mainSeriesRenderer && this.mainSeriesRenderer.supportsAnimation;
			if (supportedChartType) {
				if (!tickAnimator) {
					console.warn(
						"Animation plug-in can not run because the tickAnimator has not been declared. See instructions in animation.js"
					);
					return;
				}

				// If symbol changes then reset all of our variables
				if (this.prevSymbol != chart.symbol) {
					this.prevQuote = 0;
					chart.closePendingAnimation = null;
					this.prevSymbol = chart.symbol;
				}
				unanimateScroll();
				tickAnimator.stop();
				if (appendQuotes.length > 2) {
					return;
				}
			}
			var newParams = CIQ.clone(params);
			if (!newParams) newParams = {};
			newParams.animationEntry = true;
			newParams.bypassGovernor = true;
			newParams.noCreateDataSet = false;
			newParams.appending = true;
			//newParams.allowReplaceOHL = true;
			newParams.firstLoop = true;
			var symbol = this.chart.symbol;
			var period = this.layout.periodicity;
			var interval = this.layout.interval;
			var timeUnit = this.layout.timeUnit;

			function cb(quote, prevQuote, chartJustAdvanced) {
				return function (newData) {
					var newClose = newData.Close;
					if (
						!chart.dataSet.length ||
						symbol != chart.symbol ||
						period != self.layout.periodicity ||
						interval != self.layout.interval ||
						timeUnit != self.layout.timeUnit
					) {
						//console.log ("---- STOP animating: Old",symbol,' New : ',chart.symbol, Date())
						tickAnimator.stop();
						unanimateScroll();
						return; // changed symbols mid animation
					}
					var q = CIQ.clone(quote);
					q.Adj_Close = null; // Don't use this, it will mess up our calculated close
					q.Close =
						Math.round(newClose * animationParameters.granularity) /
						animationParameters.granularity; //<<------ IMPORTANT! Use 1000000 for small price increments, otherwise animation will be in increments of .0001
					//q.Close = Math.round(newClose*chart.roundit)/chart.roundit; // to ensure decimal points don't go out too far for interim values
					if (chartJustAdvanced) {
						if (!q.Open && q.Open !== 0) q.Open = q.Close;
						if (!q.High && q.High !== 0) q.High = Math.max(q.Open, q.Close);
						if (!q.Low && q.Low !== 0) q.Low = Math.min(q.Open, q.Close);
					} else {
						if (quote.Close > prevQuote.High) q.High = q.Close;
						if (quote.Close < prevQuote.Low) q.Low = q.Close;
					}
					if (chart.animatingHorizontalScroll) {
						self.micropixels = newData.micropixels;
						chart.lastTickOffset = newData.lineOffset;
					}
					newParams.updateDataSegmentInPlace = !tickAnimator.hasCompleted;
					//console.log("animating: Old",symbol,' New : ',chart.symbol);
					var updateQuotes = [q];
					// Don't include previous quote if tick mode. It will append, duplicating the quote
					if (chartJustAdvanced && self.layout.interval !== "tick")
						updateQuotes.unshift(prevQuote);
					self.updateChartData(updateQuotes, chart, newParams);
					newParams.firstLoop = false;
					if (tickAnimator.hasCompleted) {
						unanimateScroll();
					}
				};
			}
			if (supportedChartType) {
				var quote = appendQuotes[appendQuotes.length - 1];
				this.prevQuote = this.currentQuote(); // <---- prevQuote logic has been changed to prevent forward/back jitter when more than one tick comes in between animations
				var chartJustAdvanced = false; // When advancing, we need special logic to deal with the open
				var dontScroll = false;
				if (period == 1 && appendQuotes.length == 2) {
					// Don't do this if consolidating
					this.prevQuote = appendQuotes[0];
					var dataSetLength = chart.dataSet.length;
					completeLastBar(this.prevQuote);
					if (dataSetLength == chart.dataSet.length) dontScroll = true;
				}
				if (!quote || !quote.Close || !this.prevQuote || !this.prevQuote.Close)
					return false;

				if (this.extendedHours && chart.market.market_def) {
					// Filter out unwanted sessions
					var dtToFilter = quote.DT;
					if (CIQ.ChartEngine.isDailyInterval(interval)) {
						filterSession = !chart.market.isMarketDate(dtToFilter);
					} else {
						if (!nextBoundary || nextBoundary <= dtToFilter) {
							var session = chart.market.getSession(dtToFilter);
							filterSession =
								session !== "" &&
								(!this.layout.marketSessions ||
									!this.layout.marketSessions[session]);
							nextBoundary = chart.market[
								filterSession ? "getNextOpen" : "getNextClose"
							](dtToFilter);
						}
					}
					if (filterSession) {
						this.draw();
						return false;
					}
				}

				var barSpan = period;
				if (interval == "second" || timeUnit == "second") barSpan *= 1000;
				else if (interval == "minute" || timeUnit == "minute") barSpan *= 60000;
				if (!isNaN(interval)) barSpan *= interval;
				if (interval == "day" || timeUnit == "day")
					chartJustAdvanced = quote.DT.getDate() != this.prevQuote.DT.getDate();
				else if (interval == "week" || timeUnit == "week")
					chartJustAdvanced =
						quote.DT.getDate() >= this.prevQuote.DT.getDate() + 7;
				else if (interval == "month" || timeUnit == "month")
					chartJustAdvanced =
						quote.DT.getMonth() != this.prevQuote.DT.getMonth();
				else
					chartJustAdvanced =
						quote.DT.getTime() >= this.prevQuote.DT.getTime() + barSpan;

				var linearChart =
					!this.mainSeriesRenderer || !this.mainSeriesRenderer.standaloneBars;

				var beginningOffset = 0;
				if (chartJustAdvanced) {
					if (this.animations.zoom.hasCompleted) {
						var candleWidth = this.layout.candleWidth;
						if (chart.scroll <= chart.maxTicks) {
							while (this.micropixels > 0) {
								// If micropixels is larger than a candle then scroll back further
								chart.scroll++;
								this.micropixels -= candleWidth;
							}
						}
						if (chart.scroll <= chart.maxTicks) {
							this.previousMicroPixels = this.micropixels;
							this.nextMicroPixels = this.micropixels + candleWidth;
							beginningOffset = candleWidth * -1;
							if (
								chart.dataSegment.length <
									chart.maxTicks - animationParameters.ticksFromEdgeOfScreen &&
								!animationParameters.stayPut
							) {
								this.nextMicroPixels = this.micropixels;
								chart.scroll++;
							}
							chart.animatingHorizontalScroll = linearChart; // When the chart advances we also animate the horizontal scroll by incrementing micropixels
							chart.previousDataSetLength = chart.dataSet.length;
						} else {
							if (!dontScroll) chart.scroll++;
						}
					} else {
						return false;
					}
				}
				chart.closePendingAnimation = quote.Close;
				var start =
					chartJustAdvanced && !linearChart ? quote.Open : this.prevQuote.Close;
				tickAnimator.run(
					cb(quote, CIQ.clone(this.prevQuote), chartJustAdvanced),
					{
						Close: start,
						micropixels: this.nextMicroPixels,
						lineOffset: beginningOffset
					},
					{ Close: quote.Close, micropixels: this.micropixels, lineOffset: 0 }
				);
				return true; // bypass default behavior in favor of animation
			}
		});

		stx.append("draw", function () {
			if (filterSession) return;
			if (
				this.chart.dataSet &&
				this.chart.dataSet.length &&
				this.mainSeriesRenderer &&
				this.mainSeriesRenderer.supportsAnimation
			) {
				if (flashingColorThrottleCounter % flashingColorThrottle === 0) {
					flashingColorIndex++;
					flashingColorThrottleCounter = 0;
				}
				flashingColorThrottleCounter++;

				var context = this.chart.context;
				var panel = this.chart.panel;
				var currentQuote = this.currentQuote();
				if (!currentQuote) return;
				var price = currentQuote.Close;
				var x = this.pixelFromTick(currentQuote.tick, this.chart);
				if (this.chart.lastTickOffset) x = x + this.chart.lastTickOffset;
				var y = this.pixelFromPrice(price, panel);
				if (
					this.chart.yAxis.left > x &&
					this.chart.yAxis.top <= y &&
					this.chart.yAxis.bottom >= y
				) {
					if (flashingColorIndex >= flashingColors.length)
						flashingColorIndex = 0;
					context.beginPath();
					context.moveTo(x, y);
					context.arc(
						x,
						y,
						2 + flashingColorIndex * 1.07,
						0,
						Math.PI * 2,
						false
					);
					context.fillStyle = flashingColors[flashingColorIndex];
					context.fill();
				}
			}
		});
	};*/

// Declare a CIQ.ChartEngine object. This is the main object for drawing charts.
const stxx = new CIQ.ChartEngine({
  container: document.querySelector(".chartContainer"),
  layout: {
    chartType: 'mountain',
    crosshair: true,
    period: 1,
    interval: 'millisecond',
    candleWidth: 5,
  }
});

// Link an animator to each chart you want to animate by adding a line like this:
new CIQ.Animation(stxx, {
  tension: 0.3
})
// Set tension if you want to soften the curves on a line or mountain chart.

stxx.chart.xAxis.timeUnit = CIQ.MILLISECOND;
stxx.chart.xAxis.futureTicks=false;

let now = new Date();
var sampleData = [{
    "DT": new Date(now.setMilliseconds(8)),
    "Open": 152.13,
    "High": 152.19,
    "Low": 152.08,
    "Close": 152.11,
    "Volume": 4505569
  },
  {
    "DT": new Date(now.setMilliseconds(60)),
    "Open": 151.76,
    "High": 151.83,
    "Low": 151.65,
    "Close": 151.79,
    "Volume": 2799990
  },
  {
    "DT": new Date(now.setMilliseconds(102)),
    "Open": 151.79,
    "High": 151.8,
    "Low": 151.6,
    "Close": 151.75,
    "Volume": 1817706
  },
  {
    "DT": new Date(now.setMilliseconds(103)),
    "Open": 151.74,
    "High": 151.96,
    "Low": 151.74,
    "Close": 151.84,
    "Volume": 2127911
  },
  {
    "DT": new Date(now.setMilliseconds(104)),
    "Open": 151.84,
    "High": 152.03,
    "Low": 151.79,
    "Close": 151.95,
    "Volume": 1640306
  },
  {
    "DT": new Date(now.setMilliseconds(105)),
    "Open": 151.95,
    "High": 152.09,
    "Low": 151.84,
    "Close": 152.07,
    "Volume": 1420396
  },
  {
    "DT": new Date(now.setMilliseconds(106)),
    "Open": 152.07,
    "High": 152.08,
    "Low": 151.87,
    "Close": 151.91,
    "Volume": 1312368
  },
  {
    "DT": new Date(now.setMilliseconds(107)),
    "Open": 151.92,
    "High": 152.02,
    "Low": 151.88,
    "Close": 151.95,
    "Volume": 1351448
  },
  {
    "DT": new Date(now.setMilliseconds(108)),
    "Open": 151.95,
    "High": 152.02,
    "Low": 151.87,
    "Close": 151.98,
    "Volume": 1171601
  },
  {
    "DT": new Date(now.setMilliseconds(109)),
    "Open": 151.97,
    "High": 151.99,
    "Low": 151.72,
    "Close": 151.73,
    "Volume": 1340956
  },
  {
    "DT": new Date(now.setMilliseconds(110)),
    "Open": 151.73,
    "High": 151.85,
    "Low": 151.71,
    "Close": 151.82,
    "Volume": 931909
  },
  {
    "DT": new Date(now.setMilliseconds(111)),
    "Open": 151.81,
    "High": 151.87,
    "Low": 151.68,
    "Close": 151.75,
    "Volume": 864346
  },
  {
    "DT": new Date(now.setMilliseconds(112)),
    "Open": 151.74,
    "High": 151.81,
    "Low": 151.69,
    "Close": 151.73,
    "Volume": 1070323
  },
  {
    "DT": new Date(now.setMilliseconds(113)),
    "Open": 151.73,
    "High": 151.85,
    "Low": 151.71,
    "Close": 151.82,
    "Volume": 789665
  },
  {
    "DT": new Date(now.setMilliseconds(114)),
    "Open": 151.82,
    "High": 151.84,
    "Low": 151.68,
    "Close": 151.84,
    "Volume": 868275
  },
  {
    "DT": new Date(now.setMilliseconds(115)),
    "Open": 151.84,
    "High": 152.01,
    "Low": 151.83,
    "Close": 151.95,
    "Volume": 1160535
  },
  {
    "DT": new Date(now.setMilliseconds(116)),
    "Open": 151.95,
    "High": 152.07,
    "Low": 151.95,
    "Close": 152.03,
    "Volume": 1008658
  },
  {
    "DT": new Date(now.setMilliseconds(117)),
    "Open": 152.03,
    "High": 152.13,
    "Low": 151.99,
    "Close": 152.03,
    "Volume": 974990
  },
  {
    "DT": new Date(now.setMilliseconds(118)),
    "Open": 152.02,
    "High": 152.03,
    "Low": 151.91,
    "Close": 152.01,
    "Volume": 737028
  },
  {
    "DT": new Date(now.setMilliseconds(119)),
    "Open": 152.02,
    "High": 152.03,
    "Low": 151.91,
    "Close": 152.01,
    "Volume": 737028
  },
  {
    "DT": new Date(now.setMilliseconds(120)),
    "Open": 152.13,
    "High": 152.19,
    "Low": 152.08,
    "Close": 152.11,
    "Volume": 4505569
  },
  {
    "DT": new Date(now.setMilliseconds(121)),
    "Open": 151.76,
    "High": 151.83,
    "Low": 151.65,
    "Close": 151.79,
    "Volume": 2799990
  },
  {
    "DT": new Date(now.setMilliseconds(122)),
    "Open": 151.79,
    "High": 151.8,
    "Low": 151.6,
    "Close": 151.75,
    "Volume": 1817706
  },
  {
    "DT": new Date(now.setMilliseconds(123)),
    "Open": 151.74,
    "High": 151.96,
    "Low": 151.74,
    "Close": 151.84,
    "Volume": 2127911
  },
  {
    "DT": new Date(now.setMilliseconds(124)),
    "Open": 151.84,
    "High": 152.03,
    "Low": 151.79,
    "Close": 151.95,
    "Volume": 1640306
  },
  {
    "DT": new Date(now.setMilliseconds(125)),
    "Open": 151.95,
    "High": 152.09,
    "Low": 151.84,
    "Close": 152.07,
    "Volume": 1420396
  },
  {
    "DT": new Date(now.setMilliseconds(126)),
    "Open": 152.07,
    "High": 152.08,
    "Low": 151.87,
    "Close": 151.91,
    "Volume": 1312368
  },
  {
    "DT": new Date(now.setMilliseconds(127)),
    "Open": 151.92,
    "High": 152.02,
    "Low": 151.88,
    "Close": 151.95,
    "Volume": 1351448
  },
  {
    "DT": new Date(now.setMilliseconds(128)),
    "Open": 151.95,
    "High": 152.02,
    "Low": 151.87,
    "Close": 151.98,
    "Volume": 1171601
  },
  {
    "DT": new Date(now.setMilliseconds(129)),
    "Open": 151.97,
    "High": 151.99,
    "Low": 151.72,
    "Close": 151.73,
    "Volume": 1340956
  },
  {
    "DT": new Date(now.setMilliseconds(130)),
    "Open": 152.13,
    "High": 152.19,
    "Low": 152.08,
    "Close": 152.11,
    "Volume": 4505569
  },
  {
    "DT": new Date(now.setMilliseconds(131)),
    "Open": 151.76,
    "High": 151.83,
    "Low": 151.65,
    "Close": 151.79,
    "Volume": 2799990
  },
  {
    "DT": new Date(now.setMilliseconds(132)),
    "Open": 151.79,
    "High": 151.8,
    "Low": 151.6,
    "Close": 151.75,
    "Volume": 1817706
  },
  {
    "DT": new Date(now.setMilliseconds(133)),
    "Open": 151.74,
    "High": 151.96,
    "Low": 151.74,
    "Close": 151.84,
    "Volume": 2127911
  },
  {
    "DT": new Date(now.setMilliseconds(134)),
    "Open": 151.84,
    "High": 152.03,
    "Low": 151.79,
    "Close": 151.95,
    "Volume": 1640306
  },
  {
    "DT": new Date(now.setMilliseconds(135)),
    "Open": 151.95,
    "High": 152.09,
    "Low": 151.84,
    "Close": 152.07,
    "Volume": 1420396
  },
  {
    "DT": new Date(now.setMilliseconds(136)),
    "Open": 152.07,
    "High": 152.08,
    "Low": 151.87,
    "Close": 151.91,
    "Volume": 1312368
  },
  {
    "DT": new Date(now.setMilliseconds(137)),
    "Open": 151.92,
    "High": 152.02,
    "Low": 151.88,
    "Close": 151.95,
    "Volume": 1351448
  },
  {
    "DT": new Date(now.setMilliseconds(138)),
    "Open": 151.95,
    "High": 152.02,
    "Low": 151.87,
    "Close": 151.98,
    "Volume": 1171601
  },
  {
    "DT": new Date(now.setMilliseconds(139)),
    "Open": 151.97,
    "High": 151.99,
    "Low": 151.72,
    "Close": 151.73,
    "Volume": 1340956
  }
];

stxx.loadChart("TEST", sampleData, function() {
  streamSimulation();
});

/******************* Stream simulation for demo purposes only ************************/
/************************************************************************************/
/************************************************************************************/
/************************************************************************************/
function streamSimulation() {
  let price = 151.73;

  // if there is something in the masterData use the last element as the basis for our random seed
  if (stxx.chart.masterData.length) {
    price = stxx.chart.masterData[stxx.chart.masterData.length - 1].Close;
  }

  let change = (price * .02) * Math.random() - (price * .01); // random between +/-1% of current price
  price = price + parseFloat(change.toFixed(2));
  let volume = Math.floor(Math.random() * 10) + 1
  stxx.updateChartData({
    "Last": price,
    "Volume": volume
  }, null, {
    bypassGovernor: true
  });
  setTimeout(streamSimulation, 500);
}
<link rel="stylesheet" type="text/css" href="https://jsfiddle.chartiq.com/chart/css/stx-chart.css" media="screen" />

<div class="chartContainer" style="width:100%;height:400px;position:relative;"></div>

<!--[if IE 8]><script>alert("This template is not compatible with IE8");</script><![endif]-->