Is there a way to use fusion algorithms like STARFM in Google Earth Engine? - algorithm

Landsat and MODIS products both have their advantages. Landsat with its high spatial resolution and MODIS with its high temporal resolution. I've read a lot about downloading the files and fuse them locally with algorithms like STARFM in Python for example. Is there a way to fuse both collections directly in Google Earth Engine to save computational time?

There is Google earth engine code in GitHub. The link is below:
https://github.com/MacGallagher/GEE_STARFM_FUSION
The code I copied is below:
/**** Start of imports. If edited, may not auto-convert in the playground. ****/
var l8 = ee.ImageCollection("LANDSAT/LC08/C01/T1_SR"),
modis = ee.ImageCollection("MODIS/006/MOD09GQ"),
geometry4 = /* color: #d63000 */ee.Geometry.Polygon(
[[[-116.004638671875, 42.809506838324204],
[-115.59539794921875, 42.78129125156276],
[-115.499267578125, 43.004647127794435],
[-115.499267578125, 43.28920196020127],
[-116.00189208984375, 43.35114690203121],
[-116.19415283203125, 43.07691312608711]]]),
geometry = /* color: #98ff00 */ee.Geometry.Polygon(
[[[-115.93391418457031, 43.09346209534859],
[-115.80276489257812, 43.095718426590174],
[-115.80276489257812, 43.161366298103566],
[-115.9332275390625, 43.16086543618915]]]);
/***** End of imports. If edited, may not auto-convert in the playground. *****/
// based on script by Faye Peters, University of Louisville
// modified by Megan Gallagher, Boise State University
// for code inquiries, or adjustments please email megangallagher#u.boisestate.edu
// code exists for:
// landsat 5,7, and 8 NDVI merging with MODIS Terra daily
// MODIS Terra and Sentinel-2
// Landsat pre tier and modis daily terra - works with base R code
// Landsat 8 and Sentinel-2
////////////////////////////////////////Variables//////////////////////////////////////////////
// import Landsat 8 and MODIS daily terra surface reflectance 250m
var region = geometry; //region you want to export
var bounds = geometry4 //outer bounds of image to catch boundary effect, make larger than region
var date_begin = '2016-03-02' //start date of data collection, must be a landsat image date
var date_end ='2016-10-13' // end date of data collection, must be the day AFTER last landsat image
var csv_title = '2016_Dates_BOP' //title of csv output
var ls_title = '2016_landsat' // title of landsat tif file
var mod_title = '2016_mod' // title of modis tif file
/////////////////////////////////////////Code////////////////////////////////////////////////////////////////////////
var starfm = function(modis, l8){
//Preliminary filtering of MODIS and Landsat
var filt_mod = modis.filterDate(date_begin, date_end);
var filt_l8 = l8.filterDate(date_begin, date_end)
.filterBounds(bounds);
//add bounds to subset area
var subset_bounds = bounds.transform('EPSG:4326', 30).bounds().getInfo();
// get rid of bad pixels but keep metadata date information
var removeBadObservations = function(image){
var valid_data_mask = ee.Image(image).select('pixel_qa').bitwiseAnd(2).neq(0);
var numberBandsHaveData =
image.mask().reduce(ee.Reducer.sum());
var allOrNoBandsHaveData =
numberBandsHaveData.eq(0).or(numberBandsHaveData.gte(9));
var allBandsHaveData = allOrNoBandsHaveData;
//Make sure no band is just under zero
var allBandsGT = image.reduce(ee.Reducer.min()).gt(-0.001);
var result = ee.Image(image).mask(image.mask().and(valid_data_mask).and(allBandsHaveData).and(allBandsGT));
return result.copyProperties(ee.Image(image),['system:time_start']);
};
//NDVI functions for Landsat and MODIS
var getNDVI_mod = function(image){
return image
.addBands(image.normalizedDifference(['sur_refl_b02','sur_refl_b01']).multiply(10000).rename('NDVI'));};
var getNDVI_l8= function(image){
var ndvi = ee.Image(image).normalizedDifference(['B5','B4']);
return ndvi.copyProperties(ee.Image(image),['system:time_start']);
};
var filt2_l8= filt_l8.filterBounds(subset_bounds).aside(print).map(removeBadObservations).map(getNDVI_l8);
// update mask for different areas
var subset_mask = ee.Image().byte().paint(geometry4, "id").add(1);
var filtered_modis = filt_mod.filterBounds(subset_bounds).aside(print).map(getNDVI_mod);
// Pull out the date:
var extract_modis_date = function(row) {
var d = ee.Date(row.get('system:time_start'));
var d2 = ee.Date.fromYMD(d.get('year'), d.get('month'), d.get('day'));
var result = ee.Feature(null, {'date': d2});
result = result.set({'date': d2});
return result;
};
var getQABits = function(image, start, end, newName) {
//// Compute the bits we need to extract.
var pattern = 0;
for (var i = start; i <= end; i++) {
pattern += Math.pow(2, i);
}
//// Return a single band image of the extracted QA bits, giving the band a new name.
return image.select([0], [newName])
.bitwiseAnd(pattern)
.rightShift(start); };
print(filtered_modis);
filtered_modis = filtered_modis.map(function(image){
var quality = getQABits(image.select(2), 4, 5, 'QAMask');
quality = quality.eq(3).not();
return image.clip(subset_bounds).mask(image.mask().multiply(subset_mask).multiply(quality));
});
filtered_modis = filtered_modis.select('NDVI'); //Take only NDVI band
var modis_multiband = ee.Image(filtered_modis.filterDate(date_begin, date_end).iterate( function(x, modis_multiband) {
return ee.Image(modis_multiband).addBands(ee.Image(x));
}, filtered_modis.first()));
var dates_modis = filtered_modis.map(extract_modis_date);
print(dates_modis.getInfo());
var filt2_l8_ndvi = filt2_l8.map(function(image) {
return ee.Image(image)
.clip(subset_bounds)
.mask(ee.Image(image).mask().multiply(subset_mask));
});
//use this to choose the range of days, and check for overlap
var day_expand = 1;
var reduceLandsatNDVI = function(MODISdate) {
MODISdate = ee.Date(MODISdate.get('date'));
var ndvi_subset = ee.ImageCollection(filt2_l8_ndvi).filterDate( MODISdate,
MODISdate.advance(day_expand, 'day') );
ndvi_subset = ndvi_subset.map(function (image) {
var diff = MODISdate.difference(ee.Date(ee.Image(image).get('system:time_start')), 'day').abs();
return ee.Image(image).set('diff', diff);
});
ndvi_subset = ndvi_subset.sort('diff');
var ndvi_first = ndvi_subset.reduce('first');
var ndvi_mean = ndvi_subset.reduce('mean');
return ee.Algorithms.If(
ndvi_first.bandNames(),
ndvi_first.eq(0).multiply(ndvi_mean).add(ndvi_first),
ee.Image(0)
);
};
var extract_landsat_date = function(MODISdate) {
MODISdate = ee.Date(MODISdate.get('date'));
var ndvi_subset =
ee.ImageCollection(filt2_l8_ndvi).filterDate( MODISdate,
MODISdate.advance(day_expand, 'day') );
ndvi_subset = ndvi_subset.map(function (image) {
var diff = MODISdate.difference(ee.Date(ee.Image(image).get('system:time_start')), 'day').abs();
return ee.Image(image).set('diff', diff);
});
ndvi_subset = ndvi_subset.sort('diff');
var d = ndvi_subset.aggregate_first('system:time_start');
var count = ndvi_subset.aggregate_count('system:time_start');
d = ee.Algorithms.If(
ee.Number(count).gt(0),
ee.Date(d),
ee.Date('1971-01-01')
);
d = ee.Date(d);
var d2 = ee.Date.fromYMD(d.get('year'), d.get('month'),
d.get('day'));
var result = ee.Feature(null, {'LSdate': d2, 'MODISdate':
MODISdate, 'CountLSScenes': count});
result = result.set({'LSdate': d2, 'MODISdate': MODISdate,
'CountLSScenes': count});
return result;
};
var ls_collection = dates_modis.map(reduceLandsatNDVI);
print(ls_collection,'ls collection');
var dates_landsat = dates_modis.map(extract_landsat_date);
Export.table(dates_landsat, csv_title);
var ls_multiband = ls_collection.iterate( function(x,
ls_multiband)
{ return ee.Image(ls_multiband).addBands(ee.Image(x));
}, ls_collection.first());
ls_multiband = ee.Image(ls_multiband).multiply(10000).int16();
ls_multiband = ls_multiband.mask(ls_multiband.mask().multiply(ls_multiband.neq(0)));
//remove repeated first layer
var ls_multiband2=ee.Image(ls_multiband.slice(1))
var modis_multiband2=ee.Image(modis_multiband.slice(1))
Export.image.toDrive({
image: modis_multiband2,
description: mod_title,
crs:'EPSG:4326 ',
region:region,
scale:30
});
Export.image.toDrive({
image: ls_multiband2,
description: ls_title,
crs:'EPSG:4326',
region:region,
scale:30
});
return 'Done!'
}
var running = starfm(modis,l8)
print(running)
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////

