Is there any way to display one polyline with two different colours(ex: based on road speed limit) in leaflet by using shiny? Any help could be highly appreciated.
You can use this plugin : http://hgoebl.github.io/Leaflet.MultiOptionsPolyline/demo/
You will have to define the speed for each point in your GeoJSON properties.
Then you simply have to add this code after :
var myPolyline = L.multiOptionsPolyline(YourGeoJSONHere, {
multiOptions: {
optionIdxFn: function (latLng) {
var i,
speedThresholds = [5, 10, 15, 30];
for (i = 0; i < speedThresholds.length; ++i) {
if (latLng.alt <= speedThresholds[i]) {
return i;
}
}
return speedThresholds.length;
},
options: [
{color: '#0000FF'}, {color: '#0040FF'},
{color: '#0080FF'}, {color: '#00FFB0'}
]
},
weight: 5,
opacity: 0.9,
smoothFactor: 1
}).addTo(layerTrace);
For the speed : https://github.com/hgoebl/Leaflet.MultiOptionsPolyline/blob/master/demo/js/demo.js#L59-L80
I am new to Chart.Js and facing issues on click event on bar chart. I would like to get the repective x-axis lable on click function . But I am receiving error "barchart.getElementsAtEvent is not a function at HTMLCanvasElement.Graphinit.document.getElementById.onclick". I really do not understand what exactly is wrong in my code.
I am calling the below function to generate bar chart The min, item are data array for x-axis & yaxis.
cdn : "https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.5.0/Chart.js"
var barchart;
function Graphinit(min, item, labelstring, stepcount, scaleStepWidth, reporttype, min1, item1) {
$('#myChart').remove(); // this is my <canvas> element
$('#showgraph').append(' <canvas id="myChart" width="1200" height="400"></canvas>');
inputdata = min;
xaxislabel = item;
Chart.types.Bar.extend({
name: "BarAlt",
draw: function () {
Chart.types.Bar.prototype.draw.apply(this, arguments);
var ctx = this.chart.ctx;
ctx.save();
// text alignment and color
ctx.textAlign = "center";
ctx.textBaseline = "bottom";
ctx.fillStyle = this.options.scaleFontColor;
// position
var x = this.scale.xScalePaddingLeft * 0.4;
var y = this.chart.height / 2;
// change origin
ctx.translate(x, y)
// rotate text
ctx.rotate(-90 * Math.PI / 180);
ctx.fillText(this.datasets[0].label, 0, 0);
ctx.restore();
}
});
var bridgeDataPoints = [];
if ((reporttype === "Lines picked per user") || (reporttype === "Picks per item") || (reporttype === "Lines Picked by item class") || (reporttype == "Lines picked by customer") || (reporttype == "Total Lines Picked") || reporttype == "Skipped Lines") {
for (var j = 0; j < min.length; j++) {
var dataPoint = new DataPoint1(item[j], min[j]);
bridgeDataPoints.push(dataPoint);
}
}
var data = {
labels: bridgeDataPoints,
datasets: [{
label: labelstring,
fillColor: "rgba(255, 255, 255, 1)",
strokeColor: "rgba(220,220,220,1)",
pointColor: "rgba(220,220,220,1)",
pointStrokeColor: "#fff",
pointHighlightFill: "#fff",
pointHighlightStroke: "rgba(220,220,220,1)",
data: inputdata
}]
};
var barchartoptions = {
//Boolean - If we show the scale above the chart data
scaleOverlay: false,
//Boolean - If we want to override with a hard coded scale
scaleOverride: true,
//** Required if scaleOverride is true **
//Number - The number of steps in a hard coded scale
scaleSteps: stepcount,
//Number - The value jump in the hard coded scale
scaleStepWidth: scaleStepWidth,
//Number - The scale starting value
scaleStartValue: 0,
scaleEndValue: stepcount,
//String - Colour of the scale line
scaleLineColor: "rgba(0,0,0,.1)",
//Number - Pixel width of the scale line
scaleLineWidth: 1,
//Boolean - Whether to show labels on the scale
scaleShowLabels: true,
//Interpolated JS string - can access value
scaleLabel: " <%=value%>",
//String - Scale label font declaration for the scale label
scaleFontFamily: "'Arial'",
//Number - Scale label font size in pixels
scaleFontSize: 12,
//String - Scale label font weight style
scaleFontStyle: "normal",
//String - Scale label font colour
scaleFontColor: "#666",
///Boolean - Whether grid lines are shown across the chart
scaleShowGridLines: true,
//String - Colour of the grid lines
scaleGridLineColor: "rgba(0,0,0,.05)",
//Number - Width of the grid lines
scaleGridLineWidth: 1,
//Boolean - If there is a stroke on each bar
barShowStroke: true,
//Number - Pixel width of the bar stroke
barStrokeWidth: 2,
//Number - Spacing between each of the X value sets
barValueSpacing: 10,
//Number - Spacing between data sets within X values
barDatasetSpacing: 3,
//Boolean - Whether to animate the chart
animation: true,
//Number - Number of animation steps
animationSteps: 60,
//String - Animation easing effect
animationEasing: "easeOutQuart",
//Function - Fires when the animation is complete
onAnimationComplete: function (animation) {
//alert('onAnimationComplete')
},
tooltipTemplate: "<%if (label){%><%=label.tooltip%><%}%>"
};
barchartoptions.datasetFill = false;
var ctx = $("#myChart").get(0).getContext('2d');
ctx.canvas.height = 400; // setting height of canvas
ctx.canvas.width = 1200; // setting width of canvas
//var config = Chart.defaults.bar;
barchart = new Chart(ctx).BarAlt(data, barchartoptions);
var length = inputdata.length; //min1.length;
var backgroundcolorset = [];
for (var i = 0; i < length; i++) {
var rgb = [];
for (var j = 0; j < 3; j++) {
rgb.push(Math.floor(Math.random() * 255));
}
backgroundcolorset.push('rgb(' + rgb.join(',') + ')');
}
for (var j = 0; j < length; j++) {
barchart.datasets[0].bars[j].fillColor = backgroundcolorset[j]; //bar 1
}
barchart.update();
console.log()
//console.log(barchart.getElementAtEvent(e));
document.getElementById("myChart").onclick = function (evt) {
// var activePoints =
console.log(barchart);
var activePoints = barchart.getElementsAtEvent(evt);
};
} // end Graphinit
How do I hide values past the x-axis in chartjs 2.0? You will notice the chart juts past the -60 mark. The x-axis uses a time scale and I have the max and min values set.
Here's my chart configuration:
{
"type":"line",
"data":{
"datasets":[
{
"label":"Scatter Dataset",
"data":[
{
"x":"2016-09-16T16:36:53Z",
"y":88.46153846153845
},
...
{
"x":"2016-09-16T16:37:54Z",
"y":88.3076923076923
}
],
"pointRadius":0,
"backgroundColor":"rgba(0,0,255,0.5)",
"borderColor":"rgba(0,0,255,0.7)"
}
]
},
"options":{
"title":{
"display":true,
"text":"Water Level Over Last 60 Seconds"
},
"animation":false,
"scales":{
"xAxes":[
{
"type":"time",
"position":"bottom",
"display":true,
"time":{
"max":"2016-09-16T16:37:54Z",
"min":"2016-09-16T16:36:54.000Z",
"unit":"second",
"unitStepSize":5
},
"ticks":{
callback: function(value, index, values) {
return "-" + (60 - 5 * index);
}
}
}
],
"yAxes":[
{
"display":true,
"ticks":{
}
}
]
},
"legend":{
"display":false
}
}
}
You can achieve this using Chart.js plugins. They let you handle events occuring while creating, updating or drawing the chart.
Here, you'll need to affect before the chart is initialised :
// We first create the plugin
var cleanOutPlugin = {
// We affect the `beforeInit` event
beforeInit: function(chart) {
// Replace `ticks.min` by `time.min` if it is a time-type chart
var min = chart.config.options.scales.xAxes[0].ticks.min;
// Same here with `ticks.max`
var max = chart.config.options.scales.xAxes[0].ticks.max;
var ticks = chart.config.data.labels;
var idxMin = ticks.indexOf(min);
var idxMax = ticks.indexOf(max);
// If one of the indexes doesn't exist, it is going to bug
// So we better stop the program until it goes further
if (idxMin == -1 || idxMax == -1)
return;
var data = chart.config.data.datasets[0].data;
// We remove the data and the labels that shouldn't be on the graph
data.splice(idxMax + 1, ticks.length - idxMax);
data.splice(0, idxMin);
ticks.splice(idxMax + 1, ticks.length - idxMax);
ticks.splice(0, idxMin);
}
};
// We now register the plugin to the chart's plugin service to activate it
Chart.pluginService.register(cleanOutPlugin);
The plugin is basically a loop through the data to remove the values that shouldn't be displayed.
You can see this plugin working in a live example on jsFiddle.
For instance, the following chat with a min set to 2 and a max to 6 ...
... would give the following result :
I was wondering how I can make a simple bar chart that perhaps has day as the x-axis, with values 'today' and 'yesterday', and the y-axis as perhaps 'time' with corresponding values '1' and '2'. I guess I'm confused as to how to set text as the values for the x-axis, how to show the y axis, and what exactly r.g.axis does...
(I found an example using axis = r.g.axis(0,300,400,0,500,8,2) and I only know it's the xpos, ypos,width, ??, ?? num ticks, ??). Any insight would be great! Or a page with more fully featured bar chart examples (labels, etc). Thanks.
For the sake of all those googling this:
r.g.axis(x_start, y_start, x_width, from, to, steps, orientation, labels, type, dashsize)
x_start and y_start: distance of the axis text from the bottom left corner
x_width: position of the end of the text along the x axis
from and to: used to specify and range to use instead of using the labels argument
steps: is the number of ticks - 1
orientation: seems to specify x-axis vs. y-axis
type: is the type of tick mark used.
This was all deduced from the source code. I think I'll be switching to a charting library with documentation now...
The current code (Raphaeljs 2.0) has changed and has to be slightly adapted to use Raphael.g.axis instead of r.g.axis:
Raphael.g.axis(85,230,310,null,null,4,2,["Today", "Yesterday",
"Tomorrow", "Future"], "|", 0, r)
You're on the right track. You use g.axis and the positional arguments for setting the text is found in the 'text' arg (positional) and for toggling the y using the 'orientation' args. I added an example here,
Barchart with text x-axis
Reading this Q&A and a dozen like it, I still could not get gRaphaƫl to show proper labels for a bar chart. The recipes all seemed to refer to older versions of the library, or to github pages that are no longer there. gRaphaƫl produces some great looking output--but its docs leave much to be desired.
I was, however, able to use a combination of Firebug and Inspect This Element to follow the code and see what it produced. Diving into the barchart object, the required geometry is right there. To save others the frustration, here's how I solved the problem:
<script>
function labelBarChart(r, bc, labels, attrs) {
// Label a bar chart bc that is part of a Raphael object r
// Labels is an array of strings. Attrs is a dictionary
// that provides attributes such as fill (text color)
// and font (text font, font-size, font-weight, etc) for the
// label text.
for (var i = 0; i<bc.bars.length; i++) {
var bar = bc.bars[i];
var gutter_y = bar.w * 0.4;
var label_x = bar.x
var label_y = bar.y + bar.h + gutter_y;
var label_text = labels[i];
var label_attr = { fill: "#2f69bf", font: "16px sans-serif" };
r.text(label_x, label_y, label_text).attr(label_attr);
}
}
// what follows is just setting up a bar chart and calling for labels
// to be applied
window.onload = function () {
var r = Raphael("holder"),
data3 = [25, 20, 13, 32, 15, 5, 6, 10],
txtattr = { font: "24px 'Allerta Stencil', sans-serif", fill: "rgb(105, 136, 39)"};
r.text(250, 10, "A Gratuitous Chart").attr(txtattr);
var bc = r.barchart(10, 10, 500, 400, data3, {
stacked: false,
type: "soft"});
bc.attr({fill: "#2f69bf"});
var x = 1;
labelBarChart(r, bc,
['abc','b','card','d','elph','fun','gurr','ha'],
{ fill: "#2f69bf", font: "16px sans-serif" }
);
};
</script>
<div id="holder"></div>
There are a bunch of little cleanups you could do to labelBarChart(), but this basically gets the job done.
Here's a function I wrote for adding the labels. It's not particularly elegant but it will add the labels:
Raphael.fn.labelBarChart = function(x_start, y_start, width, labels, textAttr) {
var paper = this;
// offset width and x_start for bar chart gutters
x_start += 10;
width -= 20;
var labelWidth = width / labels.length;
// offset x_start to center under each column
x_start += labelWidth / 2;
for ( var i = 0, len = labels.length; i < len; i++ ) {
paper.text( x_start + ( i * labelWidth ), y_start, labels[i] ).attr( textAttr );
}
};
Usage is as follows:
var paper = Raphael(0, 0, 600, 400);
var chart = paper.barchart(0, 0, 600, 380, [[63, 86, 26, 15, 36, 62, 18, 78]]);
var labels = ['Col 1', 'Col 2', 'Col 3', 'Col 4', 'Col 5', 'Col 6', 'Col 7', 'Col 8'];
paper.labelBarChart(0, 390, 600, labels, {'font-size': 14});
I would like to propose a solution of an issue of the labelBarChart function proposed by Jonathan Eunice.
considering stacked bar-graphes (or other bar-graphes with more than one array of values), I added a test on bc.bars[0] in case the bc.bars.length means the number of arrays of values stacked.
This lead to the code :
<script>
function labelBarChart(r, bc, labels, attrs) {
// Label a bar chart bc that is part of a Raphael object r
// Labels is an array of strings. Attrs is a dictionary
// that provides attributes such as fill (text color)
// and font (text font, font-size, font-weight, etc) for the
// label text.
//Added test : replace bc.bars by generic variable barsRef
var barsRef = (typeof bc.bars[0].length === 'undefined') ? bc.bars : bc.bars[0];
var bar, gutter_y, label_x, label_y, label_text;
//Added consideration of set attrs (if set)
var label_attr = (typeof attrs === 'undefined') ? {} : attrs;
label_attr['fill'] = (typeof label_attr['fill'] === 'undefined') ? "#2f69bf" : label_attr['fill'];
label_attr['font'] = (typeof label_attr['font'] === 'undefined') ? "16px sans-serif" : label_attr['font'];
for (var i = 0; i<barsRef.length; i++) {
bar = barsRef[i];
gutter_y = bar.w * 0.4;
label_x = bar.x
label_y = bar.y + bar.h + gutter_y;
label_text = labels[i];
r.text(label_x, label_y, label_text).attr(label_attr);
}
}
// what follows is just setting up a bar chart and calling for labels
// to be applied
// I added an array of data to illustrate : data4
window.onload = function () {
var r = Raphael("holder"),
data3 = [25, 20, 13, 32, 15, 5, 6, 10],
data4 = [0, 2, 1, 40, 1, 65, 46, 11],
txtattr = { font: "24px 'Allerta Stencil', sans-serif", fill: "rgb(105, 136, 39)"};
r.text(250, 10, "A Gratuitous Chart").attr(txtattr);
var bc = r.barchart(10, 10, 500, 400, [data3, data4] {
stacked: true,
type: "soft"});
bc.attr({fill: "#2f69bf"});
labelBarChart(r, bc,
['abc','b','card','d','elph','fun','gurr','ha'],
{ fill: "#2f69bf", font: "16px sans-serif" }
);
};
</script>
<div id="holder"></div>
I just tested it with 2 arrays of values stacked.