I know highstock not support click to zoom graph
http://www.highcharts.com/docs/chart-concepts/zooming
But I want to click on the graph, the graph will display all screens, including the form "Time updates". How can i do?
For example: http://jsfiddle.net/DuyThoLe/58bzo3vg/17/enter code here
Starting from this Hgihcharts demo - http://jsfiddle.net/gh/get/jquery/1.7.2/highslide-software/highcharts.com/tree/master/samples/highcharts/chart/events-container/
... it is possible to get it to work with your chart: http://jsfiddle.net/6jLg8fg5/1/
Later you wanted to include "Time update" in pop up window, so it is added to div that will change its class (and because of CSS will be displayed on top, like a pop up): http://jsfiddle.net/6jLg8fg5/4/
Next you wanted to be able to prin, export, click legend without popping up or back down the chart. You could postpone (e.g. using setTimeout) pop up effect and check if click is not triggering legend or exporting menu.
Series have legendItemClick event - so first we shuold check that. While printing chart will have afterPrinting and beforePrinting events triggered. For exporting - it is possible to rewrite getChartHTML from exporting module using wrapping (extending Highcharts) - http://jsfiddle.net/6jLg8fg5/5/
JS:
$(function () {
(function (H) {
H.wrap(H.Chart.prototype, 'getChartHTML', function (proceed) {
printing = true;
// Run original proceed method
return this.container.innerHTML;
});
}(Highcharts));
Highcharts.setOptions({
global: {
useUTC: false
}
});
var legendClicked = false,
printing = false; //or exporting
// Create the chart
$('#chart1').highcharts('StockChart', {
chart: {
borderWidth: 0,
height: 283,
width: 660,
events: {
beforePrint: function() {
printing = true;
},
afterPrint: function(){
printing = false;
}
}
},
rangeSelector: {
buttons: [{
count: 1,
type: 'minute',
text: '1M'
}, {
count: 5,
type: 'minute',
text: '5M'
}, {
type: 'all',
text: 'All'
}],
inputEnabled: false,
selected: 0
},
title: {
text: 'Live random data'
},
legend: {
enabled: true
},
exporting: {
enabled: true
},
navigator: {
enabled: true
},
series: [{
events: {
legendItemClick: function () {
legendClicked = true;
}
},
name: 'Random data',
data: (function () {
// generate an array of random data
var data = [],
time = (new Date()).getTime(),
i;
for (i = -999; i <= 0; i += 1) {
data.push([
time + i * 1000,
Math.round(Math.random() * 100)]);
}
return data;
}())
}]
});
//the form action
var updateInterval = 10000;
$("#updateInterval").val(updateInterval).change(function () {
var v = $(this).val();
if (v && !isNaN(+v)) {
updateInterval = +v;
if (updateInterval < 1) {
updateInterval = 1;
} else if (updateInterval > 50000) {
updateInterval = 10000;
}
$(this).val("" + updateInterval);
}
});
function update() {
var series = $('#chart1').highcharts().series[0];
x = (new Date()).getTime(); // current time
y = Math.round(Math.random() * 100);
series.addPoint([x, y], true, true);
setTimeout(update, updateInterval);
}
update();
$('.chart-container').bind('mousedown', function () {
var source = this;
if(!printing) {
setTimeout(function () {
//check if legend was clicked
if (legendClicked) {
legendClicked = false;
} else if ($('.highcharts-contextmenu').css('display') === 'block' || printing) {
//check if context menu is visible
printing = false;
} else {
//else do popup or back to default
$('#chart-with-time-update').toggleClass('modal');
$('.chart', source).highcharts().reflow();
}
}, 150);
}
});
});
CSS:
.main {
width: 400px;
margin: 0 auto;
}
.chart {
min-width: 300px;
max-width: 800px;
height: 300px;
margin: 1em auto;
}
.modal {
position: fixed;
width: 100%;
height: 100%;
top: 0;
left: 0;
background: rgba(0, 0, 0, 0.7);
}
.modal .chart {
height: 90%;
width: 90%;
max-width: none;
}
Finally you needed to make it work with multiple charts - http://jsfiddle.net/6jLg8fg5/13/
(This problem was also discussed on Highcharts forum: http://forum.highcharts.com/highstock-usage/click-on-the-chart-to-zoom-chart-t33714/)
Related
I wanted to use reset zooming button of apexcharts in my project. I wanted to only reset graph after user pressing all button but the page is reloading. Is there any way to remove action of reloading? I don't have much information about apexcharts. I added below example apexchart graph and javascript code. Can you give me idea? Thank you in advance..
$(document).ready(function() {
var options = {
chart: {
height: 400,
type: 'area',
toolbar: {
show: false,
},
events: {
selection: function(chart, e) {
console.log(new Date(e.xaxis.min) )
}
},
stacked: true
},
colors: ['#ef742a','#0f2648'],
dataLabels: {
enabled: false
},
series: [
{
name: '{{ $treeItem['device_title'] }}',
type:'area',
data: []
},
],
fill: {
type: 'gradient',
gradient: {
opacityFrom: 0.6,
opacityTo: 0.2,
gradientToColors:"#1c3d89",
}
},
labels: [],
legend: {
position: 'top',
horizontalAlign: 'right',
show: true,
},
grid: {
yaxis: {
lines: {
show: false,
}
},
padding: {
top: 20,
right: 0,
bottom: 0,
left: 10
},
},
stroke: {
show: true,
curve: 'smooth',
width: 2,
},
}
var chart = new ApexCharts(
document.querySelector("#Chart"),
options
);
chart.render();
function generateDayWiseTimeSeries(baseval, count, yrange) {
var i = 0;
var series = [];
while (i < count) {
var x = baseval;
var y = Math.floor(Math.random() * (yrange.max - yrange.min + 1)) + yrange.min;
series.push([x, y]);
baseval += 86400000;
i++;
}
console.log(series);
return series;
}
var resetCssClasses = function (activeEl) {
var els = document.querySelectorAll("button");
Array.prototype.forEach.call(els, function (el) {
el.classList.remove('active');
});
activeEl.target.classList.add('active')
}
document.querySelector("#chart_all").addEventListener('click', function (e) {
resetCssClasses(e)
chart.updateOptions({
xaxis: {
min: undefined,
max: undefined,
}
})
})
});
It looks like the issue is related to the page reloading after the reset zooming button is pressed. To prevent the page from reloading, you can remove the location.reload() function or use preventDefault() method on the event that triggers the reload. Alternatively, you can use ajax to update the chart's data without reloading the page.
How to use AJAX to update the chart's data:
document.querySelector("#chart_all").addEventListener('click', function (e) {
e.preventDefault(); // prevent the page from reloading
resetCssClasses(e);
// use AJAX to retrieve new data
$.ajax({
type: "GET",
url: "path/to/data",
success: function(data) {
chart.updateSeries([{
data: data
}]);
}
});
});
When the reset zooming button is clicked, the preventDefault() method is used to prevent the page from reloading. Then, an AJAX request is made to a specified URL to retrieve new data. Once the data is successfully retrieved, the updateSeries() method is used to update the chart with the new data.
Replace path/to/data with the actual path to the data you would like to retrieve via ajax, also you may need to add error handling, and you should also check the data format that your endpoint returns and match it with the format that ApexCharts accepts.
I have a Vaadin14-based project with Polymer3 components.
I created a small wrapper for Highcharts HighStock component without using embedded Vaadin Charts.
Now I need to add a stock-tools panel to allow drawing on chart.
All needed .js and .css seemed to be added according to manuals as chart is displayed correctly along with stock-tools panel.
I can see sub-menus, change tools etc.
But I unable to draw anything on chart.
Seems like tool-button click does not turn the chart in drawing mode (style for active button or highcharts-draw-mode are not applied).
Highcharts version doesn't matter as far as I tried to update from 8 to 10 via npm.
Does anybody know the reason why stock-tool events don't work?
Thanks in advance.
The Polymer component code with some cuts is following:
import { html } from '#polymer/polymer/lib/utils/html-tag.js';
import Highcharts from 'highcharts/es-modules/masters/highstock.src.js';
import 'highcharts/es-modules/masters/modules/hollowcandlestick.src.js';
import 'highcharts/es-modules/masters/modules/data.src.js';
import 'highcharts/es-modules/masters/modules/debugger.src.js';
import 'highcharts/es-modules/masters/modules/accessibility.src.js';
import 'highcharts/es-modules/masters/modules/boost.src.js';
import 'highcharts/es-modules/masters/indicators/indicators-all.src.js';
import 'highcharts/es-modules/masters/modules/drag-panes.src.js';
import 'highcharts/es-modules/masters/modules/price-indicator.src.js';
import 'highcharts/es-modules/masters/modules/full-screen.src.js';
import 'highcharts/es-modules/masters/modules/annotations-advanced.src.js';
import 'highcharts/es-modules/masters/modules/stock-tools.src.js';
import 'highcharts/es-modules/masters/modules/heikinashi.src.js';
class StockChartComponent extends PolymerElement {
static get template() {
return html`
<style include="shared-styles shared-chart-styles">
:host {
border: 1px solid red;
width: 100%;
height: 100%;
display: block;
padding: 1em;
}
#container { border: 1px solid blue; }
</style>
<div class='chart stock-chart' id='container'> </div>
`;
}
static get is() {
return 'stock-chart-component';
}
connectedCallback() {
super.connectedCallback();
}
/**this method is called after some initialization on the server-side via executeJS(...) **/
onStockChartUpdate(options) {
var container = this.shadowRoot.querySelector("#container");
if (Highcharts && options && container) {
Highcharts.getJSON('https://demo-live-data.highcharts.com/aapl-ohlcv.json', function (data) {
// split the data set into ohlc and volume
var ohlc = [],
volume = [],
dataLength = data.length,
i = 0;
for (i; i < dataLength; i += 1) {
ohlc.push([
data[i][0], // the date
data[i][1], // open
data[i][2], // high
data[i][3], // low
data[i][4] // close
]);
volume.push([
data[i][0], // the date
data[i][5] // the volume
]);
}
Highcharts.stockChart(container, {
yAxis: [{
labels: {
align: 'left'
},
height: '80%',
resize: {
enabled: true
}
}, {
labels: {
align: 'left'
},
top: '80%',
height: '20%',
offset: 0
}],
tooltip: {
shape: 'square',
headerShape: 'callout',
borderWidth: 0,
shadow: false,
positioner: function (width, height, point) {
var chart = this.chart,
position;
if (point.isHeader) {
position = {
x: Math.max(
// Left side limit
chart.plotLeft,
Math.min(
point.plotX + chart.plotLeft - width / 2,
// Right side limit
chart.chartWidth - width - chart.marginRight
)
),
y: point.plotY
};
} else {
position = {
x: point.series.chart.plotLeft,
y: point.series.yAxis.top - chart.plotTop
};
}
return position;
}
},
series: [{
type: 'ohlc',
id: 'aapl-ohlc',
name: 'AAPL Stock Price',
data: ohlc
}, {
type: 'column',
id: 'aapl-volume',
name: 'AAPL Volume',
data: volume,
yAxis: 1
}],
responsive: {
rules: [{
condition: {
maxWidth: 800
},
chartOptions: {
rangeSelector: {
inputEnabled: false
}
}
}]
}
});
});
}
}
}
customElements.define(StockChartComponent.is, StockChartComponent);
Is it possible to rolloverSlice a pie chart based on seconds without an event?
Is clicking or hovering the part of the chart is the only way to rollover a slice or is there anyway to forloop this by index to show the parts every seconds
Here is my code
<script src="http://www.amcharts.com/lib/3/amcharts.js"></script>
<script src="http://www.amcharts.com/lib/3/pie.js"></script>
<script src="http://www.amcharts.com/lib/3/themes/light.js"></script>
<div id="asset--chart"></div>
<style>
#asset--chart {
width : 100%;
height : 500px;
font-size : 11px;
}
</style>
var pieChartData = [
{
asset: 'Funiture',
marketValue: 50000.00
}, {
asset: 'Cash',
marketValue: 6250.00
}, {
asset: 'Car',
marketValue: 10000.00
}, {
asset: 'Other',
marketValue: 11250.00
}
];
chartAsset = AmCharts.makeChart(
'asset--chart', {
type: 'pie',
dataProvider: pieChartData,
valueField: 'marketValue',
titleField: 'asset',
startEffect: 'easeOutSine',
pulledField: 'pullOut',
//pullOutOnlyOne: true,
// pullOutEffect: 'easeInSine',
responsive: {
enabled: true
},
labelsEnabled: false,
balloon: {
fillAlpha: 0.95,
borderThickness: 1,
borderColor: '#000000',
shadowAlpha: 0,
}
}
);
chartAsset.addListener('rollOverSlice', function(e) {
chartAsset.clickSlice(e.dataItem.index);
});
Here is the fiddle: http://jsfiddle.net/Lrktmwa5/
AmCharts provides manual rollOverSlice and rollOutSlice methods that take the index of the slice where you want to simulate hover and mouseout actions. You can call them in a setInterval or setTimeOut loop depending on your use case:
var counter = 0;
setInterval(function() {
//check if the previous slice is pulled out in order
//to simulate a mouseout action to pull it back in for this chart
if (chartAsset.chartData[(counter + (chartAsset.dataProvider.length - 1)) % chartAsset.dataProvider.length].pulled) {
chartAsset.rollOutSlice((counter + (chartAsset.dataProvider.length - 1)) % chartAsset.dataProvider.length);
}
chartAsset.rollOverSlice(counter);
counter = (counter + 1) % chartAsset.dataProvider.length;
}, 5000);
Demo below:
var pieChartData = [{
asset: 'Funiture',
marketValue: 50000.00
}, {
asset: 'Cash',
marketValue: 6250.00
}, {
asset: 'Car',
marketValue: 10000.00
}, {
asset: 'Other',
marketValue: 11250.00
}];
chartAsset = AmCharts.makeChart(
'asset--chart', {
type: 'pie',
dataProvider: pieChartData,
valueField: 'marketValue',
titleField: 'asset',
startEffect: 'easeOutSine',
pulledField: 'pullOut',
//pullOutOnlyOne: true,
// pullOutEffect: 'easeInSine',
responsive: {
enabled: true
},
labelsEnabled: false,
balloon: {
fillAlpha: 0.95,
borderThickness: 1,
borderColor: '#000000',
shadowAlpha: 0,
}
}
);
chartAsset.addListener('rollOverSlice', function(e) {
chartAsset.clickSlice(e.dataItem.index);
});
chartAsset.addListener('rollOutSlice', function(e) {
chartAsset.clickSlice(e.dataItem.index);
});
var counter = 0;
setInterval(function() {
//check if the previous slice is pulled out in order
//to simulate a mouseout action to pull it back in for this chart
if (chartAsset.chartData[(counter + (chartAsset.dataProvider.length - 1)) % chartAsset.dataProvider.length].pulled) {
chartAsset.rollOutSlice((counter + (chartAsset.dataProvider.length - 1)) % chartAsset.dataProvider.length);
}
chartAsset.rollOverSlice(counter);
counter = (counter + 1) % chartAsset.dataProvider.length;
}, 5000);
body, html {
width: 100%;
height: 100%;
margin: 0;
}
#asset--chart {
width: 100%;
height: 100%;
font-size: 11px;
}
<script src="http://www.amcharts.com/lib/3/amcharts.js"></script>
<script src="http://www.amcharts.com/lib/3/pie.js"></script>
<script src="http://www.amcharts.com/lib/3/themes/light.js"></script>
<div id="asset--chart"></div>
I am trying to create dynamic number of series from UI. Upon selection, backend updates one entry at the time. While the graphs are running fine at most times. At some random time the two series move out of sync as in http://jsfiddle.net/cRgUr/
and come back in sync after few seconds. I have referred following links for resolution but still see the issue.
Chart not moving fluently when adding value to two lines on interval and Updating spline chart two lines on top of eachother
Below is the code snippet :
function getInitialData(series){
var arrayOfValues=[];
$http({
mode:'cors',
method:'GET',
url: '/getData',
headers: { 'Content-Type':'application/json' },
cache: false,
}).success(function(data) {
arrayOfValues.push(/*populated by backend*/); // E.g values for y for number of series selected. If 2 series are to be drawn, at a time this array will contain arrayOfValue[0]= y value for series 1, arrayOfValue[1]=y value for series 2
}
drawgraph(series,arrayOfValues,newWidgetMetrics/*widget selected from UI*/);
} ).error(function(data) {
});
function drawgraph(series,arrayOfValues,newWidgetMetrics1){
var time = (new Date()).getTime();
for(let p=0;p<arrayOfValues.length;p++){
if(p<arrayOfValues.length-1){
series[p].addPoint([time,arrayOfValues[p]] ,false
, (series[0].data.length >= 20));// set false for all series but the last, with an animation where we want the line to start plotting after 20 seconds
}
else{
series[p].addPoint([time,arrayOfValues[p]] , true
, (series[0].data.length >= 20));// set true for only the last series, with an animation where we want the line to start plotting after 20 seconds
}
chart.redraw();
}
arrayOfValues=[];
}
dataSeries=function(){
for(var i=0;i<length;i++){
var obj={};
obj.type="line";
obj.data=getData();
obj.boostThreshold=60;
obj.name=newWidgetLegends[i];
tArray.push(obj);
}
return tArray;
}
func_plot();
function func_plot(){
$(document).ready(function() {
Highcharts.setOptions({
global: {
useUTC: false
}
});
chart=Highcharts.chart(divId, {
chart: {
height:'38%',
zoomType: 'x',
type: 'spline',
animation: Highcharts.svg, // don't animate in old IE
marginRight: 10,
events: {
load: function () {
maxSamples = 60,
counter = 0;
// set up the updating of the chart each second
var ser = this.series;
// setTimeout(function () {
setInterval(function (){
window['arr' + count]=[];
getInitialData(ser);
}, 1000);
}, 2000);
}
}
},
title: {
text: '',
style: {
display: 'none'
}
},
exporting: {
buttons: {
contextButton: {
y:screen.height*-0.02
}
}
},
plotOptions: {
line: {
marker: {
enabled: false
}
},
events: {
legendItemClick: function () {
return false;
}
}
},
xAxis: {
type: 'datetime',
ordinal:false,
labels: {
format: '{value:%M:%S}'
},
tickInterval: 10000,
title: {
text: newWidetXLabel,
marginBottom: 100
}
},
yAxis: {
title: {
text:newWidetYLabel,
min: 0,
max:10
},
plotLines: [{
value: 0,
width: 1,
color: '#808080'
}]
},
legend: {
title: {
text: '',
style: {
fontStyle: 'italic'
}
},
layout: 'horizontal',
align: 'right',
verticalAlign: 'top',
x: -30,
y: -17
},
boost: {
seriesThreshold:2,
useGPUTranslations: true
},
credits: {
enabled: false
},
tooltip: {
formatter: function () {
return Highcharts.dateFormat('%M:%S', this.x) + '<br/>' +
Highcharts.numberFormat(this.y, 2);
}
},
series: dataSeries()
});
});
}
$(window).resize(function() {
height = chart.height,
width = chart.width,
chart.setSize(width, height, doAnimation = false);
});
}
}
}]);
This issue happens because both series are not being drawn at the same moment. Second argument of the addPoint function is a flag that indicates whether the chart should be redrawn immediately after the addition or not. In your code 2 redraws happen instead of one. The update of the second series breaks the animation of the first one (it has no time to finish).
The solution here is to redraw the chart only after the second call of addPoint():
series.addPoint([x, y], false, true);
series2.addPoint([x, y2], true, true);
Live demo: http://jsfiddle.net/kkulig/5y1dacxv/
API reference: https://api.highcharts.com/class-reference/Highcharts.Series#addPoint
I know how to draw vertical line in highcharts. But it's possible only when I click anywhere except upon the series. When I click on the series, no prompt is given. If I click anywhere else in the chart container, then it I get a prompt. Please give me a solution. My attempt so far:
$('#save_line_vertical').click(function(event) {
var label=document.getElementById("line_label_vertical").value;
if(label!=null)
{
var id = 'vertLine' + Math.random();
chart.addPlotLine({
value: axis_value,
color: '#'+(Math.random()*0xEEEEEE<<0).toString(16),
width: 2,
id: id,
label : {
text : label
},
events: {
click: function(e) {
chart.removePlotLine(id);
}
},
});
}
});
Here is my fiddle:
http://jsfiddle.net/das_palash89/3AqM7/
You need to add click event to series object too, with small polishing, see:
plotOptions: {
series: {
events: {
click: function (event) {
var label = prompt('Label for Vertical Line');
if (label != null) {
var chart = this.xAxis;
chart.addPlotLine({
value: chart.toValue(event.x),
color: '#' + (Math.random() * 0xEEEEEE << 0).toString(16),
width: 2,
id: 'vertLine',
zIndex: 9999,
label: {
text: label
}
});
}
}
}
}
},
Demo: http://jsfiddle.net/3AqM7/5/