I'm drawing a chart with jqPlot, and in my template I've designed the chart so that it grows downwards, kind of flip the bars so that they start from the top and go down, depending on some input from the db. I was thinking of multiplying by -1, but it doesn't seem to work.
Any suggestions? Here is my code.
$(document).ready(function(){
$.jqplot.config.enablePlugins = true;
var c0 = "";
var c1 = "";
var c2 = "";
var c3 = "";
var c4 = "";
var c5 = "";
var c6 = "";
var c7 = "";
var c8 = "";
var c9 = "";
var a0 = "<?php echo $numArticles[0]?>";
var a1 = "<?php echo $numArticles[1]?>";
var a2 = "<?php echo $numArticles[2]?>";
var a3 = "<?php echo $numArticles[3]?>";
var a4 = "<?php echo $numArticles[4]?>";
var a5 = "<?php echo $numArticles[5]?>";
var a6 = "<?php echo $numArticles[6]?>";
var a7 = "<?php echo $numArticles[7]?>";
var a8 = "<?php echo $numArticles[8]?>";
var a9 = "<?php echo $numArticles[9]?>";
var s1 = [a0, a1, a2, a3, a4, a5,a6,a7,a8,a9];
var ticks = [c0, c1,c2,c3,c4,c5,c6,c7,c8,c9];
plot1 = $.jqplot('chart1', [s1], {
// Only animate if we're not using excanvas (not in IE 7 or IE 8)..
animate: !$.jqplot.use_excanvas,
seriesDefaults:{
shadow: false,
renderer:$.jqplot.BarRenderer,
pointLabels: { show: true }
},
axes: {
xaxis: {
renderer: $.jqplot.CategoryAxisRenderer,
ticks: ticks,
showTickMarks:false
},
yaxis: {
renderer: $.jqplot.CategoryAxisRenderer,
ticks: ticks,
showTicks: false // same options as axesDefaults
}
},
grid: {
drawGridLines: false, // wether to draw lines across the grid or not.
gridLineColor: '#0d1c26', // *Color of the grid lines.
background: 'transparent', // CSS color spec for background color of grid.
borderColor: '#122934', // CSS color spec for border around grid.
borderWidth: 0, // pixel width of border around grid.
shadow: false // draw a shadow for grid.
// CanvasGridRenderer takes no additional options.
},
seriesColors: [ "#0a3b4c"],
highlighter: { show: false }
});
$('#chart1').bind('jqplotDataClick',
function (ev, seriesIndex, pointIndex, data) {
$('#info1').html('series: '+seriesIndex+', point: '+pointIndex+', data: '+data);
}
);
});
</script>
EDIT:
This answer is only relevant for PieRenderer, not for BarRenderer that is used in question.
Not sure about flipping, but maybe setting "startAngle" to 180 might do the trick?
plot1 = jQuery.jqplot ('chart1', [data],
{
seriesDefaults: {
renderer: jQuery.jqplot.PieRenderer,
rendererOptions: {
startAngle : 180
}
},
... other stuff ...
}
For reference, other renderer options: http://www.jqplot.com/docs/files/plugins/jqplot-pieRenderer-js.html
Related
Is it possible to draw a target line on pie chart?
For example, goal is 90% but installed is 70% and not-installed is 30%. I need to show the goal as dotted line as shown in the image below.
You can use the render event of the grid to draw the dotted line on the chart. I would use the visual property of the series to get the center point and radius of the pie, then in the render, draw a path from the pie center at the correct angle.
WORKING DEMO
var center;
var radius;
$("#chart").kendoChart({
theme: "Bootstrap",
legend: {visible: true,position: "bottom"},
seriesDefaults: { labels: {visible: false, }},
series: [{
type: "pie",
data: [{
category: "Installed",value: 45,color: "#52B84D"
}, {
category: "Not Installed",value: 25,color: "#E64F49"
}],
visual: function(e) {
//use this function to get the center and radius
//for use in the render function
center = e.center;
radius = e.radius;
// return the default visual element
return e.createVisual();
},
}],
render: function(e){
var draw = kendo.drawing;
var geom = kendo.geometry;
var chart = e.sender;
//angle is 90% of 270 because 0 is horizontal
var cornerRad = (0.9 * 270) * Math.PI / 180;
var nx = Math.cos(cornerRad)*radius + center.x;
var ny = Math.sin(cornerRad)*radius + center.y;
// The center and radius are populated by now.
var path = new draw.Path({
stroke: {
color: "#000",
width: 2,
dashType: "dash"
}
});
path.moveTo(center).lineTo(nx, ny, 0).close();
// Draw it on the Chart drawing surface
chart.surface.draw(path);
}
});
I wanted to display the labels just like how it is done here, within chartjs documentation samples.
However, along with one label, I want to display another label beside the first label. Both the labels have different font colors. Something like this:
Is that possible? If yes, kindly let me know how can that be achieved.
Currently I am able to display one label using following code:
Chart.plugins.register({
afterDatasetsDraw: function(chart, easing) {
// To only draw at the end of animation, check for easing === 1
var ctx = chart.ctx;
chart.data.datasets.forEach(function (dataset, i) {
var meta = chart.getDatasetMeta(i);
if (!meta.hidden) {
meta.data.forEach(function(element, index) {
// Draw the text in black, with the specified font
ctx.fillStyle = 'rgb(0, 0, 0)';
var fontSize = 16;
var fontStyle = 'normal';
var fontFamily = 'Helvetica Neue';
ctx.font = Chart.helpers.fontString(fontSize, fontStyle, fontFamily);
// Just naively convert to string for now
var dataString = dataset.data[index].toString();
// Make sure alignment settings are correct
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
var padding = 5;
var position = element.tooltipPosition();
ctx.fillText(dataString, position.x, position.y - (fontSize / 2) - padding);
});
}
});
}
});
Yes, that is possible. You can achieve that using the following chart plugin :
Chart.plugins.register({
afterDatasetsDraw: function(chart, ease) {
var barLabels = chart.options.barLabels;
if (!barLabels) return;
var ctx = chart.ctx;
chart.data.datasets.forEach(function(dataset, index) {
var meta = chart.getDatasetMeta(index);
if (!meta.hidden) {
meta.data.forEach(function(segment, index) {
var model = segment._model,
position = segment.tooltipPosition(),
x = position.x,
y = position.y,
height = model.height,
padding = height / 4;
ctx.save();
ctx.textBaseline = 'middle';
ctx.font = 'bold ' + height / 2 + 'px Arial';
ctx.fillStyle = '#777'; //first label's font color
var text1 = barLabels.first[index],
text2 = barLabels.second[index],
textWidth = ctx.measureText(text1).width + padding;
ctx.fillText(text1, x + padding, y);
ctx.fillStyle = '#000'; //second label's font color
ctx.fillText(text2, x + padding + textWidth, y);
ctx.restore();
});
}
});
}
});
To utilize the plugin, define the following properties in your chart options :
barLabels: {
first: ['0.4M', '1.6M', '0.6M', '0.7M', '1.5M'],
second: ['19.3%', '19.1%', '14.1%', '9.0%', '8.9%']
}
ᴡᴏʀᴋɪɴɢ ᴇxᴀᴍᴘʟᴇ ⧩
Chart.plugins.register({
afterDatasetsDraw: function(chart, ease) {
var barLabels = chart.options.barLabels;
if (!barLabels) return;
var ctx = chart.ctx;
chart.data.datasets.forEach(function(dataset, index) {
var meta = chart.getDatasetMeta(index);
if (!meta.hidden) {
meta.data.forEach(function(segment, index) {
var model = segment._model,
position = segment.tooltipPosition(),
x = position.x,
y = position.y,
height = model.height,
padding = height / 4;
ctx.save();
ctx.textBaseline = 'middle';
ctx.font = 'bold ' + height / 2 + 'px Arial';
ctx.fillStyle = '#777'; //first label's font color
var text1 = barLabels.first[index],
text2 = barLabels.second[index],
textWidth = ctx.measureText(text1).width + padding;
ctx.fillText(text1, x + padding, y);
ctx.fillStyle = '#000'; //second label's font color
ctx.fillText(text2, x + padding + textWidth, y);
ctx.restore();
});
}
});
}
});
var chart = new Chart(ctx, {
type: 'horizontalBar',
data: {
labels: ['Jan', 'Feb', 'Mar', 'Apr', 'May'],
datasets: [{
label: 'Statistics',
data: [1, 4, 2, 3, 4],
backgroundColor: ['#fd625e', '#01b8aa', '#01b8aa', '#01b8aa', '#fd625e'],
}]
},
options: {
scales: {
xAxes: [{
ticks: {
beginAtZero: true,
stepSize: 1,
max: 6
}
}]
},
barLabels: {
first: ['0.4M', '1.6M', '0.6M', '0.7M', '1.5M'],
second: ['19.3%', '19.1%', '14.1%', '9.0%', '8.9%']
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.6.0/Chart.min.js"></script>
<canvas id="ctx"></canvas>
[[["09251A0428",90],["10251A0547",37]],[["09251A0428",4],["10251A0547",54]]]
Above data contains two series. x values of each series are same. if the x values are numeric the jqplot displays line chart with two series as normal. but we need to display strings on x axis and for each string corresponding series values.
How to set strings on xaxis for multiple series line chart of jqplot?
I have preapared an example for you based on the data you gave:
JsFiddle link
$.jqplot.config.enablePlugins = true;
var chartData = [[["09251A0428",90],["10251A0547",37]],[["09251A0428",4],["10251A0547",54]]];
function PlotChart(chartData) {
var plot2 = $.jqplot('chart1', chartData, {
title: 'Mouse Cursor Tracking',
seriesDefaults: {
pointLabels: {
show: true
}
},
axes: {
xaxis: {
pad: 1,
// a factor multiplied by the data range on the axis to give the
renderer: $.jqplot.CategoryAxisRenderer,
// renderer to use to draw the axis,
tickOptions: {
formatString: '%b %#d'
}
},
yaxis: {
}
},
highlighter: {
sizeAdjust: 7.5
},
cursor: {
show: true
}
});
}
PlotChart(chartData);
hFollowing is the code for barclustered jqplot. can anyone please guide me gow to create a highlighted array in following code dynamically
$(document).ready(function(){
// For horizontal bar charts, x an y values must will be "flipped"
// from their vertical bar counterpart.
var plot2 = $.jqplot('chart2', [
[[2,1], [4,2], [6,3], [3,4]],
[[5,1], [1,2], [3,3], [4,4]],
[[4,1], [7,2], [1,3], [2,4]]], {
seriesDefaults: {
renderer:$.jqplot.BarRenderer,
// Show point labels to the right ('e'ast) of each bar.
// edgeTolerance of -15 allows labels flow outside the grid
// up to 15 pixels. If they flow out more than that, they
// will be hidden.
pointLabels: { show: true, location: 'e', edgeTolerance: -15 },
// Rotate the bar shadow as if bar is lit from top right.
shadowAngle: 135,
// Here's where we tell the chart it is oriented horizontally.
rendererOptions: {
barDirection: 'horizontal'
}
},
axes: {
yaxis: {
renderer: $.jqplot.CategoryAxisRenderer
}
}
});
});
You have a problem with your Javascript syntax and algorithm. The loop should looks like :
VData="9,453,470,232|488,378,375,142|365,275,255,434|217,317,479,89";
var a = new Array();
var split_fst = VData.split("|")
for(m=0;m<split_fst.length;m++) {
var split_snd = split_fst[m].split(",");
a[m] = new Array();
for(j=0;j<split_snd.length;j++){
a[m][j]=split_snd[j];
}
}
Your a variable now looks like : `[["9","453","470","232"],["488","378","375","142"],["365","275","255","434"],["217","317","479","89"]]
I am creating an enyo Control based on a canvas. It should capture mouse or finger events, and draw them onto it. However when I draw onto that canvas it draws only into a smaller part of it.
Look at that jsfiddle as it contains all relevant code.
enyo.kind({
name: "SignatureControl",
kind: "enyo.Canvas",
recording: false,
points: [],
handlers: {
ondown: "startRecord",
onmove: "record",
onup: "stopRecord"
},
startRecord: function(inSender, inEvent) {
this.recording = true;
if(node = this.hasNode()) {
this.points.push({
x: inEvent.clientX - node.offsetLeft,
y: inEvent.clientY - node.offsetTop,
d: false,
p: 1
});
}
this.update();
},
stopRecord: function() {
this.recording = false;
},
record: function(inSender, inEvent) {
if( this.recording ) {
if(node = this.hasNode()) {
this.points.push({
x: inEvent.clientX - node.offsetLeft,
y: inEvent.clientY - node.offsetTop,
d: true,
p: 1
});
}
this.update();
}
},
update: function() {
var canvas = this.hasNode();
if (canvas.getContext) {
var ctx = canvas.getContext('2d');
this.log(ctx.canvas.width);
ctx.lineJoin = "round";
ctx.lineWidth = 1;
var i = this.points.length - 1;
ctx.strokeStyle = "rgba(0,0,0," + this.points[i].p + ")";
ctx.beginPath();
if(this.points[i].d && i){
ctx.moveTo(this.points[i-1].x, this.points[i-1].y);
}else{
ctx.moveTo(this.points[i].x-1, this.points[i].y);
}
ctx.lineTo(this.points[i].x, this.points[i].y);
ctx.closePath();
ctx.stroke();
}
}
});
You can only use the height/width attributes on the canvas, not size it via CSS. Check out this updated fiddle http://jsfiddle.net/AFqvD/4/
The relevant portion is:
{kind: "SignatureControl", attributes: {height: 150, width: 300}}