Highcharts - Change value of text box when drilling down through chart - javascript

Tricky one to explain this so please bear with me.
I have this Large Tree Map created with Highcharts:
http://jsfiddle.net/mb3hu1px/2/
var data = {
"ARS": {
"01To03Years": {
"N": {
"ARGENTINA": 951433
}
},
"Above05Years": {
"N": {
"ARGENTINA": 3719665
}
}
},
"CNY": {
"03To05Years": {
"N": {
"CHINA": 162950484
}
}
},
"COP": {
"Above05Years": {
"N": {
"COLOMBIA": 323390000
}
}
},
"EUR": {
"01To03Years": {
"Y": {
"BELGIUM": 393292575
}
}
}
},
points = [],
currencyPoints,
currencyVal,
currencyI = 0,
periodPoints,
periodI,
yesOrNoPoints,
yesOrNoI,
currency,
period,
yesOrNo,
mil,
causeMil,
causeMilI,
causeName = {
'N': 'Country Name',
'Y': 'Country Name'
};
for (currency in data) {
if (data.hasOwnProperty(currency)) {
currencyVal = 0;
currencyPoints = {
id: 'id_' + currencyI,
name: currency,
color: Highcharts.getOptions().colors[currencyI]
};
periodI = 0;
for (period in data[currency]) {
if (data[currency].hasOwnProperty(period)) {
periodPoints = {
id: currencyPoints.id + '_' + periodI,
name: period,
parent: currencyPoints.id
};
points.push(periodPoints);
yesOrNoI = 0;
for (yesOrNo in data[currency][period]) {
if (data[currency][period].hasOwnProperty(yesOrNo)) {
yesOrNoPoints = {
id: periodPoints.id + '_' + yesOrNoI,
name: yesOrNo,
parent: periodPoints.id,
};
causeMilI = 0;
for (mil in data[currency][period][yesOrNo]) {
if (data[currency][period][yesOrNo].hasOwnProperty(mil)) {
causeMil = {
id: yesOrNoPoints.id + '_' + causeMilI,
name: mil,
parent: yesOrNoPoints.id,
value: Math.round(+data[currency][period][yesOrNo][mil])
};
currencyVal += causeMil.value;
points.push(causeMil);
causeMilI = causeMilI + 1;
}
}
points.push(yesOrNoPoints);
yesOrNoI = yesOrNoI + 1;
}
}
periodI = periodI + 1;
}
}
currencyPoints.value = Math.round(currencyVal / periodI);
points.push(currencyPoints);
currencyI = currencyI + 1;
}
}
Highcharts.chart('container', {
series: [{
type: 'treemap',
layoutAlgorithm: 'squarified',
allowDrillToNode: true,
animationLimit: 1000,
dataLabels: {
enabled: false
},
levelIsConstant: false,
levels: [{
level: 1,
dataLabels: {
enabled: true
},
borderWidth: 3
}],
data: points
}],
title: {
text: ''
}
});
#container {
min-width: 300px;
max-width: 600px;
margin: 0 auto;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://code.highcharts.com/highcharts.js"></script>
<script src="https://code.highcharts.com/modules/heatmap.js"></script>
<script src="https://code.highcharts.com/modules/treemap.js"></script>
<div id="container"></div>
<textarea name="text" id="text" cols="30" rows="10"></textarea>
And as you can see there is also a text area underneath.
What I want is for every level that is clicked through on the chart, the text area updates with some random text.
So for example on the first drill down, the text area could literally just print out level 1, the second drill down print level 2 etc. etc.
If anyone needs anything else from my end please let me know.
Many thanks:)

You can do this several ways. Here is how to do it with plotOptions.series.point.events.click. What you need to do is capture the point click and render some text. As you do not describe what text to show this will just update the textarea with the clicked point's properties name and value.
Highcharts.chart('container', {
series: [{
point: {
events: {
click: function() {
var thePointName = this.name,
thePointValue = this.value;
$('#text').val(function(_, val) {
return 'Category: ' + thePointName + ', value: ' + thePointValue;
});
}
}
},
type: 'treemap',
layoutAlgorithm: 'squarified',
allowDrillToNode: true,
animationLimit: 1000,
dataLabels: {
enabled: false
},
levelIsConstant: false,
levels: [{
level: 1,
dataLabels: {
enabled: true
},
borderWidth: 3
}],
data: points
}],
title: {
text: ''
}
});
Live example.

Related

Does the Chart.js tooltip not work with logarithmic or the Cartesian Time axis?

