Why my column chart is getting cropped in highcharts - javascript

I have implemented column chart using highchart .
My rightmost column is getting cropped and I am not able to get it fixed .
Please suggest which option is being missed by me .
{
"chart":{
"renderTo":"1_123456_id",
"type":"column",
"marginBottom":100,
"marginTop":100,
"marginRight":400,
"width":1050
},
"leftMetric":"Too Soft",
"rightMetric":"Too Loud",
"activeCount":8,
"passiveCount":0,
"optimal":92,
"totalResponses":25,
"averageText":"4.6",
"plotOptions":{
"series":{
"pointWidth":[
"30"
],
"borderRadius":[
"10"
],
},
"column":{
"pointPlacement":"on",
},
},
"credits":{
"enabled":false
},
"title":{
"text":"VOLUME",
"x":310,
"align":"left",
"style":{
"fontWeight":"bold",
"fontSize":15,
"color":"#000",
"marginRight":100
}
},
"xAxis":[
{
"categories":[
0,
0,
0,
1,
0,
20,
2,
0,
1,
1,
0
],
"tickmarkPlacement":"on",
"tickPositions":[
0,
1,
2,
3,
4,
5,
6,
7,
8,
9,
10,
11
],
"gridLineDashStyle":"longdash",
"gridLineWidth":1,
"labels":{
"style":{
"fontWeight":"bold",
"fontSize":15
}
}
},
{
"linkedTo":0,
"tickmarkPlacement":"on",
"tickPositions":[
0,
1,
2,
3,
4,
5,
6,
7,
8,
9,
10,
11
],
"opposite":"true",
"categories":[
0,
1,
2,
3,
4,
5,
4,
3,
2,
1,
0
],
"gridLineDashStyle":"longdash",
"gridLineWidth":1
}
],
"yAxis":{
"min":0,
"max":30,
"labels":{
"enabled":true
},
"title":{
"text":"Responses"
},
"tickInterval":2,
"gridLineColor":"#9ACD9D",
},
"series":[
{
"showInLegend":false,
"name":"speaker",
"data":[
{
"y":0,
"color":"C82506"
},
{
"y":0,
"color":"BC5B0C"
},
{
"y":0,
"color":"F39019"
},
{
"y":1,
"color":"F5D329"
},
{
"y":0,
"color":"#70BF40"
},
{
"y":20,
"color":"#01882A"
},
{
"y":2,
"color":"#70BF40"
},
{
"y":0,
"color":"F5D329"
},
{
"y":1,
"color":"F39019"
},
{
"y":1,
"color":"BC5B0C"
},
{
"y":1,
"color":"C82506"
}
]
}
]
}
LINK TO FIDDLE
EDIT
How can make grid lines to move out of axis on extremes and middle as marked in image

Correct way:
you just need to turn off clip in plotOptions
plotOptions:{
column: {
pointPlacement: "on",
clip: false,
}
}
Here is the Fiddle and also Thanks to Pawel Fus
Tricky way:
Here is what you want. i don't update my previous answer as that may help others.
but as the problem was charts cropped by highchart so i do the reverse and remove the integer number from clip-path= "url(#highcharts-NUMBER) attribute to have the full chart.
<g class="highcharts-series highcharts-tracker" visibility="visible" zIndex="3" transform="translate(51,100) scale(1 1)" style="" clip-path="url(#highcharts-1)">
Here the code to do this:
function showMagic(){
$(".highcharts-series-group").children()
.filter(function() {
var $this = $(this);
var lol = $this.attr("clip-path");
if (lol) {
$this.attr("clip-path","url(#highcharts)");
} else {
return false;
}
});
}
window.onload = showMagic;
Yes a little tricky, but it works! Here is the LIVE DEMO
UPDATE:
This part will be the answer to the update part of question:
we should format labels of xAxis :
"labels": {
"useHTML": true,
"formatter": function () {
if(this.value==0 || this.value==5)
{
return '<p style="margin-top: -20px;" >'+this.value + '<br> | </p> ' ;
}
else
{
return this.value;
}
}
},
Here is the LIVE DEMO

This is because of pointPlacement: "on". so just remove this part of yor code:
"column":{
"pointPlacement":"on",
},
When pointPlacement is "on", the point will not create any padding of the X axis In a column chart.
Here is the fiddle