Related

Dynamic report columns in BIRT

I have a BIRT report, which simply selects all the columns of a table. Every time a new column is added to the table I have to modify the report to visualize the new column. Is it possible somehow to show the result of a "select * from table" query in the report, so I shouldn't modify the report template anymore? The order of columns is not important.
Thank You.
This is not directly possible.
However, using the DE API, you can create and save a new rptdesign file based on the query, then in a second step execute that report.
The example at https://www.eclipse.org/birt/documentation/integrating/deapi.php only shows how to create layout items, but you can as well create Data Sources and Data Sets.
This is a bit tricky however, so unless you need this quite often, it is not worth the effort.
Here is an excerpt from a script I am using in a file sql2rptdesign.rptdesign to create a new report design. This should give you an idea:
importPackage(Packages.org.eclipse.birt.data.engine.api);
importPackage(Packages.org.eclipse.birt.data.engine.core);
importPackage(Packages.org.eclipse.birt.report.model.api);
importPackage(Packages.org.eclipse.birt.report.model.api.elements.structures);
importPackage(Packages.org.eclipse.birt.report.model.api.util);
importPackage(Packages.org.eclipse.birt.data.engine.api.querydefn);
var engine = reportContext.getReportRunnable().getReportEngine();
var myconfig = reportContext.getReportRunnable().getReportEngine().getConfig();
var designFactory = designHandle.getElementFactory();
// Ein neues DataSet anlegen
var de = DataEngine.newDataEngine( myconfig, null );
var dsrc = reportContext.getDesignHandle().findDataSource("lisa");
var dsHandle = designFactory.newOdaDataSet("Main", "org.eclipse.birt.report.data.oda.jdbc.JdbcSelectDataSet" );
dsHandle.setDataSource(dsrc.getName());
dsHandle.setQueryText(sql);
designHandle.getDataSets( ).add( dsHandle );
Then I add the output columns (I parsed the SQL statement beforehand to get the necessary information). I don't know if this is strictly needed.
var numColumns = 0;
for (var position=0; position<rows.length; position++) {
var row = rows[position];
var colName = row[0];
if (colName == "__Template") {
continue;
}
var colTyp = row[1];
var colWidth = row[2];
var resultCol = new OdaResultSetColumn();
resultCol.setColumnName(colName);
resultCol.setNativeName(colName);
resultCol.setDataType(colTyp);
resultCol.setPosition(position+1);
numColumns = position + 1;
dsHandle.getPropertyHandle(DataSetHandle.RESULT_SET_PROP).addItem(resultCol);
var resultHint = new ColumnHint();
resultHint.setProperty(ColumnHint.COLUMN_NAME_MEMBER, colName);
dsHandle.getPropertyHandle(DataSetHandle.COLUMN_HINTS_PROP).addItem(resultHint);
}
And then add a table, its column bindings, columns, detail rows and cell contents to the layout. This is a bit lenghty.
// Tabellarisches Layout
var elementFactory = designHandle.getElementFactory();
var body = designHandle.getBody();
var tab = elementFactory.newTableItem("Main", numColumns);
tab.setDataSet(dsHandle);
tab.pageBreakInterval = 9999;
for (var colNum=0; colNum<numColumns; colNum++) {
var r = rows[colNum];
var colName = r[0];
var colNameSlashes = addSlashes(colName);
var colType = r[1];
var width = r[2];
var pattern = r[3];
var align = r[4];
// Binding
var colBinding = StructureFactory.createComputedColumn( );
colBinding.setName(colName);
colBinding.setExpression( 'dataSetRow[' + colNameSlashes + ']');
colBinding.setDataType(colType);
tab.addColumnBinding(colBinding, true);
// Überschrift
var textdata = elementFactory.newTextData(null);
textdata.setContentType("plain");
textdata.setValueExpr(colNameSlashes);
textdata.setStringProperty("whiteSpace", "normal");
tab.getLayoutModel().getCell(1,colNum+1).getContent().add(textdata);
// Wert
var textdata = elementFactory.newTextData(null);
textdata.setContentType("plain");
textdata.setHasExpression(true);
textdata.setStringProperty("whiteSpace", "normal");
var expr = 'row[' + colNameSlashes + ']';
textdata.setValueExpr(expr);
tab.getLayoutModel().getCell(2,colNum+1).getContent().add(textdata);
// Spaltenbreite und Ausrichtung
var columnHandle = tab.getColumns().get(colNum); // 0-basiert?
if (width) {
columnHandle.setProperty("width", StringUtil.parse(width));
}
}
body.add(tab, 0);
And finally save the new file:
designHandle.saveAs(designFilename);
However, this doesn't use a template as you would like to do.

