Wordcloud-highcharts is now available in its latest release (>=6.0) and now I am baffling with laying out the gradient (linear/radial) over texts. For example in this link, if I change the colors array in the series object to
fillColor: {
linearGradient: [0, 0, 0, 200],
stops: [
[0, 'white'],
[1, 'black']
]
},
It does nothing.
Wordcloud has limited functionality and however I am unable to do accomplish this task. Even tried appending multiple defs for different text gradients with (k is such that, it lies between 0 to n)
<defs>
<radialGradient id="myRadialGradient_k"
fx="5%" fy="5%" r="65%"
spreadMethod="pad">
<stop offset="0%" stop-color="#00ee00" stop-opacity="1"/>
<stop offset="100%" stop-color="#006600" stop-opacity="1" />
</radialGradient>
</defs>
and searching for the class and apply css to fill with this myLinearGradient_k by fill:url(#myLinearGradient_k);. But it is very clumsy and heavy. Also search by id is not possible in this case and appending to class highcharts-point is the only possibility, which limits the options.
You may find this live demo helpful: http://jsfiddle.net/kkulig/mnj07vam/
In chart.events.load I placed the code responsible for finding maximum weight, creating gradients (every point has a separate one) and applying them:
chart: {
events: {
load: function() {
var points = this.series[0].points,
renderer = this.renderer,
maxWeight = 0;
// find maximum weight
points.forEach(function(p) {
if (p.weight > maxWeight) {
maxWeight = p.weight;
}
});
points.forEach(function(p, i) {
var id = 'grad' + i;
// create gradient
var gradient = renderer.createElement('linearGradient').add(renderer.defs).attr({
id: id,
x1: "0%",
y1: "0%",
x2: "100%",
y2: "0%"
});
var stop1 = renderer.createElement('stop').add(gradient).attr({
offset: "0%",
style: "stop-color:rgb(255,255,0);stop-opacity:1"
});
var stop2 = renderer.createElement('stop').add(gradient).attr({
offset: Math.round(p.weight / maxWeight * 100) + "%",
style: "stop-color:rgb(255,0,0);stop-opacity:1"
});
// apply gradient
p.update({
color: 'url(#' + id + ')'
}, false);
});
this.redraw();
}
}
}
API reference: https://api.highcharts.com/class-reference/Highcharts.SVGRenderer#createElement
Related
I am fetching data from an endpoint
I display the data in a highchart
There are several indicators that can be selected. For each of them another yAxis is added below the main one.
My series data are of this format :
series: [
{
data: [],
id: 'prices',
step: this.hasStep,
name: this.$props.title,
fillColor: 'rgba(127,183,240,0.2)',
},
{
visible: false,
type: 'column',
id: 'volume',
name: 'Volume_hardcoded',
//linkedTo: 'prices',
data: this.volumeSeries,
},
],
I save the data in the following way (don't pay attention in the logic, it works fine):
if (this.selectedTimeSpan.tickInterval === 1) {
for (let i = 0; i < prices.length; i++) {
let xData = null;
this.selectedTimeSpan.getIntradayData
? (xData = Math.floor(new Date(prices[i].time).getTime()))
: (xData = Math.floor(new Date(prices[i].date).getTime()));
priceSeries[i] = {
x: xData,
open: prices[i].first,
high: prices[i].high,
low: prices[i].low,
close: prices[i].last,
y: prices[i].last,
volume: prices[i].tradingVolume,
};
this.volumeSeries[i] = {
x: xData,
y: prices[i].tradingVolume,
};
}
} else {
let j = 0;
for (
let i = 4;
i < prices.length;
i += this.selectedTimeSpan.tickInterval
) {
priceSeries[j] = {
x: Math.floor(new Date(prices[i].date).getTime()),
open: prices[i].first,
high: prices[i].high,
low: prices[i].low,
close: prices[i].last,
y: prices[i].last,
volume: prices[i].tradingVolume,
};
this.volumeSeries[j] = {
x: Math.floor(new Date(prices[i].date).getTime()),
y: prices[i].tradingVolume,
};
j++;
}
}
When I select these indicators (they are based on the volume), I am getting this result.(You can see a blank space below the main chart.) Instead when i swap to OHLC or candlestick my main series (series[0]) it looks works fine and it looks like this. Any idea why is that happening? I haven't touched the tooltip settings at all (in case it was there a problem). I am struggling 2 days now with it can't really figure it out. Any help would be appreciated a lot. If you need more information feel free to comment so I can provide. Thanks in advance. Chris.
Fixed, there's a flag that can be used called usedOhlcData in series object. (series[0] in my case]. We just set it to true.
series:[{
data:[],
useOhlcData:true,
...}
,{
...
}]
I built a widget with multiple y Axes very similar to the official sample here: http://www.highcharts.com/stock/demo/candlestick-and-volume
I'm trying to have some sort of visual separation between the chart panes, either by
applying a special style to the maximum grid line for each pane, or
adding a horizontal line in the whitespace between the panes
The only approach i got working is using PlotLines, but I'd rather have a separator that's independent of zoom levels. Any ideas on how to achieve this?
Use Renderer to draw a path between y axes.
function drawSeparator() {
let separator = this.separator;
const options = this.options.chart.separator;
if (options && options.enabled) {
if (!separator) {
this.separator = separator = this.renderer.path({
d: 'M 0 0',
'stroke-width': options.width === undefined ? 1 : options.width,
stroke: options.color || 'black'
}).add();
}
const topAxisBottom = this.yAxis[0].top + this.yAxis[0].height;
const bottomAxisTop = this.yAxis[1].top;
const y = topAxisBottom + (bottomAxisTop - topAxisBottom) / 2;
separator.attr({
d: `M 0 ${y} L ${this.chartWidth} ${y}`
});
}
}
Call the method on load/redraw event
chart: {
events: {
load: drawSeparator,
redraw: drawSeparator
},
separator: {
enabled: true,
width: 3,
color: 'blue'
}
},
You can modify the path's d attribute, the path starts from axis.left and stops on axis.left + axis.width
Live example and output
http://jsfiddle.net/L11uqxgq/
I have a highcharts scatter plot for which I'm trying to fetch the x and y tickPositions in freemarker template, specifically the first and last one. Such as that I would get something as [-10,-10] (bottom left corner) at the intersection of the x-y axis and [30,40] (top right corner) at the intersection of the opposite sides, where xAxis ticks are [-10,0,10,20,30] and yAxis ticks are [-10,0,10,20,30,40]
I want these points so that I'll be able to plot a diagonal line across the scatter plot from bottom lower corner to top right corner. The line series should look like:
series: [
{
type : 'line',
<#--diagonal line-->
data :[[-10,-10], [30,40]], // to be calculated dynamically
lineWidth: 0.5,
marker : {
enabled : false
}
},
{
color: 'rgb(0,85,152)',
data: [[2,3],[6,7],[8,9]]
}
]
The problem at present is I'm unable to get [-10,-10], [30,40] data points. Is it even possible is what I'm wondering. Any help is much appreciated!
You have the getExtremes() function on an axis.
For example:
var extremes = $('#container').highcharts().yAxis[0].getExtremes();
Here is the doc, and here is a demo fiddle
Is this what you were trying to achieve ?
Edit
After your fiddle example, I understand better your need.
Here is the updated fiddle
var chart = $('#container').highcharts();
var extremeY = chart.yAxis[0].getExtremes();
var extremeX = chart.xAxis[0].getExtremes();
var lineSeries = {
type: 'line',
data: [
[extremeX.min, extremeY.min],
[extremeX.max, extremeY.max]
],
lineWidth: 0.5,
lineColor: 'rgb(0,0,0)',
marker: {
enabled: false
}
};
chart.addSeries(lineSeries);
I created an object with the properties of the line series. And using min and max (not dataMin and dataMax) properties from the object returned by getExtremes() you obtain the desired result.
Edit 2
You could put this code in the load event of the chart. It is a callback called after the chart finished loading. And here you can use this to refer to the chart :
$('#container').highcharts({
chart: {
events: {
load: function() {
var extremeY = this.yAxis[0].getExtremes();
var extremeX = this.xAxis[0].getExtremes();
var lineSeries = {
type: 'line',
data: [
[extremeX.min, extremeY.min],
[extremeX.max, extremeY.max]
],
lineWidth: 0.5,
lineColor: 'rgb(0,0,0)',
marker: {
enabled: false
}
};
this.addSeries(lineSeries);
}
},
//...
});
Here is the new updated fiddle
Since you need only a diagonal path, then you could add it using renderer
Example: http://jsfiddle.net/cr7gq4st/
function diagonal() {
var chart = this,
ren = chart.renderer,
diag = chart.diag,
attrs = {
'stroke-width': 0.5,
stroke: '#000',
zIndex: 1
},
topR = {
x: chart.plotLeft + chart.plotWidth,
y: chart.plotTop
},
bottomL = {
x: chart.plotLeft,
y: chart.plotTop + chart.plotHeight
},
d = 'M ' + bottomL.x + ' ' + bottomL.y + ' L ' + topR.x + ' ' + topR.y;
if( !diag ) { //if doesn't exist, then create
chart.diag = ren.path().attr(attrs).add();
}
chart.diag.attr({d:d});
}
I have an areaspline with only one series. The design calls for drawing x-axis gridlines that touch the series and don't extend beyond that. Is it possible to do this? Here's my code to configure the gridlines:
xAxis: {
gridLineWidth: 1,
tickAmount: 30,
lineWidth: 0,
labels: {
enabled: false
},
minPadding: 0
},
Another option (other then 2 mentioned by jlbriggs in a comment on the question) might be to extend Highcharts and change paths of grid lines in a wrapper like:
(function(H) {
var UNDEFINED;
H.wrap(H.Tick.prototype, 'render', function(p) {
p.apply(this, [].slice.call(arguments, 1)); //run original function
if (this.axis.isXAxis && this.gridLine) {
var point = this.axis.series[0].options.data[this.pos],
d = this.gridLine.attr('d').split(' ');
if (point !== UNDEFINED) {
d[2] = this.axis.chart.yAxis[0].toPixels(point);
d = d.join(' ');
} else {
d = ''; //remove if not crossing any point
}
this.gridLine.attr({
d: d
});
}
});
})(Highcharts)
Example: http://jsfiddle.net/69f5z3us/
If a grid line is not crossing any point, then the grid line is removed, but you could change that part of the code if you want to.
I am new to Highcharts.
I have a line chart. Here is the categories:
["9/7/14", "9/8/14", "9/9/14", "9/10/14", "9/11/14", "9/12/14", "9/13/14", "9/14/14", "9/15/14", "9/16/14", "9/17/14", "9/18/14", "9/19/14", "9/20/14", ...]
Here is the data series:
[1, 4, 0, 2, 1, 1, 1, 5, 3, 1, 0, 0, 6, 8, ... ]
I added zoom to my chart, very similar to this jsfiddle demo: http://jsfiddle.net/348sh/3/
chart: {
renderTo: 'container',
zoomType: 'x'
},
I would like to get the total of only those Y values within the zoomed-in window, not the total of the entire data series. For this, I need to capture what values are included in the x axis in the zoomed window. So I added the following based on my research:
xAxis: {
type: 'line',
events: {
setExtremes: function(event) {
console.log(event.min);
console.log(event.max);
}
}
}
However, the values for event.min or event.max are numbers such as 3.6552511415525117, 7.10730593607306. I have no way to know which x values are included in the zoomed window. How can I find which x values are included? Any way to get the start and end x values ?
Thanks!
I did further research. I notice that I may have answered my question already in my question. It turns out that the numbers I gave in my question are very helpful, not clueless. Math.ceil(min) and Math.floor(max) are just the beginning and ending index of the data points in the data series that are show up in the zoomed window. The another thing to note is to use afterSetExtremes event. This is the moment where chart finalizes the starting and ending points in the X axis. So the complete answer is:
xAxis: {
type: 'line',
events: {
afterSetExtremes: function(event) {
var start = Math.ceil(event.min);
var end = Math.floor(event.max);
}
}
}
I am new to Highcharts and love to get corrected if I am wrong.
Cheers.
This may help you . Try this fiddle : http://jsfiddle.net/7kv9a25r/ .
chart: {
events: {
selection: function (event) {
var text,
label;
if (event.xAxis) {
text = 'min: ' + Highcharts.numberFormat(event.xAxis[0].min, 2) + ', max: ' + Highcharts.numberFormat(event.xAxis[0].max, 2);
} else {
text = 'Selection reset';
}
label = this.renderer.label(text, 100, 120)
.attr({
fill: Highcharts.getOptions().colors[0],
padding: 10,
r: 5,
zIndex: 8
})
.css({
color: '#FFFFFF'
})
.add();
setTimeout(function () {
label.fadeOut();
}, 1000);
}
},
zoomType: 'x'
},