First remove tickPositions, they are unnecessary when using categories. Then you need to set:
min: -0.5
max: categories.length - 0.5 (10.5 in your case)
startOnTick: false
endOnTick: false
And live example: http://jsfiddle.net/ASJm9/7/

Related

Show quarter markers instead of years in JSCharting Gantt Chart

I am new to this JSCharting library and working with it to create a Gantt Chart. When I map my data on the chart, it slices the Y Axis based on years. I am trying to slice it based on 3 months intervals. Instead of 2021, 2022, 2023, I want to show Q1, Q2, Q3, Q4 for each year.
One quick and dirty solution I found is below, to create markers on Y Axis like this:
{
yAxis: {
markers: [2020, 2021, 2022, 2023, 2024, 2025, 2026, 2027, 2028].reduce(
(all: { label: { text: string; color: string }; value: string }[], year) => {
return [
...all,
...[1, 4, 7, 10].map((month) => ({
label: {
text: month === 1 ? "Q1" : month === 4 ? "Q2" : month === 7 ? "Q3" : "Q4",
color: "#ddd",
},
color: "#ddd",
value: `${month}/1/${year}`,
legendEntry: {
visible: false,
},
})),
];
},
[]
),
},
}
However, when I do that, first line of data covers the quarter labels like so.
Is there a proper way to do this and show it in the bottom with along with years? I'd appreciate any help.
You can use calendar patterns to create ticks for quarters and months more easily. Here's an example.
var chart = JSC.chart('chartDiv', {
debug: true,
axisToZoom: 'x',
margin_right: 10,
xAxis: {
scale_type: 'time',
defaultTick_enabled: false,
customTicks: [
{
value_pattern: 'month',
label_text: '%min'
},
{
value_pattern: 'quarter',
label_text: qTickText
},
{
value_pattern: 'year',
label_text: '%min'
}
]
},
legend_visible: false,
title_label_text:
'Apple iPhone sales (in million units)',
series: [
{
type: 'line spline',
defaultPoint: {
marker: {
outline: { width: 2, color: 'white' }
}
},
points: [
{ x: '04/1/2016', y: 74.78 },
{ x: '07/1/2016', y: 51.19 },
{ x: '10/1/2016', y: 40.4 },
{ x: '1/1/2017', y: 45.51 },
{ x: '04/1/2017', y: 78.29 },
{ x: '07/1/2017', y: 50.76 },
{ x: '10/1/2017', y: 41.03 },
{ x: '1/1/2018', y: 46.68 },
{ x: '04/1/2018', y: 67.32 },
{ x: '07/1/2018', y: 52.22 },
{ x: '10/1/2018', y: 41.3 },
{ x: '1/1/2019', y: 46.89 }
]
}
]
});
function qTickText(v) {
return dateToQuarter(v[0]);
}
function dateToQuarter(d) {
d = new Date(d);
return 'Q' + (Math.floor(d.getMonth() / 3) + 1);
}

Google spreadsheet API. Cannot specify axisPosition of a series