with my current configs, I can't get tooltips to appear. I am using the latest version of Chart.js, with the latest luxon, and the luxon-chartjs plugin via cdn.
i am using a logarithmic Y axis and cartesian timeline x-axis
i can only get a tooltip to appear when I include a blank callback for label. However, that tooltip that appears only has the unformatted date of the datapoint and no other info. when i ask the label callback to return something, nothing is displayed... when i include a blank callback for title or return anything in the title callback, this works and is displayed. i have hacked together a tooltip but in previous versions I've had no issue with the chart automagically creating these for me.
here is my current code and the working fiddle
let maxArray, correctArray, incorrectArray, objectArray
let yourImage = new Image()
yourImage.src = `https://res.cloudinary.com/behaviorreportcard/image/upload/w_10,h_18,c_scale/v1623785517/Untitled_10_qbwmx4.png`;
let ctx = document.getElementById('myChart').getContext('2d');
Chart.defaults.font.size = '10px';
Chart.defaults.plugins.tooltip.enabled = true
const Interval = luxon.Interval,
DateTime = luxon.DateTime,
Duration = luxon.Duration;
let minTime = "2017-01-19",
maxTime = "2017-04-01",
start = DateTime.fromISO(minTime),
end = DateTime.fromISO(maxTime),
duration = Duration.fromObject({
days: 1
});
function getStart() {
let newStart
if (start.weekday != 7) {
return start.minus({
days: start.weekday
}).toFormat("yyyy-MM-dd")
} else {
return start.toFormat("yyyy-MM-dd")
}
}
let emptyArray = Interval.fromDateTimes(start, end).splitBy(duration).map(t => ({
date: t.s.toFormat("yyyy-MM-dd"),
correct: null,
incorrect: null
}));
let incomingData = [{
date: '2017-01-01',
correct: 10,
incorrect: 20
},
{
date: '2017-01-02',
correct: 10,
incorrect: 0.09
},
{
date: '2017-01-03',
correct: 0.9,
incorrect: null
}, {
date: '2017-01-04',
correct: 3,
incorrect: 0.09
}, {
date: '2017-01-27',
correct: 5,
incorrect: 0.09
}, {
date: '2017-01-28',
correct: 10,
incorrect: null
}, {
date: '2017-02-19',
correct: null,
incorrect: 50
}, {
date: '2017-02-20',
correct: 75,
incorrect: 50
}, {
date: '2017-02-28',
correct: 60,
incorrect: 0.085
}, {
date: '2017-03-01',
correct: 75,
incorrect: null
}, {
date: '2017-03-02',
correct: 10,
incorrect: null
}
]
let returns = []
emptyArray.forEach(x => {
let objToReplace = incomingData.find(o => o.date === x.date)
let objIndex = incomingData.indexOf(objToReplace);
if (objIndex != -1) {
returns.push(incomingData[objIndex])
} else {
returns.push(x)
}
})
let dates = []
let corrects = []
let incorrects = []
let nulls = []
let nullVal = 0.025
returns.forEach(x => {
dates.push(x.date)
if (x.correct != null && x.incorrect != null) {
nulls.push(null)
} else if (x.correct == null && x.incorrect != null) {
nulls.push(nullVal)
}
if (x.incorrect == null) {
incorrects.push(null)
} else {
incorrects.push(x.incorrect)
}
if (x.correct == null) {
corrects.push(null)
} else {
corrects.push(x.correct)
}
})
function returnList(key) {
return returns.map(x => {
return x[key]
})
}
function returnNulls() {
let list = []
returns.forEach(x => {
if ((x.correct != null && x.incorrect == null) || (x.correct == null && x.incorrect != null)) {
list.push(nullVal)
} else {
list.push(null)
}
})
return list
}
console.log(returnNulls())
var myChart = new Chart(ctx, {
type: 'line',
data: {
labels: returnList('date'),
datasets: [{
label: 'none',
data: returnNulls(),
spanGaps: false,
pointStyle: yourImage,
},
{
label: 'Corrects',
data: returnList('correct'),
borderWidth: 1,
pointRadius: 5,
spanGaps: false,
fill: false,
borderColor: 'green',
pointStyle: 'circle'
},
{
label: 'Incorrects',
data: returnList('incorrect'),
fill: false,
spanGaps: false,
borderColor: 'red',
pointStyle: 'triangle',
pointRadius: 5,
borderWidth: 1
}
]
},
options: {
events: ['mousemove', 'mouseout', 'click', 'touchstart', 'touchmove'],
interaction: {
mode: 'nearest'
},
plugins: {
tooltip: {
enabled: true,
callbacks: {
label: function(item) {},
title: function(item) {
let date = item[0].label.split(',').slice(0, 2).join(',')
let dataSet = item[0].dataset.label
if (dataSet == 'none') {
return
}
return date + '\n' + dataSet
}
}
},
legend: {
display: true,
position: 'bottom',
labels: {
filter: (x, y) => {
if (!x.text.includes('none')) {
return x
}
},
usePointStyle: 'true',
fontColor: 'black',
fontSize: 12
}
},
title: {
display: true,
text: 'Your daily average results for chapter __',
fontColor: 'black',
fontSize: 18,
}
},
scales: {
x: {
ticks: {
font: {
size: 12
}
},
min: getStart(),
max: '2017-03-31',
type: 'time',
time: {
unit: 'day',
stepSize: 7
}
},
y: {
type: 'logarithmic',
max: 100,
min: 0.01,
ticks: {
autoSkip: false,
callback: function(value,
index,
values) {
switch (value) {
case 1:
return '1 per minute';
case 0.1:
return '.1/min';
case 0.01:
return '.01/min';
case 0.001:
return '.001/min';
case 10:
return '10 per min';
case 100:
return '100 per min';
case 1000:
return '1000 per min';
}
},
}
},
},
},
}
);
the HTML
<div id='chart' class='chart' width='400px' height='100%'>
<canvas id="myChart" class='chart' ></canvas>
</div>
and the scripts I'm calling out to
https://cdn.jsdelivr.net/npm/chart.js#3.3.2/dist/chart.min.js
https://cdnjs.cloudflare.com/ajax/libs/luxon/1.27.0/luxon.min.js
https://cdn.jsdelivr.net/npm/chartjs-adapter-luxon#0.2.1