Amcharts V4 mark values on series with known value

I have a amChart4 XYChart loaded from a CSV external file.
How to mark the max values on a serie, max values are known when writing the file. So just need to mark the data points with a bullet.
var maxNm = 404.24;
var maxHP = 327.7;
Se code with working chart loaded from CSV.
https://codepen.io/lasse-kofoed/pen/WNbNXxe
// Themes begin
am4core.useTheme(am4themes_material);
am4core.useTheme(am4themes_animated);
// Themes end
// Create chart instance
var chart = am4core.create("chartdiv", am4charts.XYChart);
chart.responsive.enabled = true;
// Set up data source
chart.dataSource.url = "https://master.tus.io/files/a6bfda6a8051313c0c0b1d7129a75786+DB7aQwWVBca.GAK4H6FLamUT58549Asv6vLoR9kEJySMEVOsFlCSi9eqzgMYLhqXdMJDZoTE0C90HuVUUKD7KoKdFjlM0f1IRkkQ0L5X6iykr8kSsyNWTtPkcmzIFwDp";
chart.dataSource.parser = new am4core.CSVParser();
chart.dataSource.parser.options.useColumnNames = true;
// Increase contrast by taking evey second color
chart.colors.step = 2;
chart.dataSource.events.on("error", function (ev) {
console.log("Oopsy! Something went wrong");
});
// Create value axis
var valueAxis = chart.yAxes.push(new am4charts.ValueAxis());
valueAxis.tooltip.disabled = true;
valueAxis.title.text = "Power & Torque";
var categoryAxis = chart.xAxes.push(new am4charts.CategoryAxis());
categoryAxis.dataFields.category = "Rpm";
// Create serie Nm
var nm = chart.series.push(new am4charts.LineSeries());
var maxNm = 404.24;
nm.dataFields.valueY = "Nm";
nm.dataFields.categoryX = "Rpm";
nm.yAxis = valueAxis;
nm.name = "Nm";
nm.strokeWidth = 1;
//nm.tensionX = 0.7;
nm.tooltipText = "{valueY.value} Nm";
var hp = chart.series.push(new am4charts.LineSeries());
var maxHP = 327.7;
hp.dataFields.valueY = "Hp";
hp.dataFields.categoryX = "Rpm";
hp.yAxis = valueAxis;
hp.name = "Hp";
hp.strokeWidth = 1;
//hp.tensionX = 0.7;
hp.tooltipText = "{valueY.value} Hp";
// Add legend
chart.legend = new am4charts.Legend();
// Add cursor
chart.cursor = new am4charts.XYCursor();
Updated a CodePen with the result.
https://codepen.io/lasse-kofoed/pen/eYmprPR
Found that using the event beforedatavalidated you can alter the data and set a field to false.
And then set propertyFields.disabled = true on a bullet object ( hides all bullets )
and .propertyFields.disabled to the field name that was added to the data list item ( show on bullets on values that have the field set to false )
chart.series.values[0].dataItem.values.valueY
Also found that the max and min values can be found here, but is not using that information in the example
// Add max Torque bullet
var maxTorque = nm.bullets.push(new am4charts.CircleBullet());
maxTorque.disabled = true;
maxTorque.propertyFields.disabled = "maxTorque";
maxTorque.radius = 8;
maxTorque.strokeWidth = 2;
maxTorque.stroke = am4core.color("#fff");
var maxTorqueLabel = nm.bullets.push(new am4charts.LabelBullet());
maxTorqueLabel.label.text = "Max torque\n[bold]{valueY} {name}#{categoryX}[/]";
maxTorqueLabel.disabled = true;
maxTorqueLabel.propertyFields.disabled = "maxTorque";
maxTorqueLabel.label.dy = -30;
// Add max Power bullet
var maxPower = hp.bullets.push(new am4charts.CircleBullet());
maxPower.disabled = true;
maxPower.propertyFields.disabled = "maxPower";
var maxPowerLabel = hp.bullets.push(new am4charts.LabelBullet());
maxPowerLabel.label.text = "Max power\n[bold]{valueY} {name}#{categoryX}[/]";
maxPowerLabel.disabled = true;
maxPowerLabel.propertyFields.disabled = "maxPower";
maxPowerLabel.label.dy = -30;
chart.events.on("beforedatavalidated", function(ev) {
var maxT = chart.data.find(x => x.Rpm === "5221");
var maxP = chart.data.find(x=> x.Rpm === "5888");
if(typeof maxT !== "undefined")
{
maxT.maxTorque = false;
}
if(typeof maxP !== "undefined")
{
maxP.maxPower = false;
}
});

