var DemoApp = angular.module('DemoApp', ['dx']);
DemoApp.controller('DemoController', function DemoController($scope) {
var store = new DevExpress.data.CustomStore({
load: function() {
return connection.invoke("getAllData");
},
key: "date"
});
$scope.chartOptions = {
dataSource: {
store: store
},
margin: {
right: 30
},
loadingIndicator: {
enabled: true
},
title: "Stock Price",
series: [{
pane: "Price",
argumentField: "date",
type: "candlestick",
aggregation: {
enabled: true,
method: "custom",
calculate: function(e) {
var prices = e.data.map(function(i) {
return i.price;
});
if (prices.length) {
return {
date: e.intervalStart,
open: prices[0],
high: Math.max.apply(null, prices),
low: Math.min.apply(null, prices),
close: prices[prices.length - 1]
};
}
}
}
}, {
pane: "Volume",
name: "Volume",
type: "bar",
argumentField: "date",
valueField: "volume",
color: "red",
aggregation: {
enabled: true,
method: "sum"
}
}],
panes: [{
name: "Price"
}, {
name: "Volume",
height: 80
}],
customizePoint: function(arg) {
if(arg.seriesName === "Volume") {
var point = $("#chart").dxChart("getAllSeries")[0].getPointsByArg(arg.argument)[0].data;
if(point.close >= point.open) {
return { color: "#1db2f5" };
}
}
},
tooltip: {
enabled: true,
shared: true,
argumentFormat: "shortDateShortTime",
contentTemplate: function (pointInfo, element) {
var volume = pointInfo.points.filter(function(point) {
return point.seriesName === "Volume";
})[0];
var prices = pointInfo.points.filter(function(point) {
return point.seriesName !== "Volume";
})[0];
return "<div class='tooltip-template'><div>" + pointInfo.argumentText + "</div>" +
"<div><span>Open: </span>" + Globalize.formatCurrency(prices.openValue, "USD") + "</div>" +
"<div><span>High: </span>" + Globalize.formatCurrency(prices.highValue, "USD") + "</div>" +
"<div><span>Low: </span>" + Globalize.formatCurrency(prices.lowValue, "USD") + "</div>" +
"<div><span>Close: </span>" + Globalize.formatCurrency(prices.closeValue, "USD") + "</div>" +
"<div><span>Volume: </span>" + Globalize.formatNumber(volume.value, { maximumFractionDigits: 0 }) + "</div>";
}
},
crosshair: {
enabled: true,
horizontalLine: { visible: false }
},
zoomAndPan: {
argumentAxis: "both"
},
scrollBar: {
visible: true
},
legend: {
visible: false
},
argumentAxis: {
argumentType: "datetime",
minVisualRangeLength: { minutes: 10 },
visualRange: {
length: "hour"
}
},
valueAxis: {
placeholderSize: 50
}
};
$scope.connectionStarted = false;
var connection = new signalR.HubConnectionBuilder()
.withUrl("https://js.devexpress.com/Demos/NetCore/stockTickDataHub")
.configureLogging(signalR.LogLevel.Information)
.build();
connection.start()
.then(function () {
connection.on("updateStockPrice", function (data) {
store.push([{ type: "insert", key: data.date, data: data }]);
});
$scope.connectionStarted = true;
$scope.$apply();
});
});
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>DevExtreme Demo</title>
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0" />
<link rel="stylesheet" type="text/css" href="https://cdn3.devexpress.com/jslib/19.2.4/css/dx.common.css" />
<link rel="stylesheet" type="text/css" href="https://cdn3.devexpress.com/jslib/19.2.4/css/dx.light.css" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<script>window.jQuery || document.write(decodeURIComponent('%3Cscript src="js/jquery.min.js"%3E%3C/script%3E'))</script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.16/angular.min.js"></script>
<script>window.angular || document.write(decodeURIComponent('%3Cscript src="js/angular.min.js"%3E%3C\/script%3E'))</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/cldrjs/0.4.4/cldr.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/cldrjs/0.4.4/cldr/event.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/cldrjs/0.4.4/cldr/supplemental.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/cldrjs/0.4.4/cldr/unresolved.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/globalize/1.1.1/globalize.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/globalize/1.1.1/globalize/message.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/globalize/1.1.1/globalize/number.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/globalize/1.1.1/globalize/currency.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/globalize/1.1.1/globalize/date.min.js"></script>
<script src="https://cdn3.devexpress.com/jslib/19.2.4/js/dx.all.js"></script>
<script src="js/signalr/signalr-client.js"></script>
<link rel="stylesheet" type="text/css" href="styles.css" />
<script src="index.js"></script>
</head>
<body class="dx-viewport">
<div class="demo-container" ng-app="DemoApp" ng-controller="DemoController">
<div ng-if="connectionStarted">
<div id="chart" dx-chart="chartOptions"></div>
</div>
</div>
</body>
</html>
#chart{
height: 440px;
}
.tooltip-template span {
font-weight: 500;
}