How can I style highchart select to look like hover? - javascript

Highcharts is an amazing library, however I need to programatically scroll through the chart as if the cursor itself was hovering across the x-axis. The only way I can think of doing this is by selecting points, unfortunately I could not find options in highcharts api documentation that allows me to put crosshairs/ playheader on selected points.
How can I do this?

This is not part of the API, but you can use point.onMouseOver() to fire mouseover event: http://jsfiddle.net/15dzo23n/1/
Example:
var index = 0;
$('#container').highcharts({
chart: {
events: {
load: hoverAnim
}
},
tooltip: {
crosshairs: true
},
series: [{
name: 'AAPL',
data: [5, 10, 15, 12, 13, 14, 12, 1, 12, 1, 12, 12, 12, 1]
}]
});
function hoverAnim(e) {
var chart = this,
points = chart.series[0].points,
len = points.length;
if (index < len) {
chart.hoverSeries = chart.series[0];
chart.hoverPoint = points[index];
chart.pointer.runPointActions(e); //display crosshair
points[index].onMouseOver(e); // display tooltip and set hover state
index++;
setTimeout(function () {
hoverAnim.call(chart, e);
}, 100);
}
}

Pawel Fus had a good answer, however I found an even better solution which doesn't have the buggy lag behavior when switching to different time points. Also events are not needed in this solution.
var chart = myElement.highcharts();
function select(value) {
// Scroll to some time.
var axes = chart.axes;
for (var i = 0; i < axes.length; i ++) {
var axis = axes[i];
axis.drawCrosshair(null, chart.series[0].points[value])
}
for (i = 0; i < chart.series.length; i++) {
var series = chart.series[i];
// Unset last value
series.points[oldValue].setState('');
// Set new value
series.points[value].setState('hover');
}
oldValue = value;
});

Related

Working with many data points in ECharts.js

I need help to improve the number of points displayed on the chart line.
With the current code, for 100000 points, only 20 drawn in the graph line.
var elements = new Array(100000);
for (i = 0; i < elements.length; i++) {
elements[i] = i;
}
var myChart = echarts.init(document.getElementById('main'));
var option = {
title: {
text: 'ECharts entry example'
},
tooltip: {},
legend: {
data:['Sales']
},
xAxis: {
data: elements
},
yAxis: {},
series: [{
name: 'Sales',
type: 'line',
data: elements
}]
};
myChart.setOption(option);
You have to modify the xAxis for this. You should take a look at the axisTicks, and play around with the interval option. It either supports auto, a number or a function.
Alternatively, you can also manually show/hide the datapoints, by telling the data elements to display them, but maybe this only works when there's an axis tick available.
For displaying every datapoint, set showAllSymbol to true in the series data.
series: [{
name: 'Sales',
type: 'line',
showAllSymbol: true,
data: elements
}]
However, 20.000 datapoints may be a lot, so you can also create an interval by setting showSymbol within the data elements
for(i = 0; i < elements.length; i++){
elements[i] = {
value: i,
symbol: (i % 100 === 0) ? 'circle' : 'none'
}
}
This will set showSymbol to true for every 100th iteration. You may have to combine this with showAllSymbol: true in the series data to work properly.
Note: % is the modulus operator

Dynamic width for each column if value is 0 in highcharts

I'm new to highcharts plugin and I need to set different width for each column if the value is empty.
series: [{
name: 'Jane',
data: [1, 0, 4]
}, {
name: 'John',
data: [5, 7, 3]
}]
And i need to display it this way
I need this
I have been searching the documentation but i don't find anything that does it, without a lot of code.
I achieved this, but it doesn't upload/resize dynamically.
http://jsfiddle.net/5vgjztk0/
Thanks
You can use something like merimekko chart.
(function(H) {
var each = H.each;
var xStart = 0;
var rememberX = 0;
H.wrap(H.seriesTypes.column.prototype, 'drawPoints', function(proceed) {
var series = this;
if(series.data.length > 0 ){
each(this.data, function(point) {
point.shapeArgs.width = series.xAxis.translate(point.x) - series.xAxis.translate(xStart);
point.shapeArgs.x = series.xAxis.translate(point.x) - point.shapeArgs.width;
xStart = point.x;
});
xStart = 0;
}
proceed.call(this);
})
})(Highcharts)
Demo:
http://jsfiddle.net/js55fuo1/24

Handsontable Sequence word creation

