I'm using chartkick with chart.js in Ruby on Rails. I saw the documentation and some issues, but I can't find anything to solve my problem.
I'm setting my chart in html.erb file, like this:
<%=
line_chart $hash_chart,
options: {
max: $value.max+5,
min: $value.min-5,
allowDecimals: false,
colors: color_line,
xtitle: "Title of x axis",
ytitle: "Title of y axis",
discrete: true,
points: false,
width: "500px",
height: "500px",
scales: {
yAxes: [{
distribution: 'linear'
}],
xAxes: [{
distribution: 'linear',
type: 'category', (part of a configuration attempt)
categories: $time, (part of a configuration attempt)
ticks: {
stepSize: 10
}
}]
}
}
%>
The settings until height param works, but scales settings doesn't. The answer of this issue is exactly what I make (according documentation of Chart.js), but didn't work: Force display of ticks on xAxes using chartkick gem and chart.js. I tried to put this setting inside library brace too.
Basically, I want to set the ticks in x Axis and show just some labels of my array of datas. Is it possible to format this (using this type of file)?
You are using the wrong old v2 syntax of chart.js, the scales in v3 for example have to be configured like this
scales: {
x:{
ticks: {}
},
y: {
// Y config
}
}
EDIT:
Since you are on V2 your syntax of declaring axis is correct, make sure you dont run the latest version of chartKick since it uses v3.
distribution does not do anything unless your scale type is time. The stepSize only works for linear and time scales so you will need to change type: 'category' to type: 'linear' or if you are using time data to type: 'time' if you are using time data the stepsize has to be configured in the time sub part so you will need to change ticks to time
Related
I am struggling to understand why I cannot get the ordinal aspect of my spline type chart to work correctly! I created a series of bar charts a long time ago but having not done anything like this in years I'm a tad clueless and needing some guidance, I've spent hours trying different methods and nothing works wether using Highcharts or highstock.
The code I have in the head of my page is as follows:
$(document).ready(function() {
var options = {
chart: {
renderTo: 'container',
plotBackgroundColor: null,
plotBorderWidth: null,
plotShadow: false,
type: 'spline'
},
title: {
text: theTitle,
x: -20
},
xAxis: {
ordinal: false,
type:'datetime',
labels: {formatter: function() {return Highcharts.dateFormat('%b %e (%y)', this.value);}}
},
series: []
}
$.getJSON("data_weight_loss.php", function(json) {
options.xAxis.categories = json[0]['data'];
options.series[0] = json[1];
chart = new Highcharts.Chart(options);
});
});
The dates are in datestamp format in my MySQL database as "2022-06-28 09:02:45" and despite trying all sorts I'm confused to how I can get the dates in my chart to add the dates in that don't already exist?
This image shows the chart on how it currently looks but has no relevance as the dates that are missing means the chart is not very helpful. It's been a long time since I used Highcharts and even did anything like this but as a personal project I'd love to get my chart working with the ordinal aspect in place. Is there anything glaringly obvious that I have done wrong?
The data for instance is like this if I look directly in the data call from the php page.
[{"name":"Date","data":[1651695362000,1652140800000,1652227200000,1652313600000,1652400000000,1652918400000,1653264000000,1654214400000,1654473600000,1654560000000,1654819200000,1655164800000,1655251200000,1655424000000,1655683200000,1656288000000]},{"name":"Weight","data":[2188,2000,1986,1962,1948,1868,1834,1744,1728,1720,1702,1682,1676,1666,1652,1622]}]
Any help would be appreciated, thank you.
I'm working on a choropleth map that shows the share of the population that has confirmed positive case of Covid-19 in each political jurisdiction. Similar to this example in the per capita Mapbox graphic on this page of the The New York Times.
I figured out just about every detail expect how to customize the legend. Currently, the labels display the shareOfPop as a number. Though, I want to prefix each label with "1 in ${shareOfPop}", and to add a suffix to the final label "1 in ${shareOfPop} or more".
enter image description here.
I've created this map in an Observable Notebook.
Things I've tried so far...
Making us of the custom legend encodings
To specify label text:
vl.color()
.fieldQ('shareOfPop')
.scale(
{
scheme: "yelloworangered",
domain: [250, 10],
clamp: true,
}
)
.legend({
title: "Share of Pop.",
encode: {
labels: {text: "1 in ${datum.value}"}
}
})
Register a custom formatter
Which I doubt I've accomplished correctly.
Here's what my configuration looks like (which is based on the config in the Introduction to Vega-Lite notebook).
vl = {
const [vega, vegalite, api, tooltip] = await Promise.all([
'vega#5.13.0',
'vega-lite#4.14.1',
'vega-lite-api#0.11.0',
'vega-tooltip#0.22.1'
].map(module => require(module)));
const options = {
config: {
// allow custom format types
customFormatTypes: true,
config: {
view: {continuousWidth: 400, continuousHeight: 300},
mark: {tooltip: null}
}
},
init: view => {
// initialize tooltip handler
view.tooltip(new tooltip.Handler().call);
// enable horizontal scrolling for large plots
if (view.container()) view.container().style['overflow-x'] = 'auto';
// register a custom expression function...am I doing this right???
vega.expressionFunction('1inX', function(datum) {
return `1 in ${datum}`
})
},
view: {
// view constructor options
loader: vega.loader({baseURL: 'https://cdn.jsdelivr.net/npm/vega-datasets#1/'}),
renderer: 'canvas'
}
};
return api.register(vega, vegalite, options);
}
Then I specify this custom formatType when defining the mark:
vl.color()
.fieldQ('shareOfPop')
.scale(
{
scheme: "yelloworangered",
domain: [250, 10],
clamp: true,
}
)
.legend({
title: "Share of Pop.",
formatType: "1inX",
})
)
Neither of these approaches produced any noticeable change.
Gonna answer my own question here.
Turns out Legend has a general labelExpr property that allows you to specify a Vega expression for customizing the label.
In my case, I wanted to always prepend the string "1 in ", and also append "+" when over may domain limit. Here's how I did it using the join() and if() functions.
...
vl.color()
.legend(
{
labelExpr: "join(['1 in ', datum.value, if(datum.value >= 250, '+', '')], '')"
}
)
This property isn't documented for Legend, though it is for for Axis).
Since the public 7.0 release of PrimeFaces includes ChartJs, I thought I'd give it a try.
It works fine, however so far I have not been able to properly display data with values changing over time in a line chart.
chart.js has cartesian time axes for this purpose, however in PrimeFaces , only CartesianLinearAxes is available.
Feeding date objects (instead of String labels) to ChartData simply results in no x-axis being drawn.
Am I missing something or did they just skip this functionality when including chart.js in Primefaces?
OK great questions.
First, PF knows they did not implement time yet but there is an open ticket: https://github.com/primefaces/primefaces/issues/4564
Second, have no fear you can use the Extender feature to make it work. Here is an example we used.
In your Java model for your chart set the Extender feature on.
chartModel.setExtender("chartExtender");
In your XHTML add this JavaScript code function to match when you set in #1 Java bean.
function chartExtender() {
//copy the config options into a variable
var options = $.extend(true, {}, this.cfg.config);
options = {
//remove the legend
legend: {
display: false
},
scales: {
xAxes: [{
display: true,
type: "time",
time: {
parser: 'h:mm:ss a',
tooltipFormat: 'h:mm:ss a',
unit: 'hour',
displayFormats: {
'hour': 'h:mm:ss a'
}
}
}],
yAxes: [{
display: true,
scaleLabel: {
display: true,
labelString: 'Your Y Axis',
fontSize: 13,
}
}]
}
};
//merge all options into the main chart options
$.extend(true, this.cfg.config, options);
};
You can see the different time formats available from ChartsJS using MomentJS.
Just a complement to do the extender works, use this.cfg.config.options = {...
for exemple:
function extName() {
this.cfg.config.options = {
legend: {
display: false
}
};
};
I have this issue with my pre tag that I have been trying to resolve for a while now. I have tried almost 20 suggestions that I have found and none of them seem to work.
I have a server running with node.js that has 2 websites on it, technically it's one website with 2 layouts. If I try using pre-tag on my 1st layout, everything seems to be displaying normally, however on my 2nd page I guess extra tabs that I can't seem to locate.
Here is what I have:
<pre><pre><code >
<script>
new Chart(document.getElementById("bar-chart"), {
type: 'bar',
data: {
labels: ["Blue", "Black", "Green", "Silver", "Red"],
datasets: [
{
label: "Votes for this color: ",
backgroundColor: ["#3e95cd", "#000000", "#35d90e", "#c0c0c0", "#c45850"],
data: [120, 384, 81, 223, 192]
}
]
},
options: {
legend: { display: false },
title: {
display: true,
text: 'Best Car Colors according to a 1000 votes survey'
}
}
});
</script>
</code></pre></pre>
and it is displaying like this:
Visuals
anyone have any idea what and why? I have tried unsetting all css and re-setting pre tag, but it does exactly the same thing.
Updated:
For all those who were and are still struggling with same issue, I found the problem! So I am using handlebars, and one the features is called "partials"
and I had a page that called on those partials, in this manner:
{{>crashcorse/intro_lessons}}
however it had some extra spaced before the {{> }} tag, due to auto formatting, removing these extra spaced seem to solved the issue.
We've just updated to the latest Highcharts version and now a few of our chart types have a new line connecting the tooltip to the point.
It's mainly obvious on charts with fixed tooltips.
Does anyone know how to remove this line without removing the border of the tooltip itself?
I have come up with a work around that involves setting the borderwidth of the tooltip to 0 and adding a rounded, bordered, coloured div to the tooltip using useHTML:true and disabling the shadow.
Though I dont want to do this for every chart as it seems a bit nasty.
This also affects bar and tree maps that I can see and I've trawled the documentation to no avail.
http://jsfiddle.net/mattscotty/bqw4bc4x/1/
Highcharts.chart('container', {
title: {
text: 'Fixed tooltip'
},
tooltip: {
positioner: function () {
return { x: 80, y: 50 };
},
backgroundColor: 'rgba(255,255,255,0.8)',
//Uncomment below to remove line, but this also removes tooltip border
//borderWidth:0,
//shadow:false
},
xAxis: {
categories: ['Jan', 'Feb', 'Mar']
},
series: [{
data: [29.9, 71.5, 106.4]
}, {
data: [194.1, 95.6, 54.4]
}]
});
Thanks in advance.
By default tooltip's shape is set to a callout which has a chevron/line pointing to the point. You can change the tooltip's shape to, e.g. rectangle - which does not have any connector.
tooltip: {
positioner: function () {
return { x: 80, y: 50 };
},
backgroundColor: 'rgba(255,255,255,0.8)',
shape: 'rect'
example: http://jsfiddle.net/bqw4bc4x/2/
The accepted answer only partially worked in Highstock. The connectors for the volume and indicator tooltips were suppressed, but I still had a connector from the DateTime box to the crosshair.
As an alternative to the shape: 'rect' hack, you can try:
tooltip: {
positioner: function () {
return { x: 80, y: 50 };
},
split: false,
shared: true,
backgroundColor: 'rgba(255,255,255,0.8)'
These split: and shared: settings consolidate all the tooltip boxes into a single box. Provided that this meets your needs it seems to solve the connector issue.
Very odd design decision by Highcharts. The connectors are highly intrusive visually and I can't imagine that many designers will want to use them, but you can only disable them with a hack. What were they thinking?