I have the following scenario in haml:
#ownershipChart{"chart-data" => [["pie1", 100], ["pie2", 150], ["pie3", 200]]}
#ownershipChart{"chart-data" => [["pie4", 45], ["pie5", 50], ["pie6", 20]]}
and in javascript:
$(function(){
$('#ownershipChart').highcharts({
chart: {
type: 'pie'
},
title:{
text: 'Ownership'
},
plotOptions:{
pie:{
allowPointSelect: true
}
},
series: [{
type: 'pie',
name: 'Ownership',
data: $('#ownershipChart').attr('chart-data')
}]
});
});
As you can figure, I'm trying to create one highcharts function that applies across these two charts at the same time. First, I know this is incorrect because $('#ownershipChart').attr('chart-data') isn't returning anything. Second, is this the right way to think about it? I'm currently dynamically generating the haml div id="ownershipChart" so dynamically generating a highcharts js object every time also feels wrong.
What's the best way to generate multiple highcharts when the div ids they are attached to is unknown and varies user by user?
You could instead use a class, and loop through each instance creating the chart as you go. Something like this:
$(function () {
$('.ownershipChart').each(function() {
$(this).highcharts({
chart: {
type: 'pie'
},
title: {
text: 'Ownership'
},
plotOptions: {
pie: {
allowPointSelect: true
}
},
series: [{
type: 'pie',
name: 'Ownership',
data: $(this).attr('chart-data')
}]
});
});
});
Note that the data property is filled by a reference to this, which means the data will be read from the current element in the iteration.
Related
I'm using highchart large tree map demo. I'm getting level data on click of each section. But also need to get the data on back button. So I'm using events drill up function to get data on click of back button. below is my code.
this.setState({
data: {
series: [{
type: 'treemap',
layoutAlgorithm: 'squarified',
allowDrillToNode: true,
animationLimit: 1000,
dataLabels: {
enabled: false
},
levelIsConstant: false,
levels: [{
level: 1,
dataLabels: {
enabled: true
},
borderWidth: 0,
}],
data: points,
events: {
click:(e)=>{
console.log(e)
},
drillup:(e)=>{
console.log(e)
}
}
}],
// subtitle: {
// text: 'Click points to drill down. Source: WHO.'
// },
title: {
text: ''
}
}
})
But don't know drill up is not working even click is working and also I added
import drilldown from "highcharts/modules/drilldown";
drilldown(Highcharts);
But still not getting any data. Please help.
Notice that treemap series don't use the drilldown module, but has own drilldown implementation, which logic you can find here: https://code.highcharts.com/modules/treemap.src.js
What you will need to do is render a custom button while clicking the point and attach an update functionality on this button. Something like here:
Demo: https://jsfiddle.net/BlackLabel/gas07t34/
events: {
click() {
let chart = this.chart;
chart.button = chart.renderer.button('back', 500, 0, function() {
chart.series[0].update({
data: data1
})
chart.button.destroy();
}).add()
this.update({
data: data2
})
}
}
API: https://api.highcharts.com/class-reference/Highcharts.SVGRenderer#button
API: https://api.highcharts.com/class-reference/Highcharts.Series#update
I am tried to get the series from the already displayed highchart and use that series to plot a new chart in another one html div, i have written below code to achieve this,finally i get the series from existing graph but can't render to the new html div
var data = chart.series; // series from already displyed
jQuery('#commonModal_res').highcharts({
chart: { zoomType: 'x'},
title: { text: "" },
subtitle: { text: 'Click and drag in the plotted area to zoom in' },
xAxis: { type: 'datetime' },
legend: { enabled: false },
series: data,
});
note : throwing too many recursion error
The problem occurs because you're trying to assign the complete and already built series object, instead of configuration object which is required. In order to make it work, you need to assign the configuration object by this way:
$('#new_con').highcharts({
chart: { zoomType: 'x'},
title: { text: "" },
subtitle: { text: 'Click and drag in the plotted area to zoom in' },
xAxis: { type: 'datetime' },
legend: { enabled: false },
series:charts[0].userOptions.series,
});
Then your chart should be rendered properly.
Additionaly, you can access appropriate chart by the Highcharts.charts array on global Highcharts object, where all charts are stored, just like that:
series: Highcharts.charts[0].userOptions.series,
In this case creating new charts array is unnecessary.
Live example: http://jsfiddle.net/cqfj5t34/
I have a Highchart graph which receives data from backend in the form of Handlebars expressions. Something like this.
$('#container').highcharts({
xAxis: {
categories: [{{{histKeys}}}]
},
yAxis: {
title: {
text: 'Failure Percentage',
style: {
color: '#cc0000'
}
},
labels: {
format: '{value}%',
style: {
color: '#cc0000'
}
},
plotLines: [{
value: 0,
width: 1,
color: '#808080'
}]
},
credits: {
enabled: false
},
plotOptions: {
series: {
cursor: 'pointer',
point: {
events: {
click: function() {
var index = this.series.name;
var tfs = epochKeys[Math.ceil(this.x)];
window.location.href = url;
return false;
}
}
}
}
},
legend: {
layout: 'vertical',
align: 'right',
verticalAlign: 'middle',
borderWidth: 0
},
series: [
{{#each histData as |index|}}
{
name: '{{#key}}',
type: 'spline',
allowPointSelect: true,
{{#each index as |status|}}
{{#if_eq #key "histSuccess"}}
{{/if_eq}}
{{#if_eq #key "histFailure"}}
data: [{{this}}],
{{/if_eq}}
{{/each}}
},
{{/each}}
]
});
Now i make an AJAX call to get data to refresh the graph. How do i pass the new value of Handlebars expressions to the variables used in the Highcharts code.
So the data i receive in the AJAX call contains the values of all these expressions that have been used in the Highcharts function.
Since the code is dynamic, i can't manually update the series values also because the number of lines on the graph differ depending upon the data coming from the backend.
Thanks for any input.
You can get the (already existing) highcharts object in the ajax callback like this:
$('#container').highcharts()
There's in fact a quite good API to interact with this object, documented here: http://api.highcharts.com/highcharts
For starters, you can replace an existing chart by calling addSeries() again. For that to work, your series must have an id, and you add a series with the same id again:
$('#container').highcharts().addSeries({ id: 'myid', data: .... });
In the same way, you can also remove existing series:
$('#container').highcharts().removeSeries('myid');
It's also possible only to replace the data of a series, something along the lines of this:
$('#container').highcharts().getSeries('myid').setData(...);
I hope that is a little help for you.
I'm working with the columnrange chart type, and some of my could end up being much much smaller than the normal size, so I would like to specify the minPointLength so that the small data points are still visible amidst their larger neighbors and can easily be hovered over and clicked on. I have tried placing the minPointLength option in multiple places throughout my code, but it doesn't seem to ever affect the size of the columns. I have gotten minPointLength to work fine on other chart types, but not with the columnrange chart. Here is a little js fiddle I borrowed and modified to attempt to accomplish what I want: http://jsfiddle.net/kdCgU/7/
$(function() {
window.chart = new Highcharts.Chart({
chart: {
renderTo: 'container',
type: 'columnrange',
inverted: true
},
xAxis: {
labels: {
enabled: false
}
},
plotOptions: {
series: {
minPointLength: 10, //This doesn't seem to do anything
dataLabels: {
enabled: true,
},
}
},
series: [{
name: "Product A",
data: [[-200, 200]]},
{
name: "Product B",
data: [[-150, 150]]},
{
name: "Product C",
data: [[-100, 100]]},
{ name: "Small Data",
data: [[0, 1]]}
]
});
Any help would be greatly appreciated, thanks!
It is known bug reported here , but is fixed in master branch.
http://jsfiddle.net/sbochan/kdCgU/8/
Like I said in my comment it is a bug. It is already reported on their github here.
It seems to be fixed on the master :
http://jsfiddle.net/xAU6X/
I am using ExtJs/ YUI charts in my application.
What I am wondering, is it possible to dynamically change the color on any of the charts based on data?
i.e. I have a store which contains a field holding the hex color for that particular row. Is it possible to dynamically set the color of a bar in the bar chart with the hex value?
Take a look at this blog post. When you are configuring the chart object, pass a series object with a style property as described in that post to define the colors and their sequence.
Then you just need to get your colors by either looping through your store records and building a new array, or perhaps pulling it from your store with store.query. Then pass this array as the property.
(...),
series: [style: { colors: arrayBuiltFromStore }],
(...)
From what I've been able to find, you can use the
(...),
series: [style: {colors: arrayBuiltFromStore }],
(...)
method if you're creating a pie chart (or another chart with series.colors attribute), and it works great.
If you're using a type of chart that doesn't support series.colors... it gets a little more convoluted. I found that using the renderer method works fairly well. The only problem with this method (that I can see right away) is that it doesn't change the colors in the legend. It would take some further editing to see if this could be pulled from the store.
If you figure out the legend issue, let me know, but I hope this helps.
Note: Not all the variables used in the below script are populated in the script.
function myColorer(rec) {
var aFiller = new Array('#0000FF','#31CD31','#FFFF00','#FF0000');
return aFiller[rec];
}
Ext.onReady(function() {
var sDataStore = new Ext.data.JsonStore(sPathToDataStore);
chart = new Ext.chart.Chart({
renderTo: document.getElementById('test-graph'),
width: 800,
height: 600,
animate: true,
store: sDataStore,
legend: {
position: 'right',
isVertical: true,
},
axes: [{
type: 'Numeric',
grid: true,
position: 'left',
fields: ['field1','field2','field3','field4'],
title: 'Title Here',
grid: {
odd: {
opacity: 1,
fill: '#ddd',
stroke: '#bbb',
'stroke-width': 1
}
},
minimum: 0,
adjustMinimumByMajorUnit: 0
}, {
type: 'Category',
position: 'bottom',
fields: label1,
title: sXAxisLabel,
grid: true,
}],
series: [{
renderer: function(sprite, record, curAttr, index, store) {
var color = myColorer(index);
return Ext.apply(curAttr, {
fill: color
});
},
type: 'area',
highlight: false,
axis: 'left',
xField: label1,
yField: ['field1','field2','field3','field4'],
style: {
opacity: 0.93
}
}]
});
});
Try this:
Create a hidden field and assign its value to the value of the store field which contains the colour value.
when rendering bar chart, set the background colour of a bar to the value of the hidden field.
Yes, you can do it by using renderers. Following code example changes colors of bars in bar chart:
series: {
type: 'bar',
xField: 'name',
yField: 'value',
label:{
field: 'value'
},
renderer: function(sprite, config, rendererData, index) {
var record = rendererData.store.getData().items[index];
return Ext.apply(rendererData, {
fillStyle: record.data.color,
});
}
}
Here 'color' is a field of the store model. You can set different color for each bar by setting it in corresponding record in your store.