Unable to set SeriesIdentifier of Birt chart using javascript - birt

I am trying to create a birt chart report with a dynamic series label.
I have created the aggregate data binding as the first(row["year"]), which will give results like '2020', but I don't know how to get this binding value in JavaScript. Please any ideas?
function afterDataSetFilled( series, dataSet, icsc )
{
var chart = icsc.getChartInstance();
importPackage(Packages.java.util);
importPackage(Packages.org.eclipse.birt.chart.model.data.impl);
importPackage(Packages.org.eclipse.birt.chart.model.component.impl);
importPackage(Packages.org.eclipse.birt.chart.model.type.impl);
importPackage(Packages.org.eclipse.birt.chart.model.attribute);
var xAxis = chart.getAxes().get(0);
var yAxis = xAxis.getAssociatedAxes().get(0);
var xSerieDef = xAxis.getSeriesDefinitions().get(0);
var ySerieDef1 = yAxis.getSeriesDefinitions().get(0);
var dt = dataSet[row.year];
ySerieDef1.getSeries().get(0).setSeriesIdentifier(dt);
}

Related

google form script exclude sundays on dates choices

im making a script for making an apointment. I get the choices of appointmentt date from my spreadsheet using script. How to exclude sunday when i get the choices from my spreadsheet ? i cant find a way to remove the sunday.
here is the code
var ssID = "1hil07Z2wvTXH1szX9bNfPKVLDQVO36ACQFGOU6_VUI0";
var formID="1SD5BenAnNxNz-wtw0YPut6YdTf7a62zHn_z3VrTdTUU";
var wsData = SpreadsheetApp.openById(ssID).getSheetByName("DATA");
var form = FormApp.openById(formID);
function main(){
var labels = wsData.getRange(1,1,1,wsData.getLastColumn()).getValues()[0];
labels.forEach(function(label,i){
var options = wsData
.getRange(2, i+1,wsData.getLastRow()-1,1)
.getDisplayValues()
.map(function(o){return o[0]})
.filter(function(o){return o !== ""})
//Logger.log(options);
updateDropDownUsingTitle(label,options);
});
}
function updateDropDownUsingTitle(title,values) {
var title = "Tanggal Penjemputan";
var items = form.getItems();
var titles = items.map(function(item){
return item.getTitle();
});
var pos = titles.indexOf(title);
var item = items[pos];
var itemID = item.getId();
updateDropdown(itemID,values);
}
function updateDropdown(id,values) {
var item = form.getItemById(id);
item.asListItem().setChoiceValues(values);
}
this is the form
THis is my spreadsheet
There are 3 ways to achieve your goal:
Use a non-Sunday formula in sheet
Add a weekday column to sheet and filter in script
getValues and new Date instead of getDisplayValues, filter Sunday and then Utilities.formatDate
You can use the following formula:
=ArrayFormula(TODAY()+FILTER({1;2;3;4;5;6;7}, WEEKDAY(TODAY()+{1;2;3;4;5;6;7})<>1))
See on Google Sheets
This will give you the next 7 days excluding Sunday.

Trying to set custom colours for a chart

