私はHighChartsと Angular のhighcharts-ngディレクティブを使用しています。そして、私が取るほとんどの行動は、価格ラインを消滅させるか、実際には表示しない可能性が高い.
- ブラウザー ウィンドウのサイズを変更して、グラフのサイズを変更します (線が90%消えます) 。
- タイムスパンの変更 (約20%の確率で線が消えます)
- 価格ライン データの変更 (ラインは約10%の確率で消えます)
- チャートへの面グラフの追加または削除
- エラーなし
^ 上記の%は感覚に基づいています:(
^ また、フォーカス タイムライン ナビゲーター内の折れ線グラフも消えることに注意してください。また、グラフにカーソルを合わせると、欠けている線のポイントが表示されます。
以下は、チャートがどのように見えるかです (ただし、フォーカス ラインも下に消えています)。
私が使用しているグラフは、1 つの折れ線グラフ (株価) と他のデータをグラフ化する最大 3 つの面グラフを持つマルチ グラフの一種です。私もhighstocks 4.2.0を使用しています。私たちのアプリは非常に複雑で、plunkr で複製するのは困難です。
これが私のchartConfigです
generateChartObject();
function generateChartObject() {
// Create the chart
vs.chartConfig = {
options: {
ignoreHiddenSeries: false,
credits: { enabled: true, text: 'tickertags' },
legend: {
itemStyle: {
color: "#333333",
cursor: "pointer",
fontSize: "10px",
fontWeight: "normal"
},
enabled: true,
floating: true,
align: 'left',
verticalAlign: 'top',
x: 60
},
chart : {
title: { text: '' },
subtitle: { text: '' },
renderTo: 'chart1',
zoomType: 'x',
events: {
load: function () {
broadcastChartloaded();
vs.chartObject.hideLoading();
}
}
},
scrollbar: {
enabled: false,
liveRedraw: false
},
navigator : {
enabled: true,
adaptToUpdatedData: true,
series : {
// data : quote_data
}
},
rangeSelector: {
enabled: false,
},
tooltip: {
pointFormatter: tooltipFormatter,
shared: true
},
exporting: { enabled: false },
plotOptions: {
series: {
point: {
events: {
click: afterClick,
}
}
},
area: {
stacking: 'normal',
},
column: {
stacking: 'normal',
}
}
},
exporting: { enabled: false },
useHighStocks: true,
xAxis : {
dateTimeLabelFormats : {
hour: '%I %p',
minute: '%I:%M %p'
},
events : {
afterSetExtremes : afterSetExtremes,
setExtremes : setExtremes
},
minRange: 3600 * 1000 // one hour
},
yAxis: [{ // Primary yAxis
labels: {
format: '${value:.2f}',
style: {
color: '#4C73FF',
}
},
title: {
text: 'Price',
style: {
color: '#4C73FF',
}
}
},
{ // Secondary yAxis
gridLineWidth: 0,
title: {
text: 'Mentions',
style: {
color: '#FDE18D'
}
},
labels: {
formatter: volumeFormatter,
style: {
color: '#FDE18D'
}
},
opposite: false
}],
func: function(chart) {
vs.chartObject = chart;
}
};
}
チャートの生成方法:
ステップ 1 価格線を作成する
ここで私の tickersController で、どのティッカーをチャート コントローラーに送信するかをブロードキャストします。
$scope.$emit("display.chart", vm.ticker.ticker);
私の highChartsController はイベントを受け取り、その作業を開始します。
$scope.$on("display.chart", function(event, ticker) {
displayChart(ticker)
.then(function (data) {
// console.log('"displayChart TICKER data returned"',data);
vs.chartObject.addSeries({
zIndex: 1000,
showInLegend: true,
yAxis: 0,
type: 'line',
name: ticker,
color: '#4C73FF',
data: data,
dataGrouping: {
enabled: true
}
}, true);
checkForTags();
}).catch(function(error) {
console.error('error', error);
});
}
);
以下は、API GET を待機する Promise を含む displayChart 関数です (Promise は quote_data のデータを返します)。
function displayChart(ticker) {
console.log('displayChart()');
var deferred = $q.defer(),
promise;
if (ticker === undefined) ticker = 'SPY';
vs.ticker = ticker; // Bugged, sometimes ticker is an Object
vs._ticker = ticker; // Quick fix
symbolUrls = {};
var url = '/app/api/tickers/quotes/'+ticker;
symbolUrls[ticker] = url;
promise = ApiFactory.quotes(buildFullUrl('quotes', url)).then(function (data) {
var quote_data = formatQuotes(data, 'quotes');
// Remove any old chart series:
if (!_.isEmpty(vs.chartObject)) {
while(vs.chartObject.series.length > 0)
vs.chartObject.series[0].remove(true);
}
deferred.resolve(quote_data);
});
return deferred.promise;
}
今私のeventListenerに戻って$scope.$on("display.chart", function(event, ticker) {
displayChart が Promise とデータを返したら、シリーズを追加してから次のように呼び出しますcheckForTags()
。
displayChart(ticker)
.then(function (data) {
// console.log('"displayChart TICKER data returned"',data);
vs.chartObject.addSeries({
zIndex: 1000,
showInLegend: true,
yAxis: 0,
type: 'line',
name: ticker,
color: '#4C73FF',
data: data,
dataGrouping: {
enabled: true
}
}, true);
checkForTags();
ステップ 2、面グラフを取得してグラフ化します。
function checkForTags() {
var tags = TagFactory.retrieveTickerTags('all');
// Up to 3 tags in the tags Array (The Area graphs):
if (tags.length) {
getTickerTags(tags);
}
}
function getTickerTags(tags) {
prepareTags(tags).then(function(data) {
// Once data comes back from prepareTags, the loop below,
// generates up to 3 tag Area Graphs in the chart:
for (var i = data.length - 1; i >= 0; i--) {
vs.chartObject.addSeries({
showInLegend: true,
zIndex: 900,
yAxis: 1,
type: 'area',
// name: term,
color: lookupColors[i],
data: data[i],
dataGrouping: {
enabled: false
}
}, true);
if (i === 0) {
handleRedraw(); // function below
}
}
})
.catch(function(error) {
console.error('error', error);
});
}
function prepareTags(tags) {
var deferred = $q.defer();
var tagsComplete = 0;
var allTags = [];
// Request ALL Tag series quote data:
for (var i=0; i<tags.length; i++) {
var url = '/app/api/twitter/' + tags[i].term_id;
getTagData(url, tags[i].term, term_positions[tags[i].term_id]).then(function(data) {
// Push tag data into allTags Array:
allTags.push( data );
tagsComplete++;
// When loop is complete, resolve all the Promises:
if (tagsComplete === tags.length) {
deferred.resolve(allTags);
}
});
}
return deferred.promise;
}
function getTagData(url, term, i) {
var e = vs.chartObject.xAxis[0].getExtremes();
var final_url = buildFullUrl(url, Math.round(e.min/1000), Math.round(e.max/1000));
// Response returned:
return ApiFactory.quotes(final_url).then(function(data) {
// Formatted data returned:
return formatQuotes(data);
});
}
// Finally the handlRedraw function is called at the end:
function handleRedraw() {
vs.chartObject.hideLoading();
vs.chartObject.redraw();
}
ステップ 3、ブラウザ ウィンドウのサイズを変更します。
以下は、chartController にイベントをブロードキャストするウィンドウ サイズ変更関数です。restoreChartSize がヒットし、最後に changePeriodicity がヒットします。
window.onresize = function(event) {
$scope.$emit("window.resize");
$scope.$emit("restore.chart");
};
function restoreChartSize() {
if (!vs.chartObject.reflowNow) {
vs.chartObject.reflowNow = vs.chartObject.reflowNow = function() {
this.containerHeight = this.options.chart.height || $(this.renderTo).height();
this.containerWidth = this.options.chart.width || $(this.renderTo).width();
this.setSize(this.containerWidth, this.containerHeight, true);
this.hasUserSize = null;
}
}
vs.chartObject.reflowNow();
changePeriodicity(vs.interval);
}
function changePeriodicity(newInterval) {
vs.interval = newInterval;
var rightDate = new Date();
var leftDate = new Date();
if ( newInterval == "hour" ) {
leftDate.setHours(rightDate.getHours()-1);
}
else if ( newInterval == "day" ) {
leftDate.setDate(rightDate.getDate()-1);
}
else if ( newInterval == "week" ) {
leftDate.setDate(rightDate.getDate()-7);
}
else if ( newInterval == "month" ) {
leftDate.setDate(rightDate.getDate()-30);
}
else if ( newInterval == "year" ) {
leftDate.setDate(rightDate.getDate()-365);
}
if (vs.chartObject.xAxis) {
vs.chartObject.showLoading('Loading data...');
vs.chartObject.xAxis[0].setExtremes(leftDate.getTime(), rightDate.getTime());
}
// if (vs.chartObject.loadingShown) {
// handleRedraw();
// }
}
ここでの考えや指示は大歓迎です!