I'm using the following json to generate my PieChart, but it generates a blank chart with no error.
The following block is my code to generate the chart:
$.post('/admin/relatorios/getVendasCidadeChart', {
dt_inicio: $("#datepicker-from").val(),
dt_fim: $("#datepicker-to").val()
}).done(function(donutData){
var dados = new google.visualization.DataTable(donutData);
var options = {
title: "Vendas por Cidade",
width: "100%",
height: "100%",
};
var chart = new google.visualization.PieChart(document.getElementById('vendas-cidade'));
chart.draw(dados, options);
});
The json output by the post request:
{"cols":[{"id":"","label":"Loja","type":"string"},{"id":"","label":"Valor(R$)","type":"number"}],"rows":[{"c":[{"v":"Loja Shopping"},{"v":"8620.00"}]},{"c":[{"v":"Loja Centro"},{"v":"10240.00"}]}]}
Chart generated:
http://i.stack.imgur.com/Dfhe4.png
Update 1
Fiddle reproducing the problem:
https://jsfiddle.net/thatmesg/1/
I had similar "issue" but that wasn't an issue. All my pie slices were just returning 0 which may happen and it's logically correct.
Add sliceVisibilityThreshold: 0 to your options variable. It should display the legend even if there will be no data. If you'll see the legend then we can assume that Google Chart library works as expected. If not... then we'll investigate further.
var options = {
legend: { position: 'top', maxLines: 6 },
sliceVisibilityThreshold: 0
};
EDIT:
I see that you're using wrong type of brackets:
That's how your JSON should look like. If you generate it using PHP, don't forget to use json_encode.
var data = google.visualization.arrayToDataTable([["Category","Hours"],["Compliance \/ Policy ($0.00)",0],["Harrassment ($0.00)",0],["Productivity ($0.00)",0],["Skills Gap ($0.00)",0],["Values Behaviour ($0.00)",0]]);
Also I see that yous JSON contains "keys". You should do something like (remove keys and pass just values to the JSON):
$final['json'] = json_encode(array_values($pie_hours));
The issue was with my values... The column "Valor" is defined as number, but the values was coming as strings with quotes...
Just removed the quotes from my JSON and it worked
{"cols":[{"id":"","label":"Loja","pattern":"","type":"string"},{"id":"","label":"Valor(R$)","pattern":"","type":"number"}],"rows":[{"c":[{"v":"Loja Shopping","f":null},{"v":8620.00,"f":null}]},{"c":[{"v":"Loja Centro","f":null},{"v":10240.00,"f":null}]}]}
Updated fiddle
Related
So What I am doing is that I am taking timestamp data as X axis and the values as Y-axis.
but the problem arises is that the data is not displaying on the chart althogh the timestamp values are being displayed in the console, but not displaying on chart.
the data values are as follows:
var countArray = ["2020-14-03 11:14:48.225000","2020-14-03 11:14:48.226000","2020-14-03 11:14:48.227000","2020-14-03 11:14:48.228000","2020-14-03 11:14:48.229000","2020-14-03 11:14:48.230000","2020-14-03 11:14:48.231000","2020-14-03 11:14:48.232000","2020-14-03 11:14:48.233000","2020-14-03 11:14:48.234000","2020-14-03 11:14:48.235000","2020-14-03 11:14:48.236000","2020-14-03 11:14:48.237000","2020-14-03 11:14:48.238000","2020-14-03 11:14:48.239000","2020-14-03 11:14:48.240000","2020-14-03 11:14:48.241000","2020-14-03 11:14:48.242000","2020-14-03 11:14:48.243000","2020-14-03 11:14:48.244000"]; //X-axis Values
var numArray = [2,5,3,6,4,6,3,6,3,6,3,7,3,6,3,5,3,5,6,3] ; // Y-axis Values
Here is the Fiddle That I am trying.
https://jsfiddle.net/abnitchauhan/wq4na5fy/
the main problem is that the data is not displaying as per the values above
You have set the shift argument in the addPoint method to true, which, combined with an empty data array, causes that points do not appear.
if (x > 1000) {
series.addPoint([x, y], true, false, false);
}
Live demo: https://jsfiddle.net/BlackLabel/xhok1d6e/
API Reference: https://api.highcharts.com/class-reference/Highcharts.Series#addPoint
You have to enable tooltip in highcharts option like below:
tooltip: {
enabled: true,
},
The tooltip's content is rendered from a subset of HTML.
Highcharts Tooltip document
Highcharts Tooltip API Reference
Following is my resultant chart
Here the value of legends Happy and Very Happy is 0, hence it is overlapping each other and unable to read. So, How can I hide these values and strike through the legends while loading itself like in the below image? And yes, it is a dynamically loaded chart.
Link - Reference Pie Chart
Thanks in advance.
I am posting this answer hoping that, it will be helpful for someone later. You can also post a better solution if found.
After some deep diving into the library the files, I realised that is there are no direct answers to my question. But we can achieve that by emptying the label text in case of 0 data values.
For that, we must edit the chart options as follows,
public pieChartOptions: ChartOptions = {
responsive: true,
legend: {
position: 'top',
},
plugins: {
datalabels: {
formatter: (value, ctx) => {
const label = ctx.chart.data.labels[ctx.dataIndex];
if (ctx.dataset.data[ctx.dataIndex] > 0)
return label + " : " + ctx.dataset.data[ctx.dataIndex];
else
return "" // retun empty if the data for label is empty
},
}
},
showLines: true,
spanGaps: true,
cutoutPercentage: 1,
rotation: 15, // rotate the chart
};
Here in the function returns empty value in case the data for the corresponding label is 0. Also I rotate the chart 15deg to make the labels horizontal align in most cases.
Reference - Chart.js documentation
Hence I achieved a better view to the user and the overlapping issues are resolved. Thanks.
I need to be able to add some custom info to the pie.info.contentsFunction in Zoomcharts. I have multiple charts on the page, each one created like so...
var pc = new PieChart({
pie: {
innerRadius: 0.5,
},
container: chartContainer1,
area: { height: 500 },
data:chartData,
toolbar: {
"fullscreen": true,
"enabled": true
},
info: {
contentsFunction: boomChartTT
}
});
In the "boomChartTT" function I need to know what chart is being hovered upon. I'd like to be able to do something like this...
info: {
contentsFunction: boomChartTT(i)
}
...where 'i' is the index of the chart.
The reason I need to know the chart index is because I have some other data saved in an indexed array for each chart. The index of the chart matches the index of the data.
EXAMPLE: if user hovers on a slice in chart2 I'd want to pass '2' to the boomChartTT function so I can access the totals data for that chart (say, totalsData[2]).
I've done this in the past with other chart libraries by simply adding a data attribute to the chart container to give me the index like so...
<div id="chartContainer1" data-index="1"></div>
...and then I'm able to access the chartContainer from the hover function (contentsFunction) and then get that index.
I don't want to add the totals data to the actual chart data because I'd have to add it to each slice which is redundant.
Is there a way to do this?
Please let me know if my post is unclear.
EDITED TO ADD:
I don't think it matters but here is the boomChartTT function:
function boomChartTT(data,slice){
var tt="<div class=\"charttooltip\">";
if(data.name==="Others" || data.name==="Previous"){return tt+=data.name+"</div>";}
//var thisData=dataSearch(totalsData[i],"REFERRINGSITE",data.id);
tt+="<h5 class=\"strong\">"+data.id+"</h5>"+oHoverTable.render(thisData)+"</div>";
return tt;
}
The commented line is where I would need the index (i) to to get the correct totalsData.
SOLVED. I simply added "chartIndex" to the data like so...
for(var i=0;i<r.length;i++){
var thisDataObj ={
id:r[i].REFERRINGSITE,
value:r[i].PCTOFSALES,
name:r[i].REFERRINGSITE,
chartIndex: arguments[1],//<----- arguments[1] is the chart index
style: { expandable: false, fillColor: dataSearch(dataRSList,"REFERRINGSITE",r[i].REFERRINGSITE)[0].COLOR }
};
chartData.preloaded.subvalues.push(thisDataObj);
}
Then in the boomChartTT function...
function boomChartTT(data,slice){
var tt="<div class=\"charttooltip\">";
if(data.name==="Others" || data.name==="Previous"){return tt+=data.name+"</div>";}
var thisData=dataSearch(totalsData[data.chartIndex-1],"REFERRINGSITE",data.id);
tt+="<h5 class=\"strong\">"+data.id+"</h5>"+oHoverTable.render(thisData)+"</div>";
return tt;
}
I feared that adding custom fields to the chart data would break the chart (which I believe I've experienced with other libraries). So, there you go.
I have several morris.js charts that populate from my databases depending on certain search terms. Im using the following code to build a "Legend" for my donut charts. The code works fine but Im struggling with adding both a number and text, I'm getting a console error:
ReferenceError: value not defined
Here is the code I'm currently using (works great):
// Build the Donut:
var donut = Morris.Donut({
element: 'donut',
data : donutParts,
colors: color_array
});
// Build the Legend:
donut.options.data.forEach(function(label, i){
var legendItem = $('<span></span>').text(label['label']).prepend('<i> </i>');
legendItem.find('i').css('backgroundColor', donut.options.colors[i]);
$('#legend').append(legendItem)
})
This will give me a legend with matching color squares with the appropriate labels eg:
[red] UK
But I want:
[red] # UK
I've tried using .integer and other variations like so:
// Build the Donut:
var donut = Morris.Donut({
element: 'donut',
data : donutParts,
colors: color_array
});
// Build the Legend:
donut.options.data.forEach(function(label, i){
var legendItem = $('<span></span>').text(label['label']).integer(['value']).prepend('<i> </i>');
legendItem.find('i').css('backgroundColor', donut.options.colors[i]);
$('#legend').append(legendItem)
})
But this gives me the error that value is not defined, i want to take the value(v) from donutParts
Here is my donutParts variable:
// Fetch the data to populate the donut chart:
var chartData = JSON.parse( $('#chartData').val() );
// Break up the object into parts of the donut:
var donutParts = [];
$.each( chartData, function(k,v){
donutParts.push({
label: k,
value: v
});
});
Any help? cheers!
ANSWER
The following code produces the desired output:
// Build the Legend:
donut.options.data.forEach(function(label, i){
var legendItem = $('<span></span>').text(label['value']+" "+label['label']).prepend('<i> </i>');
legendItem.find('i').css('backgroundColor', donut.options.colors[i]);
$('#legend').append(legendItem)
})
This is a SS of the legend output after implementing the given answer
Big thank you to #WillParky93
So what I said in the comments was technically wrong but after further reading this is what the 'donut.options.data.forEach' is doing.
Create an object dom of <span></span> -> add the text from label['label'] (which appears to be UK in your example) -> add some <i> tags.
THEN
Find the newly created tags -> add the CSS rule for background colour
THEN
add it to your #legend
So the solution was actually more simple when thinking of it like this; the answer be just this:
// Build the Legend:
donut.options.data.forEach(function(label, i){
var legendItem = $('<span></span>').text(label['value']+" "+label['label']).prepend('<i> </i>');
legendItem.find('i').css('backgroundColor', donut.options.colors[i]);
$('#legend').append(legendItem)
})
The change is in .text(label['label']) which is now .text(label['value']+" "+label['label'])
I am plotting a graph in XPages using QJplot. It was working fine before until I copied the entire process ie, buttons that extract data, buttons that plot data etc. Now for some reason I keep getting an error that says "An error has occurred while updating some of the page. $ is not a function." When I do a preview in the browser and look on the error console it highlights this "$(document).ready(function(){"
In the working version the code below is identical, the only difference is the values are extracted from a different view.
`<xp:scriptBlock id="scriptBlock" rendered="true">
<xp:this.value>
<![CDATA[$(document).ready(function(){
var line1 = #{javascript:return compositeData.Temp};
var line2 = #{javascript:return compositeData.MaxTemp};
var line3 = #{javascript:return compositeData.MinTemp};
var ticks1 = #{javascript:return compositeData.Time};
var plot1 = $.jqplot('chart3', [line1,line2,line3], {
title: '#{javascript: return compositeData.title}',
animate:#{javascript:return compositeData.animated},
seriesDefaults: {
renderer: $.jqplot.LineRenderer,
rendererOptions:{lineMargin: 25},
pointLabels:{show:true, stackedValue: true}
},
series:[
{label:'#{javascript:return compositeData.legendTemp}'},
{label:'#{javascript:return compositeData.legendMaxTemp}'},
{label:'#{javascript:return compositeData.legendMinTemp}'},
],
legend: {
show: #{javascript:return compositeData.legendShow},
placement: '#{javascript:return compositeData.legendPlacement}'
},
axes: {
xaxis:{
label: "Time (min)",
pad: 0,
renderer:$.jqplot.CategoryAxisRenderer,
ticks: ticks1
},
yaxis:{
label: "Temperature (Deg. C)"
}
}
});
});
]]>
</xp:this.value>
</xp:scriptBlock>`
The code which extracts values from the view is working too. The button that doesn't work is the one that is supposed to plot the graph.
<xp:button
value="Replot Chart" id="refresh_code_plot">
<xp:eventHandler
event="onclick" submit="true" refreshMode="partial"
refreshId="code_plot">
</xp:eventHandler>
</xp:button>
code_plot is the custom control which contains scriptBlock. It is linked to the XPages via this code
<xc:code_plot
id="code_plot" legendMaxTemp="Upper Threshold"
legendMinTemp="Lower Threshold" legendTemp="Data"
title="Logger Data (Temperature)" cssStyle="width:900px;">
<xc:this.animated><![CDATA[#{javascript:getComponent("animated").getValue();}]]></xc:this.animated>
<xc:this.Temp><![CDATA[#{javascript:getComponent("extracted_Temp").getValue();}]]></xc:this.Temp>
<xc:this.MaxTemp><![CDATA[#{javascript:getComponent("extracted_MaxTemp").getValue();}]]></xc:this.MaxTemp>
<xc:this.MinTemp><![CDATA[#{javascript:getComponent("extracted_MinTemp").getValue();}]]></xc:this.MinTemp>
<xc:this.legendShow><![CDATA[#{javascript:"true";}]]></xc:this.legendShow>
<xc:this.stackedSeries><![CDATA[#{javascript:getComponent("stackSeries").getValue();}]]></xc:this.stackedSeries>
<xc:this.ticks><![CDATA[#{javascript:getComponent("extracted_Time").getValue();}]]></xc:this.ticks>
<xc:this.Time><![CDATA[#{javascript:getComponent("extracted_Time").getValue();}]]></xc:this.Time>
<xc:this.legendPlacement><![CDATA[#{javascript:getComponent("extracted_Time").getValue()}]]></xc:this.legendPlacement>
</xc:code_plot>
Are there any obvious bugs in this?
Seems you are indeed missing your jquery link. Also simplify:
old:
{label:'#{javascript:return compositeData.legendTemp}'}
new:
{label:'#{compositeData.legendTemp}'}
Are you including jQuery on the main page? it doesn't recognize its namespace.
I fixed this bug. Because I am using different custom controls I didn't define one or two variables in the custom properties and this is why the button which is responsible for plotting the graph wasn't working. One of the other problems I had was in the extracted_Data ids. It is case sensitive and when I was transferring the buttons etc.. the case of some of the ids changed.