Highmaps with rich information in separate container

I use highmaps with "Rich information on click" in a json format. For this I used a previously existing example. However, there are a few parts that I would like to add.
Separate container in which the extra information (countryChart) is
displayed instead of a single container in which both the map and
the extra information are shown Solution given by ppotaczek
Is it possible to display the total per category if no country is selected. In the example below, this means that in (Countrychart)
graph, cat1: 14, cat2: 3 and cat3: 15 (Canada, US and India added
together) are shown. Solution given by ppotaczek
The flags are not displayed, I cannot figure out why this is. Solution given by Emad
In this example I have made a start on the graph hopefully this is a good basis for the extra functionality.
$.ajax({
url: 'https://cdn.rawgit.com/highcharts/highcharts/v6.0.4/samples/data/world-population-history.csv',
success: function() {
var jsondata = {
"data": [{
"value": "8",
"code": "in",
"name": "india",
"testdata": [{
"vcount": "3"
}, {
"vcount": null
}, {
"vcount": "5"
}]
}, {
"value": "15",
"code": "us",
"name": "united states",
"testdata": [{
"vcount": "9"
}, {
"vcount": "2"
}, {
"vcount": "4"
}]
}, {
"value": "9",
"code": "ca",
"name": "canada",
"testdata": [{
"vcount": "2"
}, {
"vcount": "1"
}, {
"vcount": "6"
}]
}]
}
var mapChart;
var countryChart;
var graphdata = [];
var graphdataf = [];
var valuecount;
var countries = {};
$.each(jsondata.data, function(i, item) {
var graphval = [];
var value = item.value;
var code = item.code;
var name = item.name;
graphval.push(code);
graphval.push(value);
graphdata.push(graphval);
$.each(item.testdata, function(j, itemval) {});
countries[item.code] = {
name: item.name,
code3: item.code,
data: item.testdata
};
});
var data = [];
for (var code3 in countries) {
if (countries.hasOwnProperty(code3)) {
$.each(countries[code3].data, function(j, itemval) {
//var graphvaldata = [];
var value = itemval.vcount;
data.push({
name: countries[code3].name,
code3: code3,
value: value,
});
});
}
}
// Wrap point.select to get to the total selected points
Highcharts.wrap(Highcharts.Point.prototype, 'select', function(proceed) {
proceed.apply(this, Array.prototype.slice.call(arguments, 1));
var points = mapChart.getSelectedPoints();
if (points.length) {
if (points.length === 1) {
$('#info #flag').attr('class', 'flag ' + points[0].flag);
$('#info h2').html(points[0].name);
} else {
$('#info #flag').attr('class', 'flag');
$('#info h2').html('Comparing countries');
}
$('#info .subheader').html('<h4>Historical population</h4><small><em>Shift + Click on map to compare countries</em></small>');
if (!countryChart) {
countryChart = Highcharts.chart('country-chart', {
chart: {
height: 250,
spacingLeft: 0
},
credits: {
enabled: false
},
title: {
text: null
},
subtitle: {
text: null
},
xAxis: {
tickPixelInterval: 50,
crosshair: true,
categories: ['cat1', 'cat2', 'cat3']
},
yAxis: {
title: null,
opposite: true
},
tooltip: {
split: true
},
plotOptions: {
series: {
animation: {
duration: 500
},
marker: {
enabled: false
}
}
}
});
}
$.each(points, function(i, point) {
var data,
dataRaw = countries[point['hc-key']].data;
if (dataRaw) {
data = dataRaw.map((p) => parseInt(p.vcount));
}
// Update
if (countryChart.series[i]) {
countryChart.series[i].update({
name: this.name,
data: data,
type: points.length > 1 ? 'column' : 'column'
}, false);
} else {
countryChart.addSeries({
name: this.name,
data: data,
type: points.length > 1 ? 'column' : 'column'
}, false);
}
});
while (countryChart.series.length > points.length) {
countryChart.series[countryChart.series.length - 1].remove(false);
}
countryChart.redraw();
} else {
$('#info #flag').attr('class', '');
$('#info h2').html('');
$('#info .subheader').html('');
if (countryChart) {
countryChart = countryChart.destroy();
}
}
});
// Initiate the map chart
mapChart = Highcharts.mapChart('container', {
title: {
text: 'Population history by country'
},
subtitle: {
text: 'Source: The World Bank'
},
mapNavigation: {
enabled: true,
buttonOptions: {
verticalAlign: 'bottom'
}
},
colorAxis: {
type: 'logarithmic',
endOnTick: false,
startOnTick: false,
minColor: '#fff',
maxColor: '#3D1C5C',
min: 5,
max: 15,
},
tooltip: {
footerFormat: '<span style="font-size: 10px">(Click for details)</span>'
},
credits: {
enabled: false
},
series: [{
data: graphdata,
mapData: Highcharts.maps['custom/world'],
joinBy: 'hc-key',
name: 'Total Play',
allowPointSelect: true,
cursor: 'pointer',
states: {
select: {
color: '#a4edba',
borderColor: 'black',
dashStyle: 'shortdot'
}
}
}]
});
}
});
* {
font-family: sans-serif;
}
#wrapper {
height: 500px;
width: 1000px;
margin: 0 auto;
padding: 0;
overflow: visible;
}
#container {
float: left;
height: 500px;
width: 700px;
margin: 0;
}
#info {
float: left;
width: 270px;
padding-left: 20px;
margin: 100px 0 0 0;
border-left: 1px solid silver;
}
#info h2 {
display: inline;
font-size: 13pt;
}
#info .f32 .flag {
vertical-align: bottom !important;
}
#info h4 {
margin: 1em 0 0 0;
}
#media screen and (max-width: 920px) {
#wrapper,
#container,
#info {
float: none;
width: 100%;
height: auto;
margin: 0.5em 0;
padding: 0;
border: none;
}
}
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
<script src="https://code.highcharts.com/highcharts.js"></script>
<script src="https://code.highcharts.com/maps/modules/map.js"></script>
<script src="https://code.highcharts.com/mapdata/custom/world.js"></script>
<!-- Flag sprites service provided by Martijn Lafeber, https://github.com/lafeber/world-flags-sprite/blob/master/LICENSE -->
<link rel="stylesheet" type="text/css" href="//github.com/downloads/lafeber/world-flags-sprite/flags32.css" />
<div id="wrapper">
<div id="container"></div>
<div id="info">
<span class="f32"><span id="flag"></span></span>
<h2></h2>
<div class="subheader">Click countries to view history</div>
<div id="country-chart"></div>
</div>
</div>
Thanks in advance for your help!
I can aswer to your third question : The flags are not displayed, I cannot figure out why this is.
The problem is with this line :
$('#info #flag').attr('class', 'flag ' + points[0].flag);
There is no flag property in points object, you can change it to this :
$('#info #flag').attr('class', 'flag ' + points[0]["hc-key"]);
And you will have the flag now.
https://jsfiddle.net/vq26m8nb/7/
As to your questions:
Both charts are already in separate containers. You can remove the div with 'wrapper' id to split them so that they do not appear side by side. Check this example: https://jsfiddle.net/BlackLabel/8jo7vzty/
Yes, for example you can call select on some point with an additional argument and sum the data in the wrapped select method (depending on that additional argument).
if (points.length) {
...
if (arguments[3]) {
totalData = [];
Highcharts.objectEach(countries, function(el){
el.data.forEach(function(val, i){
if (totalData[i]) {
totalData[i] += parseInt(val.vcount)
} else {
totalData[i] = parseInt(val.vcount);
}
});
});
$('#info h2').html('Total data');
countryChart.series[0].setData(totalData);
mapChart.series[0].points[0].select(false, false, true);
}
} else if (!arguments[3]) {
$('#info #flag').attr('class', '');
$('#info h2').html('');
$('#info .subheader').html('');
if (countryChart) {
countryChart = countryChart.destroy();
}
}
...
mapChart = Highcharts.mapChart('container', ...);
mapChart.series[0].points[0].select(true, false, true);
Live demo: https://jsfiddle.net/BlackLabel/mg7x3kje/
The flags are not displayed because your points do not have flag property. You can add them in the way as #Emad Dehnavi suggested.