how to remove lines from amcharts map Dynamically

I want to remove Lines from amcharts maps dynamically. I can add lines dynamically but not able to remove it dynamically
var chart = am4core.create("chartdiv", am4maps.MapChart);
chart.geodata = am4geodata_worldLow;
chart.projection = new am4maps.projections.Miller();
var markerPoints = [];
// Create map polygon series
var polygonSeries = chart.series.push(new am4maps.MapPolygonSeries());
polygonSeries.useGeodata = true;
polygonSeries.mapPolygons.template.fill = chart.colors.getIndex(0).lighten(0.5);
polygonSeries.mapPolygons.template.nonScalingStroke = true;
polygonSeries.exclude = ["AQ"];
var points = chart.series.push(new am4maps.MapImageSeries());
points.mapImages.template.nonScaling = true;
var marker = points.mapImages.template.createChild(am4core.Circle);
marker.radius = 1;
marker.fill = am4core.color("yellow");
marker.strokeWidth = 0;
marker.stroke = am4core.color("yellow");
marker.tooltipText = '{title}';
points.mapImages.template.propertyFields.latitude = "latitude";
points.mapImages.template.propertyFields.longitude = "longitude";
function addPoint(coords, title) { // this is function to add points on map
var marker = points.mapImages.create();
marker.latitude = coords.latitude;
marker.longitude = coords.longitude;
return marker;
}
var paris = addPoint({ "latitude": 48.8567, "longitude": 2.3510 }, "Paris");
var toronto = addPoint({ "latitude": 43.8163, "longitude": -79.4287 }, "Toronto");
var lineSeries = chart.series.push(new am4maps.MapArcSeries());
lineSeries.mapLines.template.line.strokeWidth = 2;
lineSeries.mapLines.template.line.strokeOpamarker = 0.5;
lineSeries.mapLines.template.line.stroke = marker.fill;
lineSeries.mapLines.template.line.nonScalingStroke = true;
lineSeries.mapLines.template.line.strokeDasharray = "1,5";
function addLine(from, to) {
var line = lineSeries.mapLines.create();
line.imagesToConnect = [from, to];
line.line.controlPointDistance = -0.3;
return line;
}
addLine(paris, toronto);
setInterval(function(){
addLine(somePoint,somePoint);
removeLine()//how to implement this one
},1000);
I want to implement a function or line of code that remove those lines which has already drawn inside setInterval ..
for bullets var bulletAttack = bullet.createChild(am4core.Sprite); I use:
bullet.hide();
bullet.kill();
maybe it will help you.
try below command before adding new line and it will fix your issue.
lineSeries.mapLines.removeIndex(0)