I'm trying to add custom colours to a column chart, so each column has a different colour. I have the following code:
__this._chartColours = ['#2776BD', '#00A1D0','#00C195','#7ED321','#A8C600','#C9B600','#E3A600', '#F7941E', '#FC7149'];
__this._chart = am4core.create(__this._tileChartDiv[0], am4charts.XYChart);
if(result.chartDataMap != null)
{
var colorSet = new am4core.ColorSet();
var counter = 0;
$.each(result.chartDataMap, function(xAxis, yAxis)
{
__this._dataProvider.push({"category": xAxis, "column-1": yAxis});
__this._chart.colors.list.push(am4core.color(__this._chartColours[counter]));
});
__this._chart.data = __this._dataProvider;
__this._chart.padding(40, 40, 40, 40);
var categoryAxis = __this._chart.xAxes.push(new am4charts.CategoryAxis());
categoryAxis.renderer.grid.template.location = 0;
categoryAxis.dataFields.category = "category";
categoryAxis.renderer.minGridDistance = 60;
categoryAxis.title.text = result.xAxisTitle;
var label = categoryAxis.renderer.labels.template;
label.wrap = true;
label.maxWidth = 120;
var valueAxis = __this._chart.yAxes.push(new am4charts.ValueAxis());
valueAxis.title.text = result.yAxisTitle;
var series = __this._chart.series.push(new am4charts.ColumnSeries());
series.dataFields.categoryX = "category";
series.dataFields.valueY = "column-1";
series.tooltipText = "{valueY.value}"
series.columns.template.strokeOpacity = 0;
__this._chart.cursor = new am4charts.XYCursor();
}
It renders the chart fine based on the dataprovider I create but it is not setting the colors. I got the colours code from here: https://www.amcharts.com/docs/v4/concepts/colors/. The XY Chart and derivative charts section
I tried to use a theme, but that didn't work either:
function am4themes_myTheme(target)
{
if (target instanceof am4core.ColorSet)
{
$.each(__this._chartColours, function(index, item)
{
target.list.push(am4core.color(item));
});
}
}
am4core.useTheme(am4themes_myTheme);
It sets all the columns to the first colour. Then I tried adding a color property to the dataProvider for each column but again it sets them all to have the first colour.
I'm pretty much out of ideas.
There are a few issues here.
First, if you want the chart to use only your colors, instead of appending to the default chart's ColorSet, you have to manually override it by assigning an array of Colors to chart.colors.list (instead of pushing values to it).
Next, the column's color (fill) by default is based on its series. So even if you populate the chart's ColorSet, it's only each new series that will get a different color, not each column.
To set an individual column's color it would be something like:
column.fill = am4core.color("#2776BD");
To get each column to have its own color, we can set that upon the column's first instantiation, i.e. on its template's inited event. Further, a column's dataItem will have a property/reference to its index, so we can use that with ColorSet's getIndex method to assign colors in sequence.
So your final code might look something like this:
__this._chart.colors.list = [
am4core.color("#2776BD"),
am4core.color("#00A1D0"),
am4core.color("#00C195"),
am4core.color("#7ED321"),
am4core.color("#A8C600"),
am4core.color("#C9B600"),
am4core.color("#E3A600"),
am4core.color("#F7941E"),
am4core.color("#FC7149")
];
series.columns.template.events.once("inited", function(event){
event.target.fill = chart.colors.getIndex(event.target.dataItem.index);
});
Here's a fork of our Simple Column Chart demo with the above code and your custom colors:
https://codepen.io/team/amcharts/pen/2ef06f392b347412c61bcdcd3439a5c6

Dc.js charts interactivity fails when charts are dynamically added by users.Pls see description for more details

I am looking for a way to get Dc.js charts to be added to a dashboard by user choice of chart in a palette.
End of the day I want the user to be able to do 2 things.
Part 1: User should be able to select and add various charts from charts palette into a dashboard by selecting respective target variable(x,y fields) which are nothing but fields in csv, one by one for each chart.
Part 2 : These charts which form a kind of dashboard should be reactive or interactive(change in one chart reflects change in all other charts) which is not the case now.
I have already achieved the 1st part by below code , but the main challenge is 2nd part. Charts are no more coordinated visualizations(by change of a pie in one chart , other charts do not reflect the change)
I have added all charts in 1 function with a switch case statement. Everything works fine up to adding the charts to the dashboard or respective div but this does not make the charts reactive(click on one chart does not affect other charts).
Little note about the below code and its intentions.
-I am dynamically creating div’s and assigning ids.
-here num in my function is a random number assigned in calling function to make sure there are no duplicate divs with same id.
-Targetvar is a field chosen by the user.
-arrayofobject is the actual data.
-ctype is the charttype chosen by user.I have declared 2 charts(pie and row) for example sake.Their are more charts in the palette for user to choose.
Please let me know what change I need to make to get charts be reactive.
function charts_all(targetvar1,arrayOfObject,num,ctype){
var selname="#divid"+num;
switch(ctype){
case "pie":
var SevPieChart=dc.pieChart(selname);
data=arrayOfObject;
var ndx = crossfilter(data);
var all = ndx.groupAll();
var targetvariable1=targetvar1;
var SevDim = ndx.dimension(function(d){ return d[targetvariable1]; })
;
var Sevgroup=SevDim.group();
SevPieChart
.height(400)
.width(1200)//1200
.radius(150)
.innerRadius(20)
.dimension(SevDim)
.group(Sevgroup)
.transitionDuration(1000)
.legend(dc.legend().x(950).y(40)) //LEGEND CODE x=950
.externalLabels(0)
.renderLabel(true)
.label(function(d) { return d.key +" (" + Math.floor(d.value / all.value() * 100) + "%)"; })
.title(function(d){return d.Sevgroup;});
//dc.renderAll();
alldefault();
break;
case "row":
var Rowchart = dc.rowChart(selname);
data=arrayOfObject;
var ndx = crossfilter(data);
var all = ndx.groupAll();
var targetvariable1=targetvar1;
var SaDim = ndx.dimension(function(d){ return d[targetvariable1]; })
;
var SAgroup=SaDim.group();
Rowchart
.width(1000)
.height(1000)
.dimension(SaDim)
.group(SAgroup)
.renderLabel(true)
.label(function(d) { return d.key+" (" + Math.floor(d.value / all.value() * 100) + "%)"; })
.data(function(group){ return group.top(40);}) ;
//Rowchart.filter = function() {};
//dc.renderAll();
alldefault();
break;
default:
}
dc.renderAll();
}