I want to specify the axis of a series. If i specify targetAxis to be "RIGHT_AXIS", it doesn't work..
The Axis-titles for LEFT_AXIS and RIGHT_AXIS are also not showing. Only the bottom one.
I want the graph to look like this:
But it ends up looking like this:
Here the red axis is at the bottom, because this column contains much lower numbers then the column with the numbers for the blue bars.
Someone who knows how i can solve this?
Here is my code:
{
addChart: {
chart: {
spec: {
title: "Graf - tibber",
basicChart: {
chartType: "COMBO",
axis: [
// X-AXIS
{
position: "BOTTOM_AXIS",
title: "TID",
},
// Y-AXIS LEFT
{
position: "LEFT_AXIS",
title: "FORBRUK(KWH)",
},
// X-AXIS RIGHT
{
position: "RIGHT_AXIS",
title: "PRIS",
},
],
legendPosition: "BOTTOM_LEGEND",
domains: [
{
domain: {
sourceRange: {
sources: [
{
sheetId: 0,
startRowIndex: 0,
endRowIndex: endIndex,
startColumnIndex: 0,
endColumnIndex: 1
}
]
}
}
}
],
series: [
{
series: {
sourceRange: {
sources: [
{
sheetId: 0,
startRowIndex: 0,
endRowIndex: endIndex,
startColumnIndex: 5,
endColumnIndex: 6,
},
],
},
},
targetAxis: "LEFT_AXIS",
},
{
series: {
sourceRange: {
sources: [
{
sheetId: 0,
startRowIndex: 0,
endRowIndex: endIndex,
startColumnIndex: 3,
endColumnIndex: 4,
},
],
},
},
targetAxis: "RIGHT_AXIS",
}
],
headerCount: 1,
},
},
position: {
newSheet: true,
},
},
},
},
],
Improved request
Disclaimer, there is a bug in the API for the right hand axis, see end of answer
{
"requests": [
{
"addChart": {
"chart": {
"spec": {
"title": "Graf - tibber",
"basicChart": {
"chartType": "COMBO",
"legendPosition": "BOTTOM_LEGEND",
"axis": [
{
"position": "BOTTOM_AXIS",
"title": "TID"
},
{
"position": "LEFT_AXIS",
"title": "FORBRUK(KWH)"
},
{
"position": "RIGHT_AXIS",
"title": "PRIS"
}
],
"domains": [
{
"domain": {
"sourceRange": {
"sources": [
{
"sheetId": 0,
"startRowIndex": 0,
"endRowIndex": 8,
"startColumnIndex": 0,
"endColumnIndex": 1
}
]
}
}
}
],
"series": [
{
"series": {
"sourceRange": {
"sources": [
{
"sheetId": 0,
"startRowIndex": 0,
"endRowIndex": 8,
"startColumnIndex": 1,
"endColumnIndex": 2
}
]
}
},
"targetAxis": "LEFT_AXIS",
"type": "COLUMN"
},
{
"series": {
"sourceRange": {
"sources": [
{
"sheetId": 0,
"startRowIndex": 0,
"endRowIndex": 8,
"startColumnIndex": 2,
"endColumnIndex": 3
}
]
}
},
"targetAxis": "RIGHT_AXIS",
"type": "LINE"
}
],
"headerCount": 1
}
},
"position": {
"newSheet": true
}
}
}
}
]
}
Note that the row and column indices I changed because I was working with some sample data. "type": "COLUMN" and "type": "LINE" entries in the series. In fact, for me, I would get 400 bad request without it. This produces a chart with BOTTOM_AXIS and LEFT_AXIS but not RIGHT_AXIS (see below for info on that). The chart also has two different scales so the line doesn't get overshadowed by the columns.
Right Axis
Unfortunately this is a current bug with the API: https://issuetracker.google.com/issues/153528225 - be sure to mark it with a ☆ to let Google know that this affects you.
Reference
Sample Chart Requests - I used the sample to navigate the documentation to find out if there were any attributes missing.

Canvasjs: different settings according to screen size

I'm using CanvasJs for a bar chart, but I would like to have different settings according to screen size.
For example, I would like to hide labels completely on the axisY for screens < 480px. How can this be done?
It seems that media queries and css can't be used to customize the charts.
Here's an example:
<script type="text/javascript">
window.onload = function () {
var chart = new CanvasJS.Chart("chartContainer", {
title: {
text: "Understanding Labels"
},
axisY: {
labelFontSize: 20
},
axisX: {
labelAngle: -30
},
data: [
{
type: "column",
dataPoints: [
{ y: 10, label: "Apples" },
{ y: 15, label: "Mangos" },
{ y: 25, label: "Oranges" },
{ y: 30, label: "Grapes" },
{ y: 28, label: "Bananas" }
]
}
]
});
chart.render();
}
</script>
I experimented with something like this which obviously doesn't work:
axisY: {
labelFormatter: function(e) {
if ($(window).width() < 480) {
return "";
},
},
},
You can define a function for labelFormatter outside of axisY object.
axisY: {
labelFormatter: axisYLabels,
},
You can modify the labels of axisY here based on width of the window.
function axisYLabels(e) {
if ($(window).width() < 480) {
return "";
} else {
return e.value;
}
}
You can see a working fiddle here.

jqplot x axis spacing