How to get total of highcharts multiple series

With the Highcharts value-in-legend plugin http://www.highcharts.com/plugin-registry/single/10/Value-In-Legend, I have been able to kind of implement a sort of multiple series total, but I do not understand how to get a total for a clicked y-axis point.
For example when I click, one day I will get the 3 separate series numbers, but I would like to get a total somehow as well, but I only know the y points on load and the visible y-points on redraw. I think the difficulty is getting the total of the 3 series points versus getting the individual point's value.
$(function() {
// Start the standard Highcharts setup
var seriesOptions = [],
yAxisOptions = [],
seriesCounter = 0,
names = ['MSFT', 'AAPL', 'GOOG'],
colors = Highcharts.getOptions().colors;
$.each(names, function(i, name) {
$.getJSON('http://www.highcharts.com/samples/data/jsonp.php?filename=' + name.toLowerCase() + '-c.json&callback=?', function(data) {
seriesOptions[i] = {
name: name,
data: data
};
// As we're loading the data asynchronously, we don't know what order it will arrive. So
// we keep a counter and create the chart when all the data is loaded.
seriesCounter++;
if(seriesCounter == names.length) {
createChart();
}
});
});
// create the chart when all data is loaded
function createChart() {
$('#container').highcharts('StockChart', {
chart: {
events: {
load: function(event) {
console.log('load');
var total = 0;
for(var i = 0, len = this.series[0].yData.length; i < len; i++) {
total += this.series[0].yData[i];
}
totalText_posts = this.renderer.text('Total: ' + total, this.plotLeft, this.plotTop - 35).attr({
zIndex: 5
}).add()
},
redraw: function(chart) {
console.log('redraw');
console.log(totalText_posts);
var total = 0;
for(var i = 0, len = this.series[0].yData.length; i < len; i++) {
if(this.series[0].points[i] && this.series[0].points[i].visible) total += this.series[0].yData[i];
}
totalText_posts.element.innerHTML = 'Total: ' + total;
}
}
},
rangeSelector: {
selected: 4
},
yAxis: {
labels: {
formatter: function() {
return(this.value > 0 ? '+' : '') + this.value + '%';
}
},
plotLines: [{
value: 0,
width: 2,
color: 'silver'
}]
},
legend: {
enabled: true,
floating: true,
align: 'left',
verticalAlign: 'top',
y: 35,
labelFormat: '<span style="color:{color}">{name}</span>: <b>{point.y:.2f} USD</b> ({point.change:.2f}%)<br/>',
borderWidth: 0
},
plotOptions: {
series: {
compare: 'percent',
cursor: 'pointer',
point: {
events: {
click: function () {
alert('Category: ' + this.category + ', value: ' + this.y);
}
}
}
}
},
series: seriesOptions
});
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="http://code.highcharts.com/stock/highstock.src.js"></script>
<script src="http://code.highcharts.com/stock/modules/exporting.js"></script>
<script src="https://rawgithub.com/highslide-software/value-in-legend/master/value-in-legend.js"></script>
<div id="container" style="height: 400px; min-width: 500px"></div>
I was able to find out a way to put the total result as a title in a multi series by reading the source code for the Highcharts value-in-legend plugin https://rawgithub.com/highslide-software/value-in-legend/master/value-in-legend.js.
$(function () {
var seriesOptions_likes = [],
seriesCounter_likes = 0,
names_likes = ['MSFT', 'AAPL', 'GOOG'],
totalText_likes = 0;
/**
* Create the chart when all data is loaded
* #returns {undefined}
*/
function createLikesChart() {
Highcharts.stockChart('container_likes', {
chart: {
},
rangeSelector: {
selected: 4
},
title: {
text: 'Total Results: '
},
yAxis: {
labels: {
formatter: function () {
return (this.value > 0 ? ' + ' : '') + this.value + '%';
}
},
plotLines: [{
value: 0,
width: 2,
color: 'silver'
}]
},
plotOptions: {
series: {
compare: 'percent',
showInNavigator: true
}
},
tooltip: {
pointFormat: '<span style="color:{series.color}">{series.name}</span>: <b>{point.y}</b> ({point.change}%)<br/>',
valueDecimals: 2,
split: true
},
series: seriesOptions_likes,
legend: {
enabled: true,
floating: true,
align: 'left',
verticalAlign: 'top',
y: 65,
borderWidth: 0
},
});
}
$.each(names_likes, function (i, name) {
$.getJSON('https://www.highcharts.com/samples/data/jsonp.php?filename=' + name.toLowerCase() + '-c.json&callback=?', function (data) {
seriesOptions_likes[i] = {
name: name,
data: data
};
// As we're loading the data asynchronously, we don't know what order it will arrive. So
// we keep a counter and create the chart when all the data is loaded.
seriesCounter_likes += 1;
if (seriesCounter_likes === names_likes.length) {
createLikesChart();
}
});
});
});
(function (H) {
H.Series.prototype.point = {}; // The active point
H.Chart.prototype.callbacks.push(function (chart) {
$(chart.container).bind('mousemove', function () {
var legendOptions = chart.legend.options,
hoverPoints = chart.hoverPoints,
total = 0;
if (!hoverPoints && chart.hoverPoint) {
hoverPoints = [chart.hoverPoint];
}
if (hoverPoints) {
var total = 0,
ctr = 0;
H.each(hoverPoints, function (point) {
point.series.point = point;
total += point.y;
});
H.each(chart.legend.allItems, function (item) {
item.legendItem.attr({
text: legendOptions.labelFormat ?
H.format(legendOptions.labelFormat, item) :
legendOptions.labelFormatter.call(item)
});
});
chart.legend.render();
chart.title.update({ text: 'Total Results: ' + total.toFixed(2) });
}
});
});
// Hide the tooltip but allow the crosshair
H.Tooltip.prototype.defaultFormatter = function () { return false; };
}(Highcharts));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://code.highcharts.com/stock/highstock.js"></script>
<script src="https://code.highcharts.com/stock/modules/exporting.js"></script>
<div id="container_likes" style="height: 400px; min-width: 600px"></div>

FlotChart do not work zooming mode

I have following example: http://jsfiddle.net/ondra15/7mb8K/1/.
I want to have together two example (multiple axes and zooming). Example zooming do not work correct - if I indicate some data in chart for zooming - do not work. Nothing happens.
Original Zooming (correct) solution works here http://www.flotcharts.org/flot/examples/zooming/index.html
Can any some idea for my code? Thanks
code
Hi I managed to get it working using code from an example I found here. I will update your jsfiddle too:
<script type="text/javascript">
var datasets = { ... };
data = null;
function plotByChoice(doAll) {
data = [];
if (doAll != null) {
$.each(datasets, function (key, val) {
data.push(val);
});
}
else {
$('#legend .legendCB').each(
function () {
if (this.checked) {
data.push(datasets[this.id]);
}
else {
data.push({ label: this.id, data: [] })
}
}
);
}
$.plot($("#placeholder"), data, {
yaxes: [{ min: 0 }, { position: "right" }],
xaxis: { tickDecimals: 0 },
legend: {
container: legend,
labelFormatter: function (label, series) {
var cb = '<input class="legendCB" type="checkbox" ';
if (series.data.length > 0) {
cb += 'checked="true" ';
}
cb += 'id="' + label + '" /> ';
cb += label;
return cb;
}
}, selection: { mode: "x" }
});
$('#legend').find("input").click(function () { setTimeout(plotByChoice, 100); });
}
plotByChoice(true);
// Create the overview plot
var overview = $.plot("#overview", data, {
legend: {
show: false
},
series: {
lines: {
show: true,
lineWidth: 1
},
shadowSize: 0
},
xaxis: {
ticks: 4
},
yaxes: [{ min: 0 }, { position: "right" }],
grid: {
color: "#999"
},
selection: {
mode: "x"
}
});
$("#placeholder").bind("plotselected", function (event, ranges) {
var options = {
series: {
lines: { show: true },
points: { show: true }
},
legend: { noColumns: 2 },
xaxis: { tickDecimals: 0 },
yaxis: { min: 0 },
selection: { mode: "x" }
};
var placeholder = $("#placeholder");
placeholder.bind("plotselected", function (event, ranges) {
$("#selection").text(ranges.xaxis.from.toFixed(1) + " to " + ranges.xaxis.to.toFixed(1));
plot = $.plot(placeholder, data,
$.extend(true, {}, options, {
xaxis: { min: ranges.xaxis.from, max: ranges.xaxis.to }
}));
});
// don't fire event on the overview to prevent eternal loop
overview.setSelection(ranges, true);
});
$("#overview").bind("plotselected", function (event, ranges) {
plot.setSelection(ranges);
});
</script>

stop redraw chart when chart types changes in highcharts

I am using three chart types Line, OHLC, Candlestick in highcharts.
I kept those options in buttons. I'm also drawing vertical and horizontal lines on charts.
The problem is, whenever I change chart type, objects(I mean the vertical and horizontal lines) should remain there.
But it just refreshed. I didn't use chart.redraw() function. I just call the method each time chart type is selected. Is there anyway if I change charts, objects should remain there?
function chart(type,printSma,linked,line,algo)
{
$('#container').highcharts('StockChart', {
credits: {
enabled : 0
},
rangeSelector : {
buttons: [{
type: 'month',
count: 1,
text: '1M'
}, {
type: 'month',
count: 3,
text: '3M'
},{
type: 'month',
count: 6,
text: '6M'
},{
type: 'all',
text: 'All'
}],
selected:3
},
legend: {
enabled: true,
layout: 'vertical',
align: 'right',
verticalAlign: 'middle',
borderWidth: 0
},
title : {
text : currecny
},
xAxis :{
ordinal: false,
minRange : 3600000,
},
yAxis : [{
offset: 0,
ordinal: false,
height:280,
labels: {
format: '{value:.5f}'
}
}],
chart: {
events: {
click: function(event) {
var ren = this.renderer;
//if(event.ctrlKey)
if(line_type=='vertical')
{
chartt ='';
axis_value='';
chartt = this.xAxis[0];
axis_value=event.xAxis[0].value;
$("#line_popup_vertical").show();
$('#save_line_vertical').click(function(event) {
var label=document.getElementById("line_label_vertical").value;
if(label!=null)
{
var id = 'vertLine' + Math.random();
chartt.addPlotLine({
value: axis_value,
color: '#'+(Math.random()*0xEEEEEE<<0).toString(16),
width: 2,
id: id,
label : {
text : label
},
events: {
click: function(e) {
//this.axis.removePlotLine(this.id);
chartt.removePlotLine(id);
}
},
});
}
line_type="";
document.getElementById("line_label_vertical").value="";
$("#horizontal").removeClass("horizontal_hover");
$("#vertical").removeClass("vertical_hover");
$("#trend").removeClass("trend_hover");
$("#fibo").removeClass("fibo_hover");
$("#pointer").addClass("pointer_hover");
$("#line_popup_vertical").fadeOut();
});
}
/*else if(event.altKey)
{*/
else if(line_type=='horizontal')
{
chartt ='';
axis_value='';
chartt = this.yAxis[0];
axis_value=event.yAxis[0].value;
$("#line_popup_horizontal").show();
$('#save_line_horizontal').click(function(event) {
var label=document.getElementById("line_label_horizontal").value;
if(label!=null)
{
var id = 'horzLine' + Math.random();
chartt.addPlotLine({
value: axis_value,
color: '#'+(Math.random()*0xEEEEEE<<0).toString(16),
width: 2,
id: id,
label : {
text : label
},
events: {
click: function(e) {
//this.axis.removePlotLine(this.id);
chartt.removePlotLine(id);
}
},
});
}
/*var label=prompt('Label for Horizontal Line');
if(label!=null)
{
//chart.yAxis[0].removePlotLine('horzLine');
var chart ='';
var id = 'horzLine' + Math.random();
chart = this.yAxis[0];
chart.addPlotLine({
value: event.yAxis[0].value,
dashStyle: 'shortdash',
color: '#'+(Math.random()*0xEEEEEE<<0).toString(16),
width: 2,
id: id,
label : {
text : label
},
events: {
click: function(e) {
//this.axis.removePlotLine(this.id);
chart.removePlotLine(id);
}
},
});
}*/
line_type="";
document.getElementById("line_label_horizontal").value="";
$("#horizontal").removeClass("horizontal_hover");
$("#vertical").removeClass("vertical_hover");
$("#trend").removeClass("trend_hover");
$("#fibo").removeClass("fibo_hover");
$("#pointer").addClass("pointer_hover");
$("#line_popup_horizontal").fadeOut();
});
}
//else if(clickDetected)
else if(line_type=='trend')
{
var x1=event.xAxis[0].value;
var x2 = this.xAxis[0].toPixels(x1);
var y1=event.yAxis[0].value;
var y2 = this.yAxis[0].toPixels(y1);
/*ren.circle(x2, y2, 5).attr({
'stroke-width': 2,
stroke: 'red',
fill: '#636363',
zIndex: 3
}).add();*/
selected_point='['+x1+','+y1+']';
all_points.push(selected_point);
all_str=all_points.toString();
if(all_points.length>1)
{
//this.series[1].remove();
this.addSeries({
type : 'line',
name : 'Trendline'+(j++),
id: 'trend',
data: JSON.parse("[" + all_str + "]"),
color:'#'+(Math.random()*0xEEEEEE<<0).toString(16),
marker:{enabled:true}
});
//$("#horizontal").removeClass("horizontal_hover");
//$("#vertical").removeClass("vertical_hover");
$("#trend").removeClass("trend_hover");
//$("#fibo").removeClass("fibo_hover");
$("#pointer").addClass("pointer_hover");
$("#pointer").click();
}
}
if(all_points.length==2)
{
all_points=[];
}
},
},
},
plotOptions: {
line: {
events: {
click: function(event) {
this.remove();
}
}
},
series: {
events: {
click: function(event) {
//For Other Lines
if(line_type=='vertical')
{
chartt ='';
axis_value='';
chartt = this.xAxis;
axis_value=chartt.toValue(event.chartX);
$("#line_popup_vertical").show();
$('#save_line_vertical').click(function(event) {
var label=document.getElementById("line_label_vertical").value;
if(label!=null)
{
var id = 'vertLine' + Math.random();
chartt.addPlotLine({
value: axis_value,
color: '#'+(Math.random()*0xEEEEEE<<0).toString(16),
width: 2,
id: id,
label : {
text : label
},
events: {
click: function(e) {
//this.axis.removePlotLine(this.id);
chartt.removePlotLine(id);
}
},
});
}
line_type="";
document.getElementById("line_label_vertical").value="";
$("#horizontal").removeClass("horizontal_hover");
$("#vertical").removeClass("vertical_hover");
$("#trend").removeClass("trend_hover");
$("#fibo").removeClass("fibo_hover");
$("#pointer").addClass("pointer_hover");
$("#line_popup_vertical").fadeOut();
});
}
else if(line_type=='horizontal')
{
chartt ='';
axis_value='';
chartt = this.yAxis;
axis_value=chartt.toValue(event.chartY);
$("#line_popup_horizontal").show();
$('#save_line_horizontal').click(function(event){
var label=document.getElementById("line_label_horizontal").value;
if(label!=null)
{
var id = 'horzLine' + Math.random();
chartt.addPlotLine({
value: axis_value,
color: '#'+(Math.random()*0xEEEEEE<<0).toString(16),
width: 2,
id: id,
label : {
text : label
},
events: {
click: function(e) {
//this.axis.removePlotLine(this.id);
chartt.removePlotLine(id);
}
},
});
}
line_type="";
document.getElementById("line_label_horizontal").value="";
$("#horizontal").removeClass("horizontal_hover");
$("#vertical").removeClass("vertical_hover");
$("#trend").removeClass("trend_hover");
$("#fibo").removeClass("fibo_hover");
$("#pointer").addClass("pointer_hover");
$("#line_popup_horizontal").fadeOut();
});
}
//else if(clickDetected)
else if(line_type=='trend')
{
var x1=chartt.toValue(event.chartX);
//var x2 = this.xAxis[0].toPixels(x1);
var y1=chartt.toValue(event.chartY);
//var y2 = this.yAxis[0].toPixels(y1);
selected_point='['+x1+','+y1+']';
all_points.push(selected_point);
all_str=all_points.toString();
if(all_points.length>1)
{
//this.series[1].remove();
this.addSeries({
type : 'line',
name : 'Trendline'+(j++),
id: 'trend',
data: JSON.parse("[" + all_str + "]"),
color:'#'+(Math.random()*0xEEEEEE<<0).toString(16),
marker:{enabled:true}
});
//$("#horizontal").removeClass("horizontal_hover");
//$("#vertical").removeClass("vertical_hover");
$("#trend").removeClass("trend_hover");
//$("#fibo").removeClass("fibo_hover");
$("#pointer").addClass("pointer_hover");
$("#pointer").click();
}
}
if(all_points.length==2)
{
all_points=[];
}
}
}
}
},
series : [
{
//allowPointSelect : true,
type : type,
name : 'Stock Price',
id: 'primary',
data : onadata,
tooltip: {
valueDecimals: 2,
crosshairs: true,
shared: true
},
dataGrouping : {
units : [
[
'hour',
[1, 2, 3, 4, 6, 8, 12]
], [
'day',
[1]
], [
'week',
[1]
], [
'month',
[1, 3, 6]
], [
'year',
[1]
]
]
}
},
]
});
}
$('#chart').find('input[name="selection"]').each(function(index, element) {
$(this).click(function(e) {
//console.log('I was clicked');
type=$(this).val();
printSma=true;
linked='primary';
period=15;
algo='SMA';
typ='trendline';
if(type=='line')
{
$(this).addClass("active_linee");
$("#ohlcc").removeClass("active_ohlcc");
$("#candlestickk").removeClass("active_candlestickk");
//$("#indicator_list").show();
//$("#indicator_list").removeClass('indicator_list_hover');
}
else if(type=='ohlc')
{
$(this).addClass("active_ohlcc");
$("#linee").removeClass("active_linee");
$("#candlestickk").removeClass("active_candlestickk");
//$("#indicator_list").hide();
//$("#indicator_list").removeClass('indicator_list_hover');
}
else if(type=='candlestick')
{
$(this).addClass("active_candlestickk");
$("#linee").removeClass("active_linee");
$("#ohlcc").removeClass("active_ohlcc");
//$("#indicator_list").hide();
//$("#indicator_list").removeClass('indicator_list_hover');
}
chart(type,printSma,linked,line,algo,typ);
});
});
});
<div id="chart" class="chart">
<!--<p>Select Chart Type : </p>-->
<div class="chart_type">
<div class="border_chart">
<input type="button" name="selection" value="candlestick" class="candlestickk" id="candlestickk" title="Candle Stick">
<input type="button" name="selection" value="ohlc" class="ohlcc" id="ohlcc" title="OHLC">
<input type="button" name="selection" value="line" class="linee" id="linee" title="Line">
</div>
</div>

Categories