I'm attempting to create a column chart that can be updated by clicking on a button, so that users can track their progress through a quiz. I'm very close with this fiddle, but my logic is off, because although the column data increases after each click, the y axis is also adding the data from the previous clicks into the sum of the column data: eg. click on button A, column A receives 1 point, Click on button B, Column B receives one point, but adds on the column A point for a total of 2 in column B, rather than just getting one point.
https://jsfiddle.net/mrjarbenne/17en2sc8/
var chart = Highcharts.chart('container', {
chart: {
type: 'column'
},
xAxis: {
categories: ['A', 'B', 'C']
},
series: [{
data: [0, 0, 0]
}]
});
// button handler
var y = 0;
$('#button').click(function () {
y += 1;
chart.series[0].data[0].update(y);
});
// button handler
var y = 0;
$('#button2').click(function () {
y += 1;
chart.series[0].data[1].update(y);
});
// button handler
var y = 0;
$('#button3').click(function () {
y += 1;
chart.series[0].data[2].update(y);
});
This other fiddle is another method I've been trying to work with, but I'm struggling to remove the Realtime functionality so it's just a stand-alone element (I don't want the chart to be updated by multi individuals in a session)
http://jsfiddle.net/realtimeframework/xdo4daju/
Thank you for any direction you can provide on where I'm going wrong.
Related
I want to make an API call on Click of RangeSelector Buttons in High stock. I am aware of the fact that there is a click event in RangeSelector but the problem is the event passed to that does not contain the min and max values of the graph. And I need these two values for making an API call. I am also aware that we can use afterSetExtremes here but the problem with that is it is triggered multiple times even when the button is not clicked. Below are some part of my code. Can anybody tell how can I get Xmin and Xmax in the click event?
const zoomButtons = [
{
type: 'minute',
count: 5,
text: '5min',
events:{
click: onClickOfRangeSelector
}
}]
function onClickOfRangeSelector(e) {
console.log(this);
console.log(e);// need to make an API call here
}
You can refer to a chart variable, please check the below code:
var chart = Highcharts.stockChart('container', {
...,
rangeSelector: {
buttons: [{
type: 'minute',
count: 5,
text: '5min',
events: {
click: function(a, b, c) {
var min = chart.xAxis[0].max - this._range,
max = chart.xAxis[0].max;
console.log(min, max);
}
}
}]
}
});
Live demo: http://jsfiddle.net/BlackLabel/x1gc38nd/
API Reference: https://api.highcharts.com/highstock/rangeSelector.buttons.events
I have a dropdown with a list of counties to select from on the map. I'm trying to figure out how I can have the county on the map highlighted when it is selected. I cannot find in the API documentation where this is done.
I tried changing the fill color of the point but when you select a new color the code to change it back to its previous color doesn't seem to want to execute.
So essentially, in my on change event code, I want to change the color the selected point by hc-key or id.
$("#county-select").change(function () {
$('.highcharts-point-select').css('fill', 'rgb(153, 145, 164)');
$('.county-checkbox').prop('checked', false);
$('.metric-td').remove();
let id = $('#county-select').val();
let fips = $(this).find(':selected').attr('data-fips');
let point = mapChart.get(fips);
});
You could use the allowPointSelect functionality to trigger selections on the map via your dropdown. Here I add the country code as the ID of the point, so that we can use chart.get to get them.
A minimal example, with two buttons to select either Norway or Sweden, exclusively (JSFiddle):
$.getJSON('https://cdn.jsdelivr.net/gh/highcharts/highcharts#v7.0.0/samples/data/world-population-density.json', function (data) {
for(var i = 0; i < data.length; i++) {
// Adding ID to data, so we can use "get" to find the points
data[i].id = data[i].code3;
}
// Initiate the chart
var chart = Highcharts.mapChart('container', {
series: [{
data: data,
mapData: Highcharts.maps['custom/world'],
joinBy: ['iso-a2', 'code'],
allowPointSelect: true,
}]
});
$('#selectnor').click(function () {
chart.get('NOR').select();
});
$('#selectswe').click(function () {
chart.get('SWE').select();
});
});
I have a highstocks chart that shows trends of non stock data because it has some good features that our product needs.
one of these features is custom technical indicators, espcially between 2 different trends showing.
I know how to define maually an indicator, but it seems I can't use more then 1 series with it, while I want to create indicators for a veraity of differneces between 2 or more series.
I can't find a way to do this, so I'm wondering if it is at all possible
Average between two series can be simply added as another separate series. You can use for example load event to calculate it and chart.addSeries() method to add it.
Code:
chart: {
zoomType: 'xy',
events: {
load: function() {
var chart = this,
dataLen = chart.series[0].points.length,
newSeries = {
id: "avg",
name: "average",
data: []
},
series1 = chart.series[0],
series2 = chart.series[1],
i;
for (i = 0; i < dataLen; i++) {
newSeries.data.push({
x: series1.points[i].x,
y: (series2.points[i].y + series1.points[i].y) / 2
})
}
chart.addSeries(newSeries);
}
}
}
Demo:
https://jsfiddle.net/BlackLabel/15sa38qb/
API:
https://api.highcharts.com/highcharts/chart.events.load
https://api.highcharts.com/class-reference/Highcharts.Chart#addSeries
I am working on a columnrange graph in Highcharts where I plot different measurements and confidence intervals in the same plot:
The first few columns inside a group (e.g. Januar) represent measurements for different cities, while the last column represent confidence intervals. I would like to add horizontal lines to the confidence intervals representing the data means. That is, each orange column would get its own line at a specific heigh going from the left to the right side of the orange rectangle. How do I plot such lines?
I know how to add lines as a separate series of type line. However, doing so, I'm not sure how to guess the exact location of orange column and also I do not know how to handle cases when some columns are hidden through the legend.
This question is related to this question though I am not able to get any of that solutions to work in my case.
Here is the fiddle: https://jsfiddle.net/nikicc/rqxqm4hm/
You can use renderer.path to draw proper lines.
function drawDataMeans() {
const intervalSeries = this.get('conf-interval'),
series = this.series.filter(series => intervalSeries !== series)
let lines = this.dataMeansLines
if (!lines) {
lines = this.dataMeansLines = series[0].data.map(series => this.renderer.path().attr({
'stroke-width': 2,
stroke: 'black'
}).add(intervalSeries.group))
}
const visibleSeries = series.filter(series => series.visible)
if (intervalSeries.visible && visibleSeries.length) {
intervalSeries.data.forEach((point, i) => {
const mean = visibleSeries.reduce((sum, series) => sum + series.data[i].high, 0) / visibleSeries.length
const {x, width} = point.shapeArgs
const y = this.yAxis[0].toPixels(mean, true)
lines[i].attr({
d: `M ${x} ${y} L ${x + width} ${y}`,
visibility: 'visible'
})
})
} else {
lines.forEach(line => line.attr({visibility: 'hidden'}))
}
}
Hook on load/redraw events
chart: {
type: 'columnrange',
inverted: false,
events: {
load: drawDataMeans,
redraw: drawDataMeans
}
},
example: https://jsfiddle.net/dq48sq3w/
I want to plot a scatter chart with lines connecting each point. Is it possible to vary the width of the line between each segment?
For example, I want the line from point A to point B to have a width of 5. I want the line between point B and point C to have a width of 2.
Sure, I could use the renderer to manually draw the lines, but then I have to handle the coordinates and scaling manually.
(FWIW, here's an example of a scatter plot with connecting lines.)
There is no configuration option to do this. The difficult way would be, as you say, to implement it your self with help of the renderer.
You can configure individual points with color and size:
data: [{
x: 161.2,
y: 51.6,
marker: {
radius: 15,
fillColor: 'rgb(255, 0, 0)'
}
}]
but the line that connects two markers do not have any individual settings.
There is a way to do this without using the renderer, however it is very much a hack.
The basic premise is that you can adjust the thickness of a line in Highcharts after render time by manipulating the SVG or VML attributes, and you can prevent Highcharts from changing it back. Therefore all you need to do is break up your series into two point series and chart them all at once. Code below, fiddle can be seen here http://jsfiddle.net/39rL9/
$(document).ready(function() {
//Define the data points
DATA = [
{x: 2,y: 4,thickness: 1},
{x: 7,y: 8,thickness: 8},
{x: 10,y: 10,thickness: 2},
{x: 22,y: 2,thickness: 10},
{x: 11,y: 20,thickness: 15},
{x: 5,y: 15,thickness: 2}
]
//Format the data into two point series
//and create an object that can be put
//directly into the "series" option
var finalSeries = [];
for (var i=0; i < DATA.length-1; i++) {
finalSeries[i]={};
finalSeries[i].data = [];
finalSeries[i].data.push(DATA[i]);
finalSeries[i].data.push(DATA[i+1])
};
//A function to change the thickness of
//the lines to the proper size
function changeLineThick(){
var drawnSeries = $(".highcharts-series")
for (var i=0; i < drawnSeries.length; i++) {
drawnSeries.eq(i)
.children("path")
.eq(3) //this could change depending on your series styling
.attr("stroke-width",DATA[i].thickness)
};
}
//Define and render the HighChart
chart = new Highcharts.Chart({
chart: {
renderTo: "chart-container",
defaultSeriesType: "scatter"
},
plotOptions: {
scatter: {
lineWidth: 2
}
},
symbols: ["circle","circle","circle","circle","circle","circle"],
series: finalSeries
})
changeLineThick();
//prevent Highcharts from reverting the line
//thincknesses by constantly setting them
//to the values you want
$("#chart-container").mousemove(function(){changeLineThick()})
})