I have a gRaphael line chart which I update on click using the below function, the problem I have is that when I try to set the column values, it does not take effect. Like so...
var iniGraph = Raphael("graph"),
chart = iniGraph.linechart(
0,5,
$('#graph').width(),$('#graph').height(),
xVals,yVals,
{ nostroke: false, symbol: ["circle",""], width: 1.5, smooth: true, shade: true, colors: ['#008cc2', '#7500c6'] }
).hoverColumn(function(){
// AFTER UPDATE THESE VALUES STILL REMAIN UNCHANGED
console.log(this.values[0]+" | "+this.values[1]);
},function(){
// do nothing
});
function animateChart(graph,curChart,newX,newY)
{
// generate the new chart
var newChart = graph.linechart(
0,5,
$('#graph').width(),$('#graph').height(),
newX,
newY,
{ nostroke: false, symbol: ["circle",""], width: 1.5, smooth: true, shade: true, colors: ['#008cc2', '#7500c6'] }
);
// THIS DOES NOT WORK, THE ORIGINAL VALUES REMAIN AFTER UPDATE
curChart.eachColumn(function(){
this.values[0] = 12341234;
this.values[1] = 12341234;
});
// animate the symbols
$.each(curChart.symbols[0],function(i,symbol){
symbol.animate({ cx: newChart.symbols[0][i].attr("cx"),cy: newChart.symbols[0][i].attr("cy") }, 200);
});
// animate the lines
$.each(curChart.lines,function(i,line){
line.animate({ path: newChart.lines[i].attr("path") }, 200);
});
// remove the new chart
newChart.remove();
}
I create an initial graph and create the line chart, I then use the animateChart function to animate/update the line chart to it's new values, the problem I am running into is that on hover, the values remain unchanged after the animateChart function has run, so I am stuck with the initial values of the chart, which is not ideal, as I have to get the column values to update to the new values I specify.
So basically, how can I update the column values when I animate/update the line chart?
I'm kinda at the end of my rope... thanks.
Related
I am facing a rather troublesome problem with chart as follows:
I want to remove the outermost border and keep the inner lines, but the chart doesn't allow me to do that. I tried using 'drawBorder: false', but it still doesn't work. Is there any way to handle this?
How to remove the value of the origin x-Axis and Y-Axis?
please refer to the image
How to edit the value of A-Xis? I want it to increase by 1000 each time on the X-Axis.
image
Setting the scales option like this:
scales: {
y: {
grid: {
drawBorder: false, // <-- this removes y-axis line
lineWidth: function (context) {
return context?.index === 0 ? 0 : 1; // <-- this removes the base line
}
}
},
x: {
grid: {
drawBorder: false,
lineWidth: 0 // <-- this removes vertical lines between bars
}
}
}
should achieve the desired look. Check out this code sandbox with an example.
You can find more information about styling the chart here.
Have some trouble with Chart.js
1) is it possible to move bottom labels on top of the chart?
2) is it possible to hide left labels with first grey line?
3) is it possible to set up permanent tooltips(to show temperature) on every point instead of hover tooltips?
Here is my chart http://jsfiddle.net/JohnnyJuarez/ojc09hv4/:
<canvas id="weeksChart" width="651" height="335"></canvas>
var dayTemperatureArray = [-5, 14, 15, 15, 17, 18, 19, 21, 22, 25, 24, 20, 19, 16];
var nightTemperatureArray = [-10, 4, 5, 6, 8, 11, 12, 15, 17, 15, 13, 12, 11, 9];
var dataWeeks = {
labels: ["16.02", "17.02", "18.02", "19.02", "20.02", "21.02", "22.02", "23.02", "24.02", "25.02", "26.02", "27.02", "28.02", "01.03"],
datasets: [
{
label: "Days temperature chart",
fillColor: "transparent",
strokeColor: "rgba(244, 6, 6, 1)",
data: dayTemperatureArray
},
{
label: "Nights temperature chart",
strokeColor: "#3f6bf5",
data: nightTemperatureArray
}
]
};
var ctx = document.getElementById("weeksChart").getContext("2d");
window.weeksChart = new Chart(ctx).Line(dataWeeks, {
responsive: true,
pointDot: true,
datasetStrokeWidth: 0.5,
scaleSteps: 2,
scaleLabel: "<%=value + '°'%>",
tooltipTemplate: "<%= value %>",
showTooltips: true
});
Thanx a lot in advance!
p.s. please avoid jquery, if it's possible :-)
Let's start with the easiest one first
2) is it possible to hide left labels with first grey line?
I assume you meant the y axis labels. You can set the scaleShowLabels option to false in the chart options to hide the y axis labels
window.weeksChart = new Chart(ctx).Line(dataWeeks, {
scaleShowLabels: false,
...
1) is it possible to move bottom labels on top of the chart?
I assume you mean the x axis labels. Chart.js doesn't have a direct option to do this. However you can hide the actual x axis labels and draw the x axis labels at the top of the chart by yourself.
Again, Chart.js doesn't have an option to hide x axis labels, but luckily there is an option to control the scale font color. Just set it to transparent and your original x axis labels are now hidden!
window.weeksChart = new Chart(ctx).Line(dataWeeks, {
scaleFontColor: "transparent",
...
Now the drawing of the x axis labels at the top of the chart. To save us the trouble of extending the chart, we can add a post animation event handler and do this in that, like so
window.weeksChart = new Chart(ctx).Line(dataWeeks, {
onAnimationComplete: function () {
animationComplete.apply(this)
}
...
with
var animationComplete = function () {
var self = this;
Chart.helpers.each(self.datasets[0].points, function (point, index) {
self.chart.ctx.font = Chart.helpers.fontString(self.fontSize, self.fontStyle, self.fontFamily)
self.chart.ctx.textAlign = 'center';
self.chart.ctx.textBaseline = "middle";
self.chart.ctx.fillStyle = "#666";
self.chart.ctx.fillText(point.label, point.x, self.scale.startPoint);
});
};
We just loop through all points in one of the dataset and add the labels (scale.startPoint is the top edge of the chart area)
Note - why do we set the font, alignment, etc. every iteration? That's for when we add the tooltips.
3) is it possible to set up permanent tooltips(to show temperature) on every point instead of hover tooltips?
The first step would be to actually show the tooltips. This is fairly simple, though a bit tedious. We loop through all the x axis point, build the label (by going through each dataset) and then construct a tooltip (fortunately, we can use Chart.MultiTooltip function for this.
We add it into the same loop we used to construct the new x axis labels. Since we need to color our tooltips, we need to get and store the set of colors in an array (which we pass on to the MultiTooltip function - we need to do this only once, so we take it out of the loop.
The modified animationComplete function is now this
var animationComplete = function () {
var self = this;
var tooltipColors = []
Chart.helpers.each(self.datasets, function (dataset) {
tooltipColors.push({
fill: dataset.strokeColor,
stroke: dataset.strokeColor
})
});
Chart.helpers.each(self.datasets[0].points, function (point, index) {
var labels = []
var total = 0;
Chart.helpers.each(self.datasets, function (dataset) {
labels.push(dataset.points[index].value)
total += Number(dataset.points[index].y);
});
new Chart.MultiTooltip({
x: point.x,
y: total / 2,
xPadding: self.options.tooltipXPadding,
yPadding: self.options.tooltipYPadding,
xOffset: self.options.tooltipXOffset,
fillColor: self.options.tooltipFillColor,
textColor: self.options.tooltipFontColor,
fontFamily: self.options.tooltipFontFamily,
fontStyle: self.options.tooltipFontStyle,
fontSize: self.options.tooltipFontSize,
titleTextColor: self.options.tooltipTitleFontColor,
titleFontFamily: self.options.tooltipTitleFontFamily,
titleFontStyle: self.options.tooltipTitleFontStyle,
titleFontSize: self.options.tooltipTitleFontSize,
cornerRadius: self.options.tooltipCornerRadius,
labels: labels,
legendColors: tooltipColors,
legendColorBackground: self.options.multiTooltipKeyBackground,
title: point.label,
chart: self.chart,
ctx: self.chart.ctx,
custom: self.options.customTooltips
}).draw()
self.chart.ctx.font = Chart.helpers.fontString(self.fontSize, self.fontStyle, self.fontFamily)
self.chart.ctx.textAlign = 'center';
self.chart.ctx.textBaseline = "middle";
self.chart.ctx.fillStyle = "#666";
self.chart.ctx.fillText(point.label, point.x, self.scale.startPoint);
});
};
It looks complex, but all we are doing is passing a options that we copy from the chart instance options to the MultiTooltip function.
The tooltips all show up when the animation is complete. HOWEVER, once you move your mouse over the chart they all up and disappear! That's because the chart instance listens for multiple events to decide whether to start checking if tooltips should be shown - one of these is mousemove (and that causes it to redraw the chart, wiping out all our hard drawn tooltips and, if we are lucky, it draws a tooltip based on the point our mouse is hovering over)
This is a configurable option. So, all we have to do is remove all such events.
window.weeksChart = new Chart(ctx).Line(dataWeeks, {
tooltipEvents: []
...
Working fiddle - http://jsfiddle.net/fuodxsfv/
Unless your chart is wide enough, you will have tooltips (mostly the middle 2 ones) overlap (of course you could incorporate logic into the above loop to handle that), but anyhoo, those were actually meant to be tooltips!
I am working on a personal project creating graphs to show data about my music listening habits from Last FM's API.
I am grabbing the JSON data via an AJAX request and then using the returned JSON objects to populate a graph created using the Chartist.js JS library.
I'm having what I consider a quite straightforward issue in that I can't work out how to increase the overall size of the chart? To be more specific I'd like to increase the spacing between each scale point on the Y axis so that you can see more accurately what each figure is.
I have created the following JS Fiddle to show my problem:
http://jsfiddle.net/jt96usn9/
According to the documentation, I believe I need to change an option attribute known as scaleMinSpace but upon changing this figure no changes seem to occur.
Any help would be great?!
var lastfm = {};
lastfm.tracker = (function(){
//Set up an object for DOM elements and data source
var config = {
getRecentTracksURL: "http://ws.audioscrobbler.com/2.0/?method=user.getrecenttracks&user=jimmersjukebox&api_key=6db1989bd348bf91797bad802c6645d8&format=json",
getMostPopularArtistsURL: "http://ws.audioscrobbler.com/2.0/?method=user.gettopartists&user=jimmersjukebox&api_key=6db1989bd348bf91797bad802c6645d8&format=json",
user: "jimmersjukebox",
recentTracksElement: $(".recent-tracks"),
currentlyPlayingActiveClass: $(".current")
};
var setupLastFM = function(){
createPopularArtistsChart();
};
var createPopularArtistsChart = function(){
$.getJSON(config.getMostPopularArtistsURL,function(data){
var artistData = data.topartists.artist,
artists = $.map(artistData, function(artist) {
return [[artist.name]];
}),
playcounts = $.map(artistData, function(playcount) {
return [[playcount.playcount]];
});
// These are the default options of the line chart
var options = {
// Options for X-Axis
axisX: {
// The offset of the labels to the chart area
offset: 10,
// If labels should be shown or not
showLabel: true,
// If the axis grid should be drawn or not
showGrid: true,
// Interpolation function that allows you to intercept the value from the axis label
labelInterpolationFnc: function(value){return value;}
},
// Options for Y-Axis
axisY: {
scaleMinSpace: 100
},
// Specify a fixed width for the chart as a string (i.e. '100px' or '50%')
width: undefined,
// Specify a fixed height for the chart as a string (i.e. '100px' or '50%')
height: undefined,
// If the line should be drawn or not
showLine: true,
// If dots should be drawn or not
showPoint: true,
// Specify if the lines should be smoothed (Catmull-Rom-Splines will be used)
lineSmooth: true,
// Overriding the natural low of the chart allows you to zoom in or limit the charts lowest displayed value
low: undefined,
// Overriding the natural high of the chart allows you to zoom in or limit the charts highest displayed value
high: undefined,
// Padding of the chart drawing area to the container element and labels
chartPadding: 15,
// Specify the distance in pixel of bars in a group
seriesBarDistance: 15,
// Override the class names that get used to generate the SVG structure of the chart
};
data = {
// A labels array that can contain any sort of values
labels: artists.slice(0,10),
// Our series array that contains series objects or in this case series data arrays
series: [
playcounts.slice(0,10)
]
};
// Create a new line chart object where as first parameter we pass in a selector
// that is resolving to our chart container element. The Second parameter
// is the actual data object.
Chartist.Bar('.ct-chart', data, options);
});
};
return{
config: config,
init: function(){
setupLastFM();
}
};
})();
$(window).load(lastfm.tracker.init);
/* Chartist.js 0.2.4
* Copyright © 2014 Gion Kunz
* Free to use under the WTFPL license.
* http://www.wtfpl.net/
*/
.ct-chart .ct-label{fill:rgba(0,0,0,.4);font-size:.75rem}.ct-chart .ct-grid{stroke:rgba(0,0,0,.2);stroke-width:1px;stroke-dasharray:2px}.ct-chart .ct-point{stroke-width:10px;stroke-linecap:round}.ct-chart .ct-line{fill:none;stroke-width:4px}.ct-chart .ct-area{stroke:none;fill-opacity:.1}.ct-chart .ct-bar{fill:none;stroke-width:10px}.ct-chart .ct-slice.ct-donut{fill:none;stroke-width:60px}.ct-chart .ct-series.ct-series-a .ct-bar,.ct-chart .ct-series.ct-series-a .ct-line,.ct-chart .ct-series.ct-series-a .ct-point,.ct-chart .ct-series.ct-series-a .ct-slice.ct-donut{stroke:#d70206}.ct-chart .ct-series.ct-series-a .ct-area,.ct-chart .ct-series.ct-series-a .ct-slice:not(.ct-donut){fill:#d70206}.ct-chart .ct-series.ct-series-b .ct-bar,.ct-chart .ct-series.ct-series-b .ct-line,.ct-chart .ct-series.ct-series-b .ct-point,.ct-chart .ct-series.ct-series-b .ct-slice.ct-donut{stroke:#F05B4F}.ct-chart .ct-series.ct-series-b .ct-area,.ct-chart .ct-series.ct-series-b .ct-slice:not(.ct-donut){fill:#F05B4F}.ct-chart .ct-series.ct-series-c .ct-bar,.ct-chart .ct-series.ct-series-c .ct-line,.ct-chart .ct-series.ct-series-c .ct-point,.ct-chart .ct-series.ct-series-c .ct-slice.ct-donut{stroke:#F4C63D}.ct-chart .ct-series.ct-series-c .ct-area,.ct-chart .ct-series.ct-series-c .ct-slice:not(.ct-donut){fill:#F4C63D}.ct-chart .ct-series.ct-series-d .ct-bar,.ct-chart .ct-series.ct-series-d .ct-line,.ct-chart .ct-series.ct-series-d .ct-point,.ct-chart .ct-series.ct-series-d .ct-slice.ct-donut{stroke:#453D3F}.ct-chart .ct-series.ct-series-d .ct-area,.ct-chart .ct-series.ct-series-d .ct-slice:not(.ct-donut){fill:#453D3F}.ct-chart.ct-square{display:block;position:relative;width:100%}.ct-chart.ct-square:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:100%}.ct-chart.ct-square:after{content:"";display:table;clear:both}.ct-chart.ct-square>svg{display:block;position:absolute;top:0;left:0}.ct-chart.ct-minor-second{display:block;position:relative;width:100%}.ct-chart.ct-minor-second:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:93.75%}.ct-chart.ct-minor-second:after{content:"";display:table;clear:both}.ct-chart.ct-minor-second>svg{display:block;position:absolute;top:0;left:0}.ct-chart.ct-major-second{display:block;position:relative;width:100%}.ct-chart.ct-major-second:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:88.8888888889%}.ct-chart.ct-major-second:after{content:"";display:table;clear:both}.ct-chart.ct-major-second>svg{display:block;position:absolute;top:0;left:0}.ct-chart.ct-minor-third{display:block;position:relative;width:100%}.ct-chart.ct-minor-third:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:83.3333333333%}.ct-chart.ct-minor-third:after{content:"";display:table;clear:both}.ct-chart.ct-minor-third>svg{display:block;position:absolute;top:0;left:0}.ct-chart.ct-major-third{display:block;position:relative;width:100%}.ct-chart.ct-major-third:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:80%}.ct-chart.ct-major-third:after{content:"";display:table;clear:both}.ct-chart.ct-major-third>svg{display:block;position:absolute;top:0;left:0}.ct-chart.ct-perfect-fourth{display:block;position:relative;width:100%}.ct-chart.ct-perfect-fourth:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:75%}.ct-chart.ct-perfect-fourth:after{content:"";display:table;clear:both}.ct-chart.ct-perfect-fourth>svg{display:block;position:absolute;top:0;left:0}.ct-chart.ct-perfect-fifth{display:block;position:relative;width:100%}.ct-chart.ct-perfect-fifth:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:66.6666666667%}.ct-chart.ct-perfect-fifth:after{content:"";display:table;clear:both}.ct-chart.ct-perfect-fifth>svg{display:block;position:absolute;top:0;left:0}.ct-chart.ct-minor-sixth{display:block;position:relative;width:100%}.ct-chart.ct-minor-sixth:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:62.5%}.ct-chart.ct-minor-sixth:after{content:"";display:table;clear:both}.ct-chart.ct-minor-sixth>svg{display:block;position:absolute;top:0;left:0}.ct-chart.ct-golden-section{display:block;position:relative;width:100%}.ct-chart.ct-golden-section:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:61.804697157%}.ct-chart.ct-golden-section:after{content:"";display:table;clear:both}.ct-chart.ct-golden-section>svg{display:block;position:absolute;top:0;left:0}.ct-chart.ct-major-sixth{display:block;position:relative;width:100%}.ct-chart.ct-major-sixth:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:60%}.ct-chart.ct-major-sixth:after{content:"";display:table;clear:both}.ct-chart.ct-major-sixth>svg{display:block;position:absolute;top:0;left:0}.ct-chart.ct-minor-seventh{display:block;position:relative;width:100%}.ct-chart.ct-minor-seventh:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:56.25%}.ct-chart.ct-minor-seventh:after{content:"";display:table;clear:both}.ct-chart.ct-minor-seventh>svg{display:block;position:absolute;top:0;left:0}.ct-chart.ct-major-seventh{display:block;position:relative;width:100%}.ct-chart.ct-major-seventh:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:53.3333333333%}.ct-chart.ct-major-seventh:after{content:"";display:table;clear:both}.ct-chart.ct-major-seventh>svg{display:block;position:absolute;top:0;left:0}.ct-chart.ct-octave{display:block;position:relative;width:100%}.ct-chart.ct-octave:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:50%}.ct-chart.ct-octave:after{content:"";display:table;clear:both}.ct-chart.ct-octave>svg{display:block;position:absolute;top:0;left:0}.ct-chart.ct-major-tenth{display:block;position:relative;width:100%}.ct-chart.ct-major-tenth:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:40%}.ct-chart.ct-major-tenth:after{content:"";display:table;clear:both}.ct-chart.ct-major-tenth>svg{display:block;position:absolute;top:0;left:0}.ct-chart.ct-major-eleventh{display:block;position:relative;width:100%}.ct-chart.ct-major-eleventh:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:37.5%}.ct-chart.ct-major-eleventh:after{content:"";display:table;clear:both}.ct-chart.ct-major-eleventh>svg{display:block;position:absolute;top:0;left:0}.ct-chart.ct-major-twelfth{display:block;position:relative;width:100%}.ct-chart.ct-major-twelfth:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:33.3333333333%}.ct-chart.ct-major-twelfth:after{content:"";display:table;clear:both}.ct-chart.ct-major-twelfth>svg{display:block;position:absolute;top:0;left:0}.ct-chart.ct-double-octave{display:block;position:relative;width:100%}.ct-chart.ct-double-octave:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:25%}.ct-chart.ct-double-octave:after{content:"";display:table;clear:both}.ct-chart.ct-double-octave>svg{display:block;position:absolute;top:0;left:0}
<script src="//cdnjs.cloudflare.com/ajax/libs/chartist/0.2.4/chartist.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<div class="chart-container">
<div class="ct-chart"></div>
</div>
if you give height in the options like
var options = {
seriesBarDistance: 10,
fullWidth: true,
showArea:true,
height:'500px'
};
new Chartist.Bar('.ct-chart', dataArray, options, responsiveOptions );
It will increase the overall height and spacing too.
Thanks
Kiran.
If the area is very small then the labels are getting overlapped in the donut chart.
How to place the data labels outside the donut chart with lines.
Currently I am able to draw the labels inside the chart. Find the sample code from here:
$(document).ready(function(){
var s1 = [['a',6], ['b',8], ['c',14], ['d',20]];
var plot3 = $.jqplot('chart4', [s1], {
seriesDefaults: {
// make this a donut chart.
renderer:$.jqplot.DonutRenderer,
rendererOptions:{
// Donut's can be cut into slices like pies.
sliceMargin: 3,
// Pies and donuts can start at any arbitrary angle.
startAngle: -90,
showDataLabels: true,
// By default, data labels show the percentage of the donut/pie.
// You can show the data 'value' or data 'label' instead.
dataLabels: 'value'
}
}
});
});
fiddle
This is my expected output:
Helps much appreciated
Ok, what you need to set is:
dataLabelPositionFactor: 2
Please see jsFiddle here:
http://jsfiddle.net/9gXc3/1/
And further info here:
http://www.jqplot.com/docs/files/plugins/jqplot-donutRenderer-js.html
Update
I'd also set the padding too to avoid overlap i.e.
padding: 50
http://jsfiddle.net/9gXc3/3/
Use, dataLabelPositionFactor: 1.2, inside rendererOptions.
Below is an example I used in a project:
rendererOptions: {
padding: 8,
showDataLabels: true,
dataLabels: percentage,
dataLabelFormatString: '%s%%',
diameter: 300,
dataLabelPositionFactor: 1.1,
sliceMargin: 4,
startAngle: -90,
color: '#DCDCDC'
}
I have javascript code as:
var plot1 = jQuery.jqplot ('chartdiv', [data],
{
seriesDefaults: {
// Make this a pie chart.
renderer: jQuery.jqplot.PieRenderer,
rendererOptions: {
// Put data labels on the pie slices.
// By default, labels show the percentage of the slice.
showDataLabels: true,
dataLabels: 'value'
}
},
legend: { show:true, location:'e'}
});
var handler = function(ev, gridpos, datapos, neighbor, plot) {
if (neighbor) {
alert('x:' + neighbor.data[0] + ' y:' + neighbor.data[1]);
}
};
$.jqplot.eventListenerHooks.push(['jqplotClick', handler]);
Now by using dataLabels: 'value' I am able to show values but shown value is 51 instead of 50.667.Value is rounded.But I need to show exact value.How to this??
My second question is that When I have mouse pointer on any region of the chart I want to show something.Is that would be done using jqplotDataMouseOver But how to use it?
Your first question can be solved with the dataLabelFormatString property:
seriesDefaults: {
// Make this a pie chart.
renderer: jQuery.jqplot.PieRenderer,
rendererOptions: {
// Put data labels on the pie slices.
// By default, labels show the percentage of the slice.
showDataLabels: true,
dataLabels: 'value',
dataLabelFormatString:'%.4f'
}
},
The '%.4f' would show 4 decimal places.
Your second question is more difficult. Apparently events on bar charts are not quite ironed out with jqplot. But the last suggestion in that link works for me:
$('#chartdiv').bind('jqplotDataMouseOver', function (ev, seriesIndex, pointIndex, data) { alert('series: '+seriesIndex+', point: '+pointIndex+', data: '+data)});
Here's a jsfiddle, remember to cache the JS files since jqplot does not allow hotlinking.