D3 stack() vs nested objects

I'm running into an issue when trying to implement a normalized stacked bar chart using D3v4.
The problem occurs due to my data format which contains nested object arrays populated dynamically on the server side.
var data = [{x:"data1", y:[{name:"red", value:10}, {name:"green", value:20}]},
{x:"data2", y:[{name:"red", value:30}, {name:"green", value:5}]}];
Calling d3.stack() on this will not work since d3 doesn't know how to traverse into the object array y. (https://jsfiddle.net/xv1qgqjg/)
Is there any way to tell d3.stack() where to find the relevant data similar to the .data(function(d){ return d.y; }) used elsewhere?
It doesn't seem to be possible. According to the documentation regarding stack(data[, arguments…]),
Any additional arguments are arbitrary; they are simply propagated to accessors along with the this object.
Thus, you'll have to change your data, creating an array which you can pass to d3.stack(), such as this:
[{red:10,green:20},
{red:30,green:5}]
Given the data array in your question, there are several ways for creating the above-mentioned array. Here is my solution (the new array is called newData):
newData = [];
data.forEach(d => {
var tempObj = {}
d.y.forEach(e => {
tempObj[e.name] = e.value;
})
newData.push(tempObj);
});
Here is a demo:
var data = [{x:"data1", y:[{name:"red", value:10}, {name:"green", value:20}]},
{x:"data2", y:[{name:"red", value:30}, {name:"green", value:5}]}];
newData = [];
data.forEach(d => {
var tempObj = {}
d.y.forEach(e => {
tempObj[e.name] = e.value;
})
newData.push(tempObj);
});
var stack = d3.stack()
.keys(["red", "green"])
.order(d3.stackOrderNone)
.offset(d3.stackOffsetExpand);
var series = stack(newData);
console.dir(series);
<script src="https://d3js.org/d3.v4.min.js"></script>

nvd3 add nvd3 chart dom element from code

I'm using the following code:
http://plnkr.co/edit/CIGW0o?p=preview
in this code the html contains
<nvd3 options="options" data="data"></nvd3>
Im trying to add it from the code:
$scope.buildNewChart = function(){
var xmlString = "<nvd3 options='options' data='data' class='ng-isolate-scope'></nvd3>";
var wrapper= document.createElement('div');
wrapper.innerHTML= xmlString;
var div= wrapper.firstChild;
var elem = document.getElementById("charts");
elem.appendChild(div);
}
but it not works as I can see the element (<nvd3 options="options" data="data"></nvd3>) but its empty
To add some element with Angular, you should use $compile
$scope.buildNewChart = function(){
var chart = angular.element("<nvd3 options='options' data='data' class=''></nvd3>");
var elem = angular.element(document.getElementById("charts"));
elem.append(chart);
$compile(chart)($scope)
}
P.S. Also it goes against Angular practices. Consider to add it into initial HTML, but hide it with ng-if or something

Resources