Thanks for this wonderful plugin.
I am using this plugin for grid functionality. For this I am trying to use sequence word creation on drag down.
I have implemented upto my knowledge. But I am facing one problem while select and drag multiple column.
I have created jsfiddle for this sample
var myData = [
["WIRE-001", 10, 11, 12, 13],
["WIRE-002", 20, 11, 14, 13],
["WIRE-003", 30, 15, 12, 13]
];
$("#exampleGrid").handsontable({
data: myData,
startRows: 5,
startCols: 5,
//minSpareCols: 1, //always keep at least 1 spare row at the right
minSpareRows: 10, //always keep at least 1 spare row at the bottom,
rowHeaders: true,
colHeaders: true,
contextMenu: true,
currentRowClassName: 'currentRow',
currentColClassName: 'currentCol',
outsideClickDeselects: false,
fillHandle: true,
beforeAutofill: function(start, end, data) {
console.log(arguments);
console.log(start);
console.log(end);
console.log(data);
var selectedVal = this.getSelected();
var selectedData = this.getData(selectedVal[0], selectedVal[1], selectedVal[2], selectedVal[3]);
var sequenceNum = [];
var sequenceWord = [];
var numberFormat = 1;
if (start.col == 0) {
for (var j = 0; j < selectedData.length; j++) {
var numbers = selectedData[j][0].match(/[0-9]+$/g);
if (numbers && !isNaN(numbers[0])) {
numberFormat = numbers[0].length;
sequenceNum.push(Number(numbers[0]));
}
var words = selectedData[j][0].match(/[A-Za-z\-]+/g);
if (words && isNaN(words[0])) {
sequenceWord.push(words[0]);
}
}
var prefix = sequenceWord.length > 0 ? sequenceWord[0] : "";
var lastValue = sequenceNum[sequenceNum.length - 1]
var diff = sequenceNum.length > 1 ? (sequenceNum[sequenceNum.length - 1] - sequenceNum[sequenceNum.length - 2]) : 1;
for (var i = 0; i < end.row; i++) {
if (!data[i]) { data[i] = []; }
data[i][0] = prefix + pad((lastValue + diff), numberFormat);
diff++;
}
}
},
afterChange: function(changes, source) {
}
});
Appreciate for helping to solve this.
I recommend opening the console and checking the errors since it becomes very clear what your problem is if you do so. The example that leads to the bug that you mentioned on your comment uses an empty row. In your code you are doing
var words = selectedData[j][0].match(/[A-Za-z\-]+/g);
However, selectedData[j][0] will be null. I would simply add a check for empty rows and handle it appropriately (toss it or default to some value)

Hichcharts- hidden series does not show again after updating plots twice

I have done something like:
Have a check box to change the plot's data
when the check box is checked/unchecked, update the series data array by calling series[i].update() accordingly.
But I have a problem that when a series is hidden by the user and try to check the checkbox and then uncheck, followed by reshow the series, the series does not show again.
Please note that If I only check the box once, no problem occurs, there will be problem only when we check the box more than once after we hide the series.
I have reproduce the problem HERE (JSFiddle)
The code to update the plot is :
if (chart) {
for (var i = 0; i < chart.series.length; i++) {
//chart.series[i].setVisible(true, true); // Note that if I add this code, then no problem
chart.series[i].update({
data: dataArray[i]
});
}
}
The problem is that you base on Highcharts generated points. When series is hidden, then points don't exist and you set empty data for a series. In other words it looks like this: chart.series[i].setData( [] );.
I suggest to use separate arrays for data and use those for your calculations. General idea: http://jsfiddle.net/pGuEv/37/ (I know, it works a bit different, but shows how should be written)
var origData = [
[11, 22, 33, 44, 55, 66, 77, 88],
[10, 20, 30, 40, 50, 60, 70, 80]
];
$('#container').highcharts({
series: [{
data: origData[0].slice()
}, {
data: origData[1].slice()
}]
});
And later:
for (var i = 0; i < origData.length; i++) { // original data
var onePlotData = [];
var sum = 0; //前面点的合计值s
for (var j = 0; j < origData[i].length; j++) { // original data
var value = origData[i][j]; // original data
var point = {
//x: value.x,
y: state ? value + sum : value - sum,
//total: value.total
}
sum = point.y;
onePlotData.push(point);
}
dataArray.push(onePlotData);
}

gRaphael Line Chart: JSON Data to Populate Popup Tags Instead of x & y Coordinates?

var times = [["1:30pm", "2:30pm"], ["3:30pm", "5:30am"], ["12:30pm", "2:30pm"], ["9:30am", "2:30pm", "4:30pm"], ["3:30pm", "5:30pm"], ["10:30am", "12:30pm"], [] ]; I have a Raphael Line Chart based on one of the examples with the popup tags on rollover. Currently, the tag is populated with data from the Y-axis. X = day of the week, Y = a "safety score", the JSON data is times of reported incidences on each day.
I can't seem to find any documentation about how to call in a third data set to populate the tag, and I can't seem to do it with my code without breaking it. Any suggestions?
Here is my code for the tags:
//tags
for (var i = 0, ii = this.y.length; i < ii; i++) {
this.tags.push(r.tag(this.x, this.y[i], this.values[i], 90, 0).insertBefore(this).attr([{ fill: "#fff"}, { fill: this.symbols[i].attr("fill") }]));
}
}, function () {
this.tags && this.tags.remove();
//end tags
});
And here is my data:
var times = [["1:30pm", "2:30pm"], ["3:30pm", "5:30am"], ["12:30pm", "2:30pm"], ["9:30am", "2:30pm", "4:30pm"], ["3:30pm", "5:30pm"], ["10:30am", "12:30pm"], [] ];
Ok, I figured it out! Here it is.
var times = [["1:30pm", "2:30pm"], ["3:30pm", "5:30am"], ["12:30pm", "2:30pm"], ["9:30am", "2:30pm", "4:30pm"], ["3:30pm", "5:30pm"], ["10:30am", "12:30pm"], [] ];
//tags
for (var i = 0, ii = this.y.length; i < ii; i++) {
this.tags.push(r.tag(this.x, this.y[i]-10, times[i].join("\n"), 90, 0).insertBefore(this).attr([{ fill: "#fff"}, { fill: this.symbols[i].attr("fill") }]));
}
}, function () {
this.tags && this.tags.remove();
//end tags
});

Categories