I'm trying to plot a scatter plot using the Highcharts library. I get some results from my database and format them in front end level using javascript (transformGraph2Data function in the following code does this work - I don't include the code of this function here to keep the question clear and short). More specifically I have the following piece of code:
<script type="text/javascript">
var graph2dataa;
function plotGraph2() {
graph2dataa = transformGraph2Data(<%=graph2data%>);
console.log(graph2dataa);
console.log(typeof graph2dataa);
Highcharts.chart('graphDiv2', {
chart: {
type: 'scatter',
zoomType: 'xy',
events: {
click: function (e) {
var x = e.xAxis[0].value,
y = e.yAxis[0].value,
series = this.series[0];
series.addPoint([x, y]);
}
}
},
xAxis: {
title: {
enabled: true,
text: '<b><%=graph2XaxisTitle%></b>'
},
startOnTick: true,
endOnTick: true,
showLastLabel: true,
plotLines: [{
value: 0,
color: 'red',
dashStyle: 'shortdash',
width: 2
}]
},
yAxis: {
title: {
text: '<b><%=graph2YaxisTitle%></b>',
style: {
fontWeight: 'normal'
}
},
plotLines: [{
value: 0,
color: 'red',
dashStyle: 'shortdash',
width: 2
}]
},
plotOptions: {
series: {
cursor: 'pointer',
turboThreshold: 0
},
scatter: {
marker: {
radius: 2,
states: {
hover: {
enabled: true,
lineColor: 'rgb(100,100,100)'
}
}
}
}
},
graph2dataa //THIS VARIABLE HOLDS THE ACTUAL DATA I'D LIKE TO PLOT
});
}
</script>
The graph2dataa variable gets the following string value:
series: [{ name: "22h - 4h", color: "#000000", data: [{ name: "HACD3", x: 0.417666669, y: 1.841010179 }, { name: "VPS53", x: 0.113499999, y: 0.153579771 }, { name: "IPO11", x: -0.300000004, y: 0.734065117 }, { name: "FIP1L1", x: 0.067000012, y: 0.165934747 }, { name: "HSPE1", x: 0.186666687, y: 0.407514478 }] }] which is valid and can be plotted if I hardcode it. The problem occurs when I try to pass that value using the graph2dataa variable.
Any ideas what am I doing wrong?
Highcharts require a specific series structure and it should be an array of object, not a string. Your transformGraph2Data function should return the correct structure, which looks this way:
var graph2dataa = [{
name: "22h - 4h",
color: "#000000",
data: [{
name: "HACD3",
x: 0.417666669,
y: 1.841010179
}, {
name: "VPS53",
x: 0.113499999,
y: 0.153579771
}, {
name: "IPO11",
x: -0.300000004,
y: 0.734065117
}, {
name: "FIP1L1",
x: 0.067000012,
y: 0.165934747
}, {
name: "HSPE1",
x: 0.186666687,
y: 0.407514478
}]
}]
Live demo: http://jsfiddle.net/BlackLabel/4ath23yo/
Related
I am working on my project with Django where I need to use Javascript and a chart library. I have two charts that I made with ApexCharts, but I don't know how to prevent the label text to being slant and overflow. I can't find anything about this problem in the documentation or I'm not enough familiar to find what I need. :)
var options07 = {
series: [{
name: 'SOHA',
data: [ {{i.szervkult07a}} ]
}, {
name: 'RITKÁN',
data: [ {{i.szervkult07b}} ]
}, {
name: 'IDŐNKÉNT',
data: [ {{i.szervkult07c}} ]
}, {
name: 'GYAKRAN',
data: [ {{i.szervkult07d}} ]
}, {
name: 'MINDIG',
data: [ {{i.szervkult07e}} ]
}],
chart: {
type: 'bar',
height: 350,
stacked: true,
stackType: '100%'
},
responsive: [{
breakpoint: 480,
options: {
legend: {
position: 'bottom',
offsetX: -10,
offsetY: 0
}
}
}],
xaxis: {
categories: ['A cég gondot fordít az ügyfelek igényeinek minél jobb megismerésére'
],
},
fill: {
opacity: 1
},
legend: {
position: 'right',
offsetX: 0,
offsetY: 50
},
};
var chart = new ApexCharts(document.querySelector("#chart_szk07"), options07);
chart.render();
var options07b = {
series: [{
name: 'SOHA',
data: [{{i.szervkult07a}}]
}, {
name: 'RITKÁN',
data: [{{i.szervkult07b}}]
}, {
name: 'IDŐNKÉNT',
data: [{{i.szervkult07c}}]
}, {
name: 'GYAKRAN',
data: [{{i.szervkult07d}}]
}, {
name: 'MINDIG',
data: [{{i.szervkult07e}}]
}],
chart: {
type: 'bar',
height: 350
},
plotOptions: {
bar: {
horizontal: false,
columnWidth: '55%',
endingShape: 'rounded'
},
},
dataLabels: {
enabled: false
},
stroke: {
show: true,
width: 2,
colors: ['transparent']
},
xaxis: {
categories: ['A cég gondot fordít az ügyfelek igényeinek minél jobb megismerésére'],
},
yaxis: {
title: {
text: 'fő'
}
},
fill: {
opacity: 1
},
tooltip: {
y: {
formatter: function (val) {
return val + " fő"
}
}
}
};
var chart = new ApexCharts(document.querySelector("#chart_szk07b"), options07b);
chart.render();
From the docs, You should be able to add rotate: 0 to the labels section of xaxis. I suggest trying to shorten those. I imagine a long label will not look as good as a shorter one.
xaxis: {
categories: ['A cég gondot fordít az ügyfelek igényeinek minél jobb megismerésére'],
labels: {
rotate: 0
}
}
(Highcharts version 6)
Is it possible to have a time line looking chart in addition to data points like in this example:
https://jsfiddle.net/s1eL30Lh/97/
<script src="https://code.highcharts.com/stock/highstock.js"></script>
but without using highstock and instead only use highcharts ?
I know it's possible to use xrange module but it's not quite the same:
https://jsfiddle.net/deep3015/q18yvy75/
If the ranges are long enough to simulate a line then you lack the ability to add "data points" on top of the line, and if you make the ranges small enough to look like data points then you don't have a line.
NOTE
I'm aware of the new chart type 'timeline' in version 7 but I need to work with version 6.1
Yes, it is possible. However, you can't use flags series because it is only supported by Highstock. Check the demo and code posted below.
Code:
function toMs(yeah, month) {
return Date.UTC(yeah, month, 1);
}
var series = [{
// First series
name: 'Running',
color: 'green',
id: 'green',
dataRaw: [{
y: 1,
xRanges: [
// first value: from; second value: to
[toMs(2000, 1), toMs(2002, 8)],
[toMs(2006, 10), toMs(2006, 11)]
]
}]
}, {
// Second series
name: 'Filed',
color: 'yellow',
id: 'yellow',
dataRaw: [{
y: 1,
xRanges: [
// first value: from; second value: to
[toMs(2002, 8), toMs(2006, 10)]
]
}]
},
{
// Second series
name: 'Granted',
color: 'blue',
id: 'blue',
dataRaw: [{
y: 1,
xRanges: [
// first value: from; second value: to
[toMs(2006, 11), toMs(2021, 8)]
]
}]
}
].map(function(series) {
series.data = [];
series.dataRaw.forEach(function(dataRaw) {
dataRaw.xRanges.forEach(function(xRange) {
series.data.push([xRange[0], dataRaw.y], [xRange[1], dataRaw.y], [xRange[1], null]); // null breakes the line
}); // forEach
}); // forEach
return series;
});
console.log(series);
var chart = Highcharts.chart('container', {
chart: {
type: 'scatter'
},
title: {
text: 'Example'
},
plotOptions: {
scatter: {
lineWidth: 5,
marker: {
enabled: true,
symbol: 'circle',
fillColor: '#FFFFFF',
lineWidth: 2,
lineColor: null,
radius: 5
},
dataLabels: {
enabled: true,
align: 'right',
rotation: -30,
x: -2,
y: 15,
formatter: function() {
return Highcharts.dateFormat('%Y-%m', this.x);
}
},
tooltip: {
pointFormatter: function() {
return Highcharts.dateFormat('%Y-%m', this.x);
}
}
},
flags: {
lineWidth: 1
}
},
xAxis: {
title: {
text: 'Time'
},
type: 'datetime',
minTickInterval: 365 * 24 * 36e5,
labels: {
align: 'left'
},
plotBands: [{
from: Date.UTC(2000, 10, 27),
to: Date.UTC(2004, 11, 1),
color: '#EFFFFF',
label: {
text: 'Office 1',
style: {
color: '#999999'
},
y: 30
}
}, {
from: Date.UTC(2004, 11, 1),
to: Date.UTC(2012, 9, 1),
color: '#FFFFEF',
label: {
text: 'Office 2',
style: {
color: '#999999'
},
y: 30
}
}, {
from: Date.UTC(2012, 9, 1),
to: Date.UTC(2020, 10, 27),
color: '#FFEFFF',
label: {
text: 'Office 3',
style: {
color: '#999999'
},
y: 30
}
}]
},
yAxis: {
tickInterval: 1
},
series: series,
annotations: [{
labelOptions: {
backgroundColor: 'rgba(255,255,255,0.5)'
},
labels: [{
distance: 10,
point: {
xAxis: 0,
yAxis: 0,
x: toMs(2002, 8),
y: 1
},
text: 'Filled Date'
}]
}]
});
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
<script src="https://code.highcharts.com/6.1/highcharts.js"></script>
<script src="https://code.highcharts.com/6.1/modules/annotations.js"></script>
<div id="container" style="height: 400px"></div>
Demo:
https://jsfiddle.net/BlackLabel/6eahoxjv/
I am very new to data visulizations.
Currently we are having a requirement to draw a chart similar to below using HighChart.js
See jsfiddle: http://jsfiddle.net/rgpz2ru5/22/ for what I tried so far.
I am successfully able to draw chart but facing issue while drawing lines between the datalabel and point (just shown in above image)?
Can you please help?
See below code to draw a chart:
$('#container').highcharts({
chart: {
type: 'scatter',
},
xAxis: {
visible: false
},
yAxis: {
title: {
text: ''
},
labels: {
formatter: function() {
return null
}
}
},
plotOptions: {
series: {
dataLabels: {
enabled: true,
inside: false,
formatter: function(){
console.log("X"+this.x)
console.log("this.x%2"+this.x%2)
if(this.x%2 == 0){
console.log("in if")
return "<div style='position: relative;height:70px; border-left:solid thin #ff0000;margin-left:10px'><span style='position: absolute;bottom: 0;right: 0;'>hello</span></div>";
}else{
console.log("in else")
return "<span style='color:black'>"+this.key+"</span><div style='height:70px; border-left:solid thin #ff0000;margin-left:10px'/>";
}
},
useHTML:true
}
},scatter: {
marker: {
radius: 5,
states: {
hover: {
enabled: false,
lineColor: "#ffb74d"
}
}
},
states: {
hover: {
marker: {
enabled: false
}
}
},
tooltip: {
headerFormat: '<b>{series.name}</b><br>',
pointFormat: '{point.x} cm, {point.y} kg'
}
}
},
series: [{
data: [{
x: 1,
y: 1,
dataLabels: {
y: -80
},
marker: {
radius: 3
},
name: 'SDS',
color: "#ffb74d"
}, {
x: 2,
y: 1,
dataLabels: {
y: 80
},
marker: {
radius: 5
},
name: 'MIP',
color:"#ffe0b2"
}, {
x: 3,
y: 1,
dataLabels: {
y: -80,
distance : 50,
softConnector : false,
connectorColor : '#D0D0D0',
},
marker: {
radius: 7
},
name: 'MDP',
color:"#ff9800"
},{
x: 4,
y: 1,
dataLabels: {
y: 80
},
marker: {
radius: 9
},
name: 'RAD',
color:"#ffb74d"
},{
x: 5,
y: 1,
dataLabels: {
y: -80
},
marker: {
radius: 3
},
name: 'SDS',
color: "#ffb74d"
}, {
x: 6,
y: 1,
dataLabels: {
y: 80
},
marker: {
radius: 5
},
name: 'MIP',
color:"#ffe0b2"
}, {
x: 7,
y: 1,
dataLabels: {
y: -80
},
marker: {
radius: 7
},
name: 'MDP',
color:"#ff9800"
},{
x: 8,
y: 1,
dataLabels: {
y: 80
},
marker: {
radius: 9
},
name: 'RAD',
color:"#ffb74d"
},{
x: 9,
y: 1,
dataLabels: {
y: -80
},
marker: {
radius: 3
},
name: 'SDS',
color: "#ffb74d"
}, {
x: 10,
y: 1,
dataLabels: {
y: 80
},
marker: {
radius: 5
},
name: 'MIP',
color:"#ffe0b2"
}, {
x: 11,
y: 1,
dataLabels: {
y: -80
},
marker: {
radius: 7
},
name: 'MDP',
color:"#ff9800"
},{
x: 12,
y: 1,
dataLabels: {
y: 80
},
marker: {
radius: 9
},
name: 'RAD',
color:"#ffb74d"
}]
}]
});
Can you please help?
Your chart seems to be of a specific kind. I personally have not seen any such visualizations before. Also, having worked with HighCharts, I doubt if any type of highchart can be transformed as yours.
However, on the first look on your figure the following idea appeared in my mind with angular framework.
You can achieve this kind of visualization using basic html and css.
Assuming you are aware with Angular terminology. I suggest having a list of all your values. Loop them in a simple div as follows:
<div ng-repeat = "c in pointsList" > </div>
Next you can use ng-style or ng-class to add dynamic css to your each div.
Seeing your figure, I assume you only following css properties:
1. border-radius
2. background-color
3. width
4. height
Seems like you have fixed categories for each type of bubbles. So you can make few fixed classes in your css and apply them dynamically on the basis of your type of point. Basically, it would look like:
<div ng-repeat = "c in pointsList" ng-class = "{'css1' : c.type1, 'css2' : c.type2}" > </div>
Along with this you will need to apply display: inline-block to bring all divs in a line.
I know, its too naive solution, but if you have limited requirements of such chart, this can help you achieve it with minimal adjustments.
To make similar chart you can use bubble chart: http://jsfiddle.net/rgpz2ru5/
Or standard scatter chart: http://jsfiddle.net/rgpz2ru5/1/
You can change marker size of scatter using marker.radius parameter:
marker: {
radius: 5,
states: {
hover: {
lineColor: "#ffb74d"
}
}
},
You can add your labels using chart.renderer.path and chart.renderer.label:
http://api.highcharts.com/highcharts/Renderer.path
http://api.highcharts.com/highcharts/Renderer.label
var drawLabels = function(chart) {
$('.cLabels').remove();
var series = chart.series,
renderer = chart.renderer,
plotTop = chart.plotTop,
plotLeft = chart.plotLeft;
Highcharts.each(series, function(s) {
Highcharts.each(s.data, function(p) {
renderer.path(['M', p.plotX + plotLeft, p.plotY + plotTop, 'L', p.plotX + plotLeft, p.plotY + plotTop - 30]).attr({
stroke: 'black',
'stroke-width': 1
}).addClass('cLabels').add();
renderer.label(p.name, p.plotX + plotLeft, p.plotY + plotTop - 50).attr({
'text-anchor': 'middle',
padding: 0
}).addClass('cLabels').add();
});
});
}
Here you can see an example how it can work: http://jsfiddle.net/rgpz2ru5/29/
I have created One HighChart ..But its 2 data coordinates are overlapping on y axis after every 2nd Coordinates.
My JSFiddle
My Code:
$(function () {
var highOptions = {
chart: {
type: 'line',
renderTo: 'container2',
zoomType: 'x',
marginTop: 100
},
title: {
text: 'Score'
},
subtitle: {
text: ' '
},
xAxis: {
title: {
text: 'XXX'
},
categories: [],
labels: {
rotation: 45,
step: 1,
y: 30
}
},
yAxis: [{ // left y axis
title: {
text: 'XXX'
},
min: 0,
max: 9,
plotLines: [{
value: 7.5,
color: '#ff0000',
width: 2,
zIndex: 4,
label: {
text: 'XXX'
}
}]
}],
plotOptions: {
column: {
dataLabels: {
enabled: true,
formatter: function () {
return Highcharts.numberFormat(this.y, 1);
}
}
}
},
legend: {
align: 'left',
verticalAlign: 'top',
y: 20,
floating: true,
borderWidth: 0
},
tooltip: {
shared: true,
crosshairs: true
},
series: []
};
highOptions.xAxis.categories = [0.1003, 0.1006, 0.1008, 1.1010, 1.1011, 1.1012, 1.1013, 2.4];
highOptions.subtitle.text = "XXX:";
chart = new Highcharts.Chart(highOptions);
for (var x = 0; x <= 1; x++) {
var newLP = [];
switch (x) {
case 0:
aName = "One";
newLP.push([0.1004, 4.5]);
newLP.push([0.1008, 1.4]);
newLP.push([1.1012, 5.5]);
newLP.push([1.1014, 2, 6]);
newLP.push([2.4, 8.22]);
break;
case 1:
aName = "Two";
newLP.push([0.1004, 5.52]);
newLP.push([0.1008, 6.16]);
newLP.push([1.1012, 6.34]);
newLP.push([1.1014, 6.69]);
newLP.push([1.1016, 6.36]);
newLP.push([2.4, 7.44]);
break;
}
chart.addSeries({
name: aName,
data: newLP
}, false);
}
chart.redraw();
});
I have test it with several data ..still it overlaps .. what could be the issue ..
Please Suggest
The problem is that you're x-axis points are so close to each other it seems as they are overlapping. For example 0.1003 is pretty close to 0.1006 and 0.1008 is pretty close to 1.1010. However, If you zoom in you can tell they are not overlapping. See http://jsfiddle.net/u9xES/555/.
I need to set different colors for each column in Highcharts graph dynamically. My Highcharts graph is:
options = {
chart: {
renderTo: 'chart',
type: 'column',
width: 450
},
title: {
text: 'A glance overview at your contest’s status'
},
xAxis: {
categories: ['Approved Photos', 'Pending Approval Photos',
'Votes', 'Entrants'],
labels: {
//rotation: -45,
style: {
font: 'normal 9px Verdana, sans-serif, arial'
}
}
},
yAxis: {
allowDecimals: false,
min: 0,
title: {
text: 'Amount'
}
},
legend: {
enabled: false
},
series: []
};
series = {
name: "Amount",
data: [],
dataLabels: {
enabled: true,
color: '#000000',
align: 'right',
x: -10,
y: 20,
formatter: function () {
return this.y;
},
style: {
font: 'normal 13px Verdana, sans-serif'
}
}
};
The data is set this way:
for (var i in Data) {
if (parseInt(Data[i]) != 0) {
series.data.push(parseInt(Data[i]));
} else {
series.data.push(null);
}
}
options.series.push(series);
chart = new Highcharts.Chart(options);
How can I dynamically set different colors for each data point in this loop?
Here is another solution with the latest version of Highcharts (currently 3.0).
Set the colorByPoint option to true and define the color sequence that you want.
options = {
chart: {...},
plotOptions: {
column: {
colorByPoint: true
}
},
colors: [
'#ff0000',
'#00ff00',
'#0000ff'
]
}
Here is an example based upon Highcharts Column with rotated labels demo
When you add the value to the series.data you can also set the color using the point options e.g
series.data.push({ y: parseInt(Data[i]), color: '#FF0000' });
For more details about the point options see https://api.highcharts.com/class-reference/Highcharts.Point#color
Try either of these approaches:
Approach 1:
Highcharts.setOptions({ colors: ['#3B97B2', '#67BC42', '#FF56DE', '#E6D605', '#BC36FE'] });
Approach 2:
var colors = ['#3B97B2', '#67BC42', '#FF56DE', '#E6D605', '#BC36FE', '#000'];
$('#bar_chart').highcharts({
chart: {
type: 'column'
},
title: {
text: ''
},
subtitle: {
text: ''
},
xAxis: {
type: 'category'
},
yAxis: {
title: {
text: ''
}
},
legend: {
enabled: false
},
plotOptions: {
series: {
borderWidth: 0,
dataLabels: {
enabled: false
}
}
},
series: [{
name: '',
colorByPoint: true,
data: [{
name: 'Blue',
y: 5.78,
color: colors[0]
}, {
name: 'Green',
y: 5.19,
color: colors[1]
}, {
name: 'Pink',
y: 32.11,
color: colors[2]
}, {
name: 'Yellow',
y: 10.04,
color: colors[3]
}, {
name: 'Purple',
y: 19.33,
color: colors[4]
}]
}]
});
i had colors from API response and 2 series. second series with dynamic colors.
following is sample to set dynamic colors while series mapping.
const response = [{
'id': 1,
'name': 'Mango',
'color': '#83d8b6',
'stock': 12.0,
'demand': 28,
},
{
id ': 2,
'name': 'Banana',
'color': '#d7e900',
'stock': 12.0,
'demand': 28,
}
];
let chartData: {
categories: [],
series: []
};
chartData.categories = response.map(x => x.name);
chartData.series.push({
name: 'Series 1',
type: 'column',
data: response.map(x => x.demand)
});
chartData.series.push({
name: 'Series 2',
type: 'column',
data: response.map(x => ({
y: x.stock,
color: x.color // set color here dynamically
}))
});
console.log('chartData: ', chartData);
you could also read more about Highcharts series Point and Marker