How to render multiple AmCharts (version 3) Serial chart on same page? - amcharts

I need a page with several charts (render multiple aspects of same dataset).
I use the same dataset
with the same chartConfig (cloned by $.extend
2 charts
all are serial type
Here is the problem code http://jsfiddle.net/mZ2Gq/227/
var chart1 = AmCharts.makeChart("chart1div", $.extend(true, AMCHART_SERIAL_CONFIG, { "theme": "dark" }) );
var chart2 = AmCharts.makeChart("chart2div", $.extend(true, AMCHART_SERIAL_CONFIG, { "theme": "light" }) );
It only can render the last chart propertly. How can I work-around this issue?

The problem is that you're using the same configuration object for both charts. This does not work.
You can solve this by using an empty object {} as target in the $.extend method.
Just like this:
AmCharts.makeChart("chart", $.extend(true, {}, AMCHART_SERIAL_CONFIG, {theme: "dark"}));
Here's your updated fiddle.
Note: You should avoid using deep merge if not necessary. It slows your code.

Related

dc.js Line Chart doesn't show Data

Data doesn't show in my line chart. It just shows the y-axis and x-axis.
My data arrays are like this:
time_list = ['00:00:00', '01:00:00', '02:00:00']
val_list = [0.7274859768018719, 0.6894762867153069, 0.6994151884676558]
I set up the chart like this:
<div id="#chart-cpu-performance"></div>
<script type="text/javascript">
var cpuperformance = dc.lineChart("#chart-cpu-performance");
var connection = new WebSocket(`ws://localhost:8001/websocket`);
function render_plots(dim, val) {
cpuperformance
.width(990)
.height(540)
.dimension(dim)
.group(val)
.x(d3.scaleBand().domain(['00:00:00', '04:00:00', '08:00:00','12:00:00',
'16:00:00', '20:00:00','23:00:00']).rangeRound([0,100]))
.y(d3.scaleLinear().domain([0,1]))
.curve(d3.curveLinear)
.renderArea(false)
.renderDataPoints(true);
cpuperformance.render();
}
connection.onmessage = function(event){
//get data and parse
var newData = JSON.parse(event.data);
var updateObject = []
newData.time_list.forEach(function additem(item, index) {
updateObject.push({time: item, avg_value: newData.val_list[index]})
});
var xfilter = crossfilter(updateObject)
var timeDim = xfilter.dimension(function(d) {return d.time;});
var avg_vPertime = timeDim.group().reduceSum(function(d) {return +d.avg_value;});
render_plots(timeDim, avg_vPertime)
}
</script>
Did I miss some parameters for cpuperformance in the render_plots function?
Yes, you missed xUnits. Also I suggest using .elasticX(true) rather than specifying the domain yourself.
Unfortunately most coordinate grid charts are not able to determine automatically what kind of data keys they are dealing with, the primary kinds being numeric, ordinal, and time.
So if your data is ordinal, you need to have
.xUnits(dc.units.ordinal)
A lot of the logic is different for charts with an ordinal X scale, and this parameter directs dc.js to use the ordinal logic. Other values tell bar charts how wide to make the bars for the numeric (dc.units.integers, dc.units.fp.precision) and time scales (d3.timeHours etc).
Also in this example, only one of the data points matches the domain you passed to scaleBand. So you'll only see one point.
It's easier to use
.elasticX(true)
.x(d3.scaleBand().rangeRound([0,100]))
and let the chart figure out what to put in the domain.
Fiddle with a working version of your code.

Aurelia + Kendo - How can I reload a Kendo pie chart after changing data?

I'm attempting to use Aurelia and the Kendo UI Bridge to display data in a pie chart. Due to project requirements, I've got the pie chart widget loading in a custom element. If my data is available before the page loads, everything works fine.
View Model
export class PieChartCustomElement {
chartData = [];
chartSeries = [{
type: 'pie',
startAngle: 150,
field: 'percent',
categoryField: 'languageName'
}];
// other variables
constructor() {
//if I hard-code the data here, all works fine
this.chartData = [
{ languageName: 'English', percent: 62.5 },
{ languageName: 'Spanish', percent: 35 },
{ languageName: 'Esperanto', percent: 2.5 }
];
}
}
View
<template>
<require from="aurelia-kendoui-bridge/chart/chart"></require>
<h4>pie chart custom element</h4>
<ak-chart k-title.bind="title"
k-legend.bind="legend"
k-series-defaults.bind="chartDefaults"
k-series.bind="chartSeries"
k-data-source.bind="chartData"
k-tooltip.bind="tooltip"
k-widget.bind="pieChart"></ak-chart>
</template>
In reality, my data is fetched from a REST API using a promise, so I don't have the data when the page initially loads. Further, I need to pass a parameter to the REST API that comes in via a #bindable attribute on the element, so I cannot populate my data source in the constructor. Hence, something like this:
#bindable({ defaultBindingMode: bindingMode.oneWay }) someArg;
attached() {
// 'api' is injected and is a simple JS class that calls the REST API
this.api.getChartData(this.someArg).then((results) => {
this.chartData = results;
});
}
I'm pretty sure that this is due to the fact that the pie chart widget has already loaded and does not automatically reload when its backing data is changed. If this is actually the case, how do I get the pie chart to reload when I change its data set? If its not, what am I doing wrong?
Working Gist - Comment/uncomment code in the constructor/activate events as indicated to see the behavior.
I believe the method you are looking for is the setDataSource()
In pie-chart.js in the attached() method in your Gist try changing
this.chartData = languageData;
to
this.pieChart.setDataSource(this.chartData);

How do I draw donut with absolute values intead of percents with Keen.io & c3?

I'm using Keen.io ("version": "3.4.1") JavaScript SDK, along with their integration with C3.js, to produce a donut graph by using the code below. However, I don't want percentages, but rather absolute numbers. i.e. Not 25%, but 7.
From reading the docs and looking at examples (see "var c3gauge") and example, I thought you could modify the output by applying the chartOptions. That doesn't seem to be working. At this point, I feel like I'm doing something stupid I'm just not catching.
How do I display absolute values in my donut, not percentages?
var c3donut = new Keen.Dataviz()
.library('c3')
.chartType('donut')
.el(document.getElementById(elem))
.title("Awesome Sauce")
.parseRawData(data)
.chartOptions({
donut: {
label: {
format: function (value) {
console.log("I never fire, why?");
return value;
}
}
}
})
.render();
This is possible with keen-dataviz.js library. I've created a working example here: https://jsfiddle.net/bx9efr4h/1/
Here's part of the code that made it work:
var chart = new Keen.Dataviz()
.el('#chart')
.type("donut")
.chartOptions({
donut: {
label: {
format: function(value) {
return value;
}
}
}
})
.prepare();
keen-js works a little differently because c3.js is not the default dataviz library for it. This is likely why it isn't working like expected for you.

How to remove NVD3 chart resize/update delay

I've created an NVD3 multiBarChart and placed it in a jQuery resizable container. When resizing the chart, each render incurs the same delay as when the chart is first drawn: staggered left-to-right delayed drawing of the bars. This looks cool when the chart is first drawn, but it's a nuisance when resizing the chart. I've experimented with nv.d3.css, reducing every delay to 0ms to no avail. Haven't yet inspected the NVD3 JS and am hoping not to need to.
Fiddle:
http://jsfiddle.net/a5Fnj/10/
var container = $("#mycontainer");
$(container[0]).resizable();
var svg = d3.select(container[0]).append("svg");
nv.addGraph(function () {
var chart = nv.models.multiBarChart();
chart.xAxis.tickFormat(d3.format(',f'));
chart.yAxis.tickFormat(d3.format(',.1f'));
d3.select(container[0]).select("svg")
.datum(exampleData())
.transition().duration(0).call(chart);
nv.utils.windowResize(chart.update);
this.stackedbar = chart;
});
function exampleData() {
return stream_layers(3, 10 + Math.random() * 100, .1).map(function (data, i) {
return {
key: 'Stream' + i,
values: data
};
});
}
As of NVD3 1.7.1 you can use the duration option:
chart.duration(0);
I used transitionDuration: -1 that worked for a stackedAreaChart.
Edit
This helped remove the transition when appending chart data, not the re-size issue, please check the comments below.
In the latest version (from github), you can set .transitionDuration():
chart.transitionDuration(0);
Edit: Even with this, some of the transitions/durations are hardcoded in the NVD3 source. The only way to get rid of those is to modify the source.

g.raphael bar chart and updating/animating the values

I'm working on some bar charts and need to update the chart values. The only way I've found to do this is to redraw the whole thing. Isn't there a way to simple update the bars? And if so what I'm really hoping to do is animate that change. Any suggestions?
http://jsfiddle.net/circlecube/MVwwq/
Here's what you want (updated Fiddle).
You were on the right track for creating a new bar chart. The only issue is, you don't want to "display" that bar chart, but you want to use its bars for animation. While this does generate a new graph which we later throw away (using remove()), it seems to be Raphael best practice.
function b_animate(){
//First, create a new bar chart
var c2 = bars.g.barchart(200, 0, 300, 400, [bdata], {stacked: false, colors:["#999","#333","#666"]});
//Then for each bar in our chart (c), animate to our new chart's path (c2)
$.each(c.bars[0], function(k, v) {
v.animate({ path: c2.bars[0][k].attr("path") }, 200);
v.value[0] = bdata[k][0];
});
//Now remove the new chart
c2.remove();
}
This is not complete, as we haven't animated the legends to match the new chart, but this technique applied to the labels should get you there. Basically, we need to re-map the hovers to show new labels (and remove the old labels).
Hopefully, this should work exactly like you hoped. Let me know if you have any issues. Enjoy!
I had to adapt the above code to get this to work with Raphaƫl 2.1.0 and g.Raphael 0.51 and JQuery 1.9.1:
function b_animate(){
var c2 = bars.barchart(10, 10, 500, 450, bdata, { colors:custom_colors});
$.each(c.bars, function(k, v) {
v.animate({ path: c2.bars[k][0].attr("path") }, 500);
v[0].value = bdata[k][0];
});
c2.remove();}
Hope this helps!

Resources