How to change the wall color or image in Three js?

i have created wall using path in three js. I want change the color option buttion automatically need to change the color onclick event.
Below my color any one help me.
// wall 1 inside
item_count = 1;
var wall_x1 = 69;
var wall_y1 = 55;
var wall_x2 = 366;
var wall_y2 = 52;
var wall_z = 0;
var wall_width = 5;
var wall_height = default_height;
var wall_wall_width = 5;
if(!wall_wall_width) { wall_wall_width = 5; }
var wall_wall_elevation = planner_default_height;
if(!wall_wall_elevation) { wall_wall_elevation = default_height; }
var wall_top_filltype = 'texture';
var wall_top_fill = 'default_wall.jpg';
var wall_side_filltype = 'texture';
var wall_side_fill = 'wall5.jpg';
if ( item_count == 0 )
{
starting_x_value = wall_x1;
starting_y_value = wall_y1;
}
path = generate_path_byline(wall_x1,wall_y1,wall_x2,wall_y2,default_depth);
path_type ="wall";
x=starting_x_value-wall_x1; y=starting_y_value-wall_y1;
// z=default_height/2;
path_transform = transformSVGPath(path);
create_surface(1,1,path_type,path_transform,starting_x_value,starting_y_value,x,y,z,default_height,wall_wall_elevation,wall_top_filltype,wall_top_fill,wall_side_filltype,wall_side_fill);
I see no clear way of defining the material at your sample code, or at least the way three.js does it:
var material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
If you use as a material a texture with an image, you have many ways to change its color... one easy trick could be to change the light color that lightens the scene or this object.