I am using jqplot and am having trouble with the spacing on the X axis.
Here is my code:
$(document).ready(function(){
var plot3 = $.jqplot('CogsLineGraph', [[1,2,3,4,5,6], [2,3,4,5,6,7], [3,4,5,6,7,8]],
{
title:'Cogs (Last 6 Months)',
seriesDefaults:
{
rendererOptions: {smooth: true}
},
series:[
{
lineWidth:1,
markerOptions: { size:7, style:'dimaond' }
},
{
lineWidth:1,
markerOptions: { size: 7, style:"dimaond" }
},
{
lineWidth:1,
markerOptions: { size:7, style:"filledSquare" }
}
]
}
);
});
Here is an image of the graph displayed on a web page:
On the X axis, the values are:
0, 0.5, 1, 1.5, 2, 2.5 etc
Can I please have some help to modify my code such that the values on the X axis are as follows:
0, 1, 2, 3 etc
Try this,
axes: {
xaxis: {
ticks: ['1','2','3','4','5','6'];
}
}

displaying custom tooltip when hovering over a point in flot

From the example here, I kind of know how to create a Flot graph that shows tooltips when hovering. But the examples only show to how to display tooltips containing the x value, y value, label, etc., and I can't figure out how to create more customized tooltips.
Is there someplace I can attach custom data, that I can access when creating the tooltip?
For example, to simplify, let's suppose my code looks like:
var d = [ { label: "Fake!", data: [ [1290802154, 0.3], [1292502155, 0.1] ] } ];
var options = {
xaxis: { mode: "time" },
series: {
lines: { show: true },
points: { show: true }
},
grid: { hoverable: true, clickable: true }
};
$.plot($("#placeholder"), d, options);
Now, when clicking on the first datapoint, I want the tooltip to show "Hello", and when clicking on the second datapoint I want to show "Bye". How do I do this? When binding the plothover event
$(".placeholder").bind("plothover", function (event, pos, item) { /* etc. */ };
I'm not sure what "item" refers to, and how to attach data to it.
You can add data to the series simply by adding it to the data array.
Instead of
$.plot(element, [[1, 2], [2, 4]] ...)
You can
$.plot(element, [[1, 2, "label"], [2, 4, "another label"]] ...)
And then use that information to show a custom label.
See this fiddle for a full example:
http://jsfiddle.net/UtcBK/328/
$(function() {
var sin = [],
cos = [];
for (var i = 0; i < 14; i += 0.5) {
sin.push([i, Math.sin(i), 'some custom label ' + i]);
cos.push([i, Math.cos(i), 'another custom label ' + i]);
}
var plot = $.plot($("#placeholder"), [{
data: sin,
label: "sin(x)"
},
{
data: cos,
label: "cos(x)"
}
], {
series: {
lines: {
show: true
},
points: {
show: true
}
},
grid: {
hoverable: true,
clickable: true
},
yaxis: {
min: -1.2,
max: 1.2
}
});
$("#placeholder").bind("plothover", function(event, pos, item) {
$("#tooltip").remove();
if (item) {
var tooltip = item.series.data[item.dataIndex][2];
$('<div id="tooltip">' + tooltip + '</div>')
.css({
position: 'absolute',
display: 'none',
top: item.pageY + 5,
left: item.pageX + 5,
border: '1px solid #fdd',
padding: '2px',
'background-color': '#fee',
opacity: 0.80
})
.appendTo("body").fadeIn(200);
showTooltip(item.pageX, item.pageY, tooltip);
}
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="http://people.iola.dk/olau/flot/jquery.flot.js"></script>
<div id="placeholder" style="width:600px;height:300px"></div>
Here is a rough JSFiddle example that I whipped up. Not sure if it's functioning exactly how you like but might spark an idea...
[update]
you'll want to bind to the
$("#placeholder").bind("plotclick", function (event, pos, item) {/* code */});
event for clicking events
[update2] Updated Example
I've adjusted the example to use your test data and to work more with what you have described above. As for the item object it seems that it is generated on the fly so, from what I can tell, you can not add additional data to it. However, you can create an array to cache the item objects when clicked and add additional data to them and use them for the hover event.
This new example does just that, it shows the normal tooltip when nothing is clicked. but once clicked it determines if the point clicked was the first or second and adds an addition property to the item object called alternateText and stores it in an array called itemsClicked.
Now when a point is hovered over it checks to see if there is a cached item object within the array based on the same index of the current item object, which is obtained via item.dataIndex. If there is a matching index in the cache array itemsClicked it will grab the item object from it and use the alternateText property that was added during the click event earlier.
The first point's item object would look something like this:
item : {
dataIndex: 0,
datapoint: [
1290802154,
0.3
],
pageX: 38,
pageY: 82,
series: {/* properties of the series that this point is in */},
seriesIndex: 0
}
Once clicked it would then look like this and be stored in the itemsClicked array:
item : {
alternateText: 'hello',
dataIndex: 0,
datapoint: [
1290802154,
0.3
],
pageX: 38,
pageY: 82,
series: {/* properties of the series that this point is in */},
seriesIndex: 0
}
Please let me know if any of this is helpful or not, if not I'll shut up and stop updating my answer :P
Also you can try following code:
function showTooltip(x, y, contents, z) {
$('<div id="tooltip">' + contents + '</div>').css({
position: 'absolute',
display: 'none',
top: y - 30,
left: x - 110,
'font-weight': 'bold',
border: '1px solid rgb(255, 221, 221)',
padding: '2px',
'background-color': z,
opacity: '0.8'
}).appendTo("body").show();
};
$(document).ready(
$(function() {
var data = [{
"label": "scott",
"data": [
[1317427200000 - 5000000 * 3, "17017"],
[1317513600000 - 5000000 * 5, "77260"]
]
},
{
"label": "martin",
"data": [
[1317427200000 - 5000000 * 2, "96113"],
[1317513600000 - 5000000 * 4, "33407"]
]
},
{
"label": "solonio",
"data": [
[1317427200000 - 5000000, "13041"],
[1317513600000 - 5000000 * 3, "82943"]
]
},
{
"label": "swarowsky",
"data": [
[1317427200000, "83479"],
[1317513600000 - 5000000 * 2, "96357"],
[1317600000000 - 5000000, "55431"]
]
},
{
"label": "elvis",
"data": [
[1317427200000 + 5000000, "40114"],
[1317513600000 - 5000000 * 1, "47065"]
]
},
{
"label": "alan",
"data": [
[1317427200000 + 5000000 * 2, "82504"],
[1317513600000, "46577"]
]
},
{
"label": "tony",
"data": [
[1317513600000 + 5000000, "88967"]
]
},
{
"label": "bill",
"data": [
[1317513600000 + 5000000 * 2, "60187"],
[1317600000000, "39090"]
]
},
{
"label": "tim",
"data": [
[1317513600000 + 5000000 * 3, "95382"],
[1317600000000 + 5000000, "89699"]
]
},
{
"label": "britney",
"data": [
[1317513600000 + 5000000 * 4, "76772"]
]
},
{
"label": "logan",
"data": [
[1317513600000 + 5000000 * 5, "88674"]
]
}
];
var options = {
series: {
bars: {
show: true,
barWidth: 60 * 60 * 1000,
align: 'center'
}
},
points: {
show: true
},
lines: {
show: true
},
grid: {
hoverable: true,
clickable: true
},
yaxes: {
min: 0
},
xaxis: {
mode: 'time',
timeformat: "%b %d",
minTickSize: [1, "month"],
tickSize: [1, "day"],
autoscaleMargin: .10
}
};
$(function() {
$.plot($('#placeholder'), data, options);
});
$(function() {
var previousPoint = null;
$("#placeholder").bind("plothover", function(event, pos, item) {
if (item) {
if (previousPoint != item.datapoint) {
previousPoint = item.datapoint;
$("#tooltip").remove();
var x = item.datapoint[0],
y = item.datapoint[1] - item.datapoint[2];
debugger;
showTooltip(item.pageX, item.pageY, y + " " + item.series.label, item.series.color);
}
} else {
$("#tooltip").remove();
previousPoint = null;
}
})
});
})
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.4.1/jquery.min.js"></script>
<script src="http://people.iola.dk/olau/flot/jquery.flot.js"></script>
<div id="content">
<div class="demo-container">
<div id="placeholder" class="demo-placeholder" style="width:800px;height:600px;"></div>
</div>
</div>

Categories

Resources