How to show polynomial tread line in Am-Line chart

How can i show a polynomial tread line in Am-line chart. I'm getting a straight trend line here, i need a polynomial trend line. My javascript code is shown below. Please someone help me to solve this issue.
function GenChartData() {
var data1 = [0.234761158, 0.23816127, 0.263960124, 0.282558558, 0.300607979, 0.318197719, 0.316059534, 0.319133276, 0.322505238, 0.323926338, 0.323720379, 0.3203703, 0.318837626, 0.318380371, 0.321465339, 0.316398839, 0.310238176, 0.301206892, 0.278454166, 0.268778255, 0.250299958, 0.23754735, 0.216277621, 0.182483871, 0.152057602, 0.129372542, 0.079524595, 0.044074801, 0.007279248, -0.021369877, -0.022801251, -0.043247196, -0.060677351, -0.055932729, -0.055847788, -0.032625365, -0.027289726, -0.022615401, -0.010850169, 0.015833104, 0.043923065, 0.055500831, 0.048043121, 0.054154849, 0.064038257, 0.049914887, 0.046542406, 0.03154397, 0.033614909, 0.030570225, 0.035606699, 0.001179461, -0.028934007, -0.019034206, 2.30344E-05];
var dates = ["12/31/2001", "1/31/2002", "2/28/2002", "3/31/2002", "4/30/2002", "5/31/2002", "6/30/2002", "7/31/2002", "8/31/2002", "9/30/2002", "10/31/2002", "11/30/2002", "12/31/2002", "1/31/2003", "2/28/2003", "3/31/2003", "4/30/2003", "5/31/2003", "6/30/2003", "7/31/2003", "8/31/2003", "9/30/2003", "10/31/2003", "11/30/2003", "12/31/2003", "1/31/2004", "2/29/2004", "3/31/2004", "4/30/2004", "5/31/2004", "6/30/2004", "7/31/2004", "8/31/2004", "9/30/2004", "10/31/2004", "11/30/2004", "12/31/2004", "1/31/2005", "2/28/2005", "3/31/2005", "4/30/2005", "5/31/2005", "6/30/2005", "7/31/2005", "8/31/2005", "9/30/2005", "10/31/2005", "11/30/2005", "12/31/2005", "1/31/2006", "2/28/2006", "3/31/2006", "4/30/2006", "5/31/2006", "6/30/2006"];
for (var i = 0; i < dates.length; i++) {
chartData.push({
date: new Date(dates[i]),
data1: data1[i]});
}
}
AmCharts.ready(function () {
// SERIAL CHART
GenChartData();
chart = new AmCharts.AmSerialChart();
chart.pathToImages = "JS/AmFiles/amcharts/images/";
chart.marginTop = 0;
chart.marginRight = 10;
chart.autoMarginOffset = 5;
//chart.backgroundColor = "#CCCCC";
chart.zoomOutButton = {
backgroundColor: '#000000',
backgroundAlpha: 0.15
};
chart.dataProvider = chartData;
chart.categoryField = "date";
// listen for "dataUpdated" event (fired when chart is rendered) and call zoomChart method when it happens
chart.addListener("dataUpdated", zoomChart);
// AXES
// category
var categoryAxis = chart.categoryAxis;
categoryAxis.parseDates = true; // as our data is date-based, we set parseDates to true
categoryAxis.minPeriod = "MM"; // our data is daily, so we set minPeriod to DD
categoryAxis.dashLength = 1;
categoryAxis.gridAlpha = 0.15;
categoryAxis.axisColor = "#DADADA";
categoryAxis.labelFrequency = 1;
categoryAxis.equalSpacing = true;
// value
var valueAxis = new AmCharts.ValueAxis();
valueAxis.axisAlpha = 0.2;
valueAxis.dashLength = 1;
chart.addValueAxis(valueAxis);
graph = new AmCharts.AmGraph();
graph.type = "smoothedLine";
graph.lineColor = "#180ad1";
graph.negativeLineColor = "#180ad1";
graph.bullet = "round";
graph.bulletSize = 5;
graph.lineThickness = 2;
graph.valueField = "data1";
chart.addGraph(graph);
// CURSOR
chartCursor = new AmCharts.ChartCursor();
chartCursor.cursorPosition = "mouse";
chart.addChartCursor(chartCursor);
// TREND LINES
// first trend line
var trendLine = new AmCharts.TrendLine();
trendLine.initialDate = new Date(chartData[0].date); // 12 is hour - to start trend line in the middle of the day
trendLine.finalDate = new Date(chartData[chartData.length-1].date);
trendLine.initialValue = 0.234761158;
trendLine.finalValue = 2.30344E-05;
trendLine.lineColor = "#CC0000";
chart.addTrendLine(trendLine);
// WRITE
chart.write("chartdiv");
});
Thanks for your help
You would need to basically have another graphline on there rather than a trendline.
You can look at this example - http://www.amcharts.com/javascript-charts/line-with-different-bullet-sizes/
to see how to equip multiple data graphs.

Resources