The problem is what you see in the chart: http://www.fanta-trade.eu/chart.php?tipo=f&code=1450018272
The chart is not showing correctly the data according with the date.
The code probably might be here:
var categoryAxesSettings = new AmCharts.CategoryAxesSettings();
Full code:
AmCharts.ready( function() {
createStockChart();
} );
var chartData = [];
chartData.push({ date: new Date(2015, 11, 15, 13, 59, 0, 0), value: 203.84, volume: 1 });
chartData.push({ date: new Date(2015, 11, 15, 13, 36, 0, 0), value: 203.86, volume: 1 });
chartData.push({ date: new Date(2015, 11, 15, 12, 59, 0, 0), value: 203.86, volume: 1 });
chartData.push({ date: new Date(2015, 11, 15, 12, 37, 0, 0), value: 203.81, volume: 1 });
chartData.push({ date: new Date(2015, 11, 15, 12, 11, 0, 0), value: 203.8, volume: 1 });
chartData.push({ date: new Date(2015, 11, 15, 11, 34, 0, 0), value: 203.79, volume: 1 });
chartData.push({ date: new Date(2015, 11, 15, 4, 47, 0, 0), value: 203.68, volume: 1 });
chartData.push({ date: new Date(2015, 11, 14, 21, 41, 0, 0), value: 202.64, volume: 1 });
chartData.push({ date: new Date(2015, 11, 14, 18, 16, 0, 0), value: 199.73, volume: 1 });
chartData.push({ date: new Date(2015, 11, 14, 17, 52, 0, 0), value: 197.94, volume: 1 });
chartData.push({ date: new Date(2015, 11, 14, 17, 22, 0, 0), value: 199.83, volume: 1 });
chartData.push({ date: new Date(2015, 11, 14, 13, 11, 0, 0), value: 198.56, volume: 1 });
chartData.push({ date: new Date(2015, 11, 14, 8, 54, 0, 0), value: 198.56, volume: 1 });
chartData.push({ date: new Date(2015, 11, 14, 8, 0, 0, 0), value: 198.56, volume: 1 });
chartData.push({ date: new Date(2015, 11, 14, 2, 11, 0, 0), value: 198.56, volume: 1 });
chartData.push({ date: new Date(2015, 11, 14, 1, 13, 0, 0), value: 198.56, volume: 1 });
var chart;
function createStockChart() {
chart = new AmCharts.AmStockChart();
// DATASETS //////////////////////////////////////////
var dataSet = new AmCharts.DataSet();
dataSet.color = "#000000";
dataSet.fieldMappings = [{
fromField: "value",
toField: "value"
}, {
fromField: "volume",
toField: "volume"
}];
dataSet.dataProvider = chartData;
dataSet.categoryField = "date";
// set data sets to the chart
chart.dataSets = [dataSet];
// PANELS ///////////////////////////////////////////
// first stock panel
var stockPanel1 = new AmCharts.StockPanel();
stockPanel1.showCategoryAxis = false;
stockPanel1.title = "Price";
stockPanel1.percentHeight = 70;
// graph of first stock panel
var graph1 = new AmCharts.StockGraph();
graph1.valueField = "value";
graph1.type = "smoothedLine";
graph1.bullet = "round";
graph1.lineThickness = 2;
graph1.bulletBorderColor = "#FFFFFF";
graph1.bulletBorderAlpha = 1;
graph1.bulletBorderThickness = 3;
stockPanel1.addStockGraph(graph1);
// create stock legend
var stockLegend1 = new AmCharts.StockLegend();
stockLegend1.valueTextRegular = " ";
stockLegend1.markerType = "none";
stockPanel1.stockLegend = stockLegend1;
// second stock panel
var stockPanel2 = new AmCharts.StockPanel();
stockPanel2.title = "Volume";
stockPanel2.percentHeight = 30;
var graph2 = new AmCharts.StockGraph();
graph2.valueField = "volume";
graph2.type = "column";
graph2.fillAlphas = 1;
stockPanel2.addStockGraph(graph2);
// set panels to the chart
chart.panels = [stockPanel1];
// OTHER SETTINGS ////////////////////////////////////
var scrollbarSettings = new AmCharts.ChartScrollbarSettings();
scrollbarSettings.graph = graph1;
chart.chartScrollbarSettings = scrollbarSettings;
var cursorSettings = new AmCharts.ChartCursorSettings();
cursorSettings.valueBalloonsEnabled = true;
cursorSettings.graphBulletSize = 1;
chart.chartCursorSettings = cursorSettings;
var categoryAxesSettings = new AmCharts.CategoryAxesSettings();
categoryAxesSettings.minPeriod="mm";
chart.categoryAxesSettings = categoryAxesSettings;
// PERIOD SELECTOR ///////////////////////////////////
var periodSelector = new AmCharts.PeriodSelector();
periodSelector.periods = [{
period: "DD",
count: 10,
label: "10 days"
}, {
period: "MM",
count: 1,
selected: true,
label: "1 month"
}, {
period: "YYYY",
count: 1,
label: "1 year"
}, {
period: "YTD",
label: "YTD"
}, {
period: "MAX",
label: "MAX"
}];
chart.periodSelector = periodSelector;
var panelsSettings = new AmCharts.PanelsSettings();
panelsSettings.marginRight = 16;
panelsSettings.marginLeft = 16;
panelsSettings.usePrefixes = true;
chart.panelsSettings = panelsSettings;
dataSet.stockEvents = [];
chart.write('chartdiv');
}
The issue is very simple, actually.
Data in amCharts must come in ascending order. While you have it in descending, which creates all kinds of anomalies.
To fix simply add your data points in ascending order. For example use unshift() instead of push().
Or simply reverse() the result array:
chartData.reverse();
Here's the same chart with reversed data:
http://codepen.io/team/amcharts/pen/5d2891ce1710ce06dae34bebc2db8644
Related
I am racking my brain trying to get this code working, I am just starting out on SwiftUI and haven't found a solution. I have a math equation that adds the variables and accepts the answer input from the user. My issue is once the answer is correct, how can i get the variables numbers1 & numbers2 to refresh and grab new numbers and give another math problem?
import SwiftUI
import Foundation
struct ContentView: View {
#State private var answer = ""
#State private var number1 = ""
#State private var number2 = ""
#State private var messageText = ""
#State private var keyboardHeight: CGFloat = 0.0
var numbers1 : Int = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10].randomElement()!
var numbers2 : Int = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10].randomElement()!
var questionNumber = 0
var value = 0.00
var body: some View {
VStack {
ForEach((1...10).reversed(), id: \.self) {_ in
Text(self.number2)
}
Text("\(numbers1)")
.font(.largeTitle)
.padding()
Text("\(numbers2)")
.font(.largeTitle)
.padding()
TextField("answer", text: self.$answer)
.padding(/*#START_MENU_TOKEN#*/.all/*#END_MENU_TOKEN#*/)
.font(/*#START_MENU_TOKEN#*/.largeTitle/*#END_MENU_TOKEN#*/)
//.keyboardType(.numberPad)
Button(action: {
var addition: Int {
let addition = self.numbers1 + self.numbers2
return addition
}
print("submit button pressed")
print(addition)
if (self.answer == String(addition)) {
print("Answer is Correct!")
}
else {
print("Answer is Incorrect")
}
self.answer = ""
}) {
Text("Submit")
.font(.largeTitle)
.padding()
.background(Color.red)
.foregroundColor(.white)
.cornerRadius(40)
}
// .padding()
.actionSheet(isPresented: /*#START_MENU_TOKEN#*/ /*#PLACEHOLDER=Is Presented#*/.constant(false)/*#END_MENU_TOKEN#*/) {
ActionSheet(title: Text(/*#START_MENU_TOKEN#*/ /*#PLACEHOLDER=Title#*/"Action Sheet"/*#END_MENU_TOKEN#*/))
}
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
```
enter code here
what you can do is this:
declare
#State var numbers1 : Int = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10].randomElement()!
#State var numbers2 : Int = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10].randomElement()!
and
if (self.answer == String(addition)) {
print("Answer is Correct!")
self.numbers1 = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10].randomElement()!
self.numbers2 = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10].randomElement()!
}
or some variation of this, like storing the array in a var.
i have two types of data in one graph - the normal range (bars) and the value (line wiht bullets). if the value is more or less then the range - the color of bullet must be red, meaning that the value is not normal... How is it possible to pass there in the graph the precalculated color or calculate it by means of adapter function or any other working way?
image example
let data = [
{
code: "07090",
name: "Sodium",
result: 150,
unit: "mmol/L",
refMin: 137,
refMax: 149,
date: "2019-10-04"
},
{
code: "07090",
name: "Sodium",
result: 139,
unit: "mmol/L",
refMin: 135,
refMax: 147,
date: "2019-10-06"
},
{
code: "07090",
name: "Sodium",
result: 130,
unit: "mmol/L",
refMin: 135,
refMax: 147,
date: "2019-10-07"
},
{
code: "07090",
name: "Sodium",
result: 140,
unit: "mmol/L",
refMin: 135,
refMax: 147,
date: "2019-11-07"
},
{
code: "07090",
name: "Sodium",
result: 147,
unit: "mmol/L",
refMin: 135,
refMax: 147,
date: "2019-11-08"
},
{
code: "07090",
name: "Sodium",
result: 147,
unit: "mmol/L",
refMin: 134,
refMax: 146,
date: "2019-11-10"
},
{
code: "07090",
name: "Sodium",
result: 147,
unit: "mmol/L",
refMin: 134,
refMax: 146,
date: "2020-11-10"
},
{
code: "07090",
name: "Sodium",
result: 147,
unit: "mmol/L",
refMin: 134,
refMax: 146,
date: "2020-11-11"
}
];
let cols = [];
let lines = [];
let chartData = [];
for(let { result, refMin, refMax, date } of data) {
let markerColor = "#fff"; // !!!! the color is predefined here
if (result > refMax || result < refMin) {
markerColor = "#f00";
}
chartData.push({
date: new Date(date),
result: result,
colMin: refMin,
colMax: refMax,
markerColor
});
}
am4core.ready(function() {
// Themes begin
am4core.useTheme(am4themes_animated);
// Themes end
// Create chart instance
var chart = am4core.create("chartContainer", am4charts.XYChart);
chart.responsive.enabled = true;
// Add data
chart.data = chartData;
// Create axes
var dateAxis = chart.xAxes.push(new am4charts.DateAxis());
dateAxis.renderer.minGridDistance = 50;
var valueAxis = chart.yAxes.push(new am4charts.ValueAxis());
var seriesCols = chart.series.push(new am4charts.ColumnSeries());
seriesCols.dataFields.dateX = "date";
seriesCols.dataFields.valueY = "colMax";
seriesCols.dataFields.openValueY = "colMin";
seriesCols.fill = am4core.color("#ccc");
seriesCols.strokeWidth = 0;
seriesCols.name = "Range";
seriesCols.tooltipText = "{colMin} - {colMax}";
seriesCols.tooltip.pointerOrientation = "horizontal";
seriesCols.tooltip.background.cornerRadius = 0;
seriesCols.tooltip.background.fillOpacity = 0.5;
seriesCols.tooltip.label.padding(10,10,7,10);
// Create series
var series = chart.series.push(new am4charts.LineSeries());
let circleBullet = series.bullets.push(new am4charts.CircleBullet());
circleBullet.circle.stroke = "#fff";
circleBullet.circle.fillOpacity = ".7";
circleBullet.circle.strokeWidth = 1;
series.dataFields.valueY = "result";
series.dataFields.dateX = "date";
series.dataFields.dummyData = "date";
series.strokeWidth = 2;
series.minBulletDistance = 30;
series.tooltipText = "{valueY}";
series.tooltip.pointerOrientation = "vertical";
series.tooltip.background.cornerRadius = 20;
series.tooltip.background.fillOpacity = 0.5;
series.tooltip.label.padding(12,12,12,12);
series.dummyData = { color: "markerColor" };
series.adapter.add("fill", function(fill, lalal) {
return fill;
});
// Add scrollbar
chart.scrollbarX = new am4charts.XYChartScrollbar();
chart.scrollbarX.series.push(series);
// Add cursor
chart.cursor = new am4charts.XYCursor();
chart.cursor.xAxis = dateAxis;
chart.cursor.snapToSeries = series;
});
SOLVED:
circleBullet.propertyFields.fill = "bulletColor";
I'm using Plotly.js to draw a 3-D scatter plot . On zoom , I want to check which points are visible . Can this be done on svg level ? or any plotly expert ?
Snippet:
var myPlot = document.getElementById("myDiv");
var trace = {
x: [1, 7, 2, 4,1],
y: [12, 9, 15, 12,2],
z: [1, 2, 4, 8,4],
// x: [1,2],
//y: [12,15],
//z: [1, 4],
mode: 'markers' ,
type: 'scatter3d' ,
marker: {size:5 }
}
var data = [trace];
var layout = {
margin: {
l: 0,
r: 0,
b: 0,
t: 0} ,
//title: {text: 'ReOptim8 Scatter Plot'},
scene: {
yaxis:{title: 'X-axis'},
xaxis:{title: 'y-axis'},
zaxis:{title: 'z-axis'},
camera: {eye: {x:1.25, y:1.25, z:1.25}}
}
};
var config = {
displayModebar : true,
displaylogo: false,
responsive: true
};
Plotly.plot( myPlot, data, layout, config );
Code pen link below :
https://codepen.io/aniwar/pen/wLOzZv
I found the code from here:
On load Google LineChart animation
google.load('visualization', '1', { packages: ['corechart'], callback: function() {
var data = new google.visualization.DataTable();
data.addRows(5);
data.addColumn('string', '');
data.addColumn('number', 'Sales');
data.addRows(5);
data.setValue(0, 0, 'Jan');
data.setValue(1, 0, 'Feb');
data.setValue(2, 0, 'Mar');
data.setValue(3, 0, 'Apr');
data.setValue(4, 0, 'May');
var options = {
title: 'Sales by months for 2013 year', curveType: 'function',
"vAxis": { "minValue": "0", "maxValue": 6 }, "hAxis": { "slantedTextAngle": "45", "slantedText": "true" }, "legend": { "position": "top" }, "pointSize": "5",
animation: { duration: 250 }
};
var chart = new google.visualization.LineChart(document.getElementById('test'));
var index = 0;
var chartData = [ 5, 1, 4, 2, 3 ]
var drawChart = function() {
console.log('drawChart index ' + index);
if (index < chartData.length) {
data.setValue(index, 1, chartData[index++]);
chart.draw(data, options);
}
}
google.visualization.events.addListener(chart, 'animationfinish', drawChart);
chart.draw(data, options);
drawChart();
}});
If I want to create multi-line, how to modify this code? Thanks!
I'm not a javascript programmer and not familiar with OOP
The author is OneMoreVladimir, but I don't have the access to comment under his post.
google.load('visualization', '1', {
packages: ['corechart'],
callback: function() {
var data = new google.visualization.DataTable();
data.addRows(5);
data.addColumn('string', '');
data.addColumn('number', 'Sales');
data.addColumn('number', 'Sales2');
data.addRows(5);
data.setValue(0, 0, 'Jan');
data.setValue(1, 0, 'Feb');
data.setValue(2, 0, 'Mar');
data.setValue(3, 0, 'Apr');
data.setValue(4, 0, 'May');
var options = {
title: 'Sales by months for 2013 year',
curveType: 'function',
"vAxis": {
"minValue": "0",
"maxValue": 8
},
"hAxis": {
"slantedTextAngle": "45",
"slantedText": "true"
},
"legend": {
"position": "top"
},
"pointSize": "5",
animation: {
duration: 600
}
};
var chart = new google.visualization.LineChart(document.getElementById('test'));
var index = 0;
var chartData = [5, 1, 4, 2, 3]
var drawChart = function() {
console.log('drawChart index ' + index);
if (index < chartData.length) {
data.setValue(index, 1, chartData[index++]);
chart.draw(data, options);
}
}
var index1 = 0;
var chartData1 = [1, 3, 4, 6, 5]
var drawChart1 = function() {
console.log('drawChart1 index1 ' + index1);
if (index1 < chartData1.length) {
data.setValue(index1, 2, chartData1[index1++]);
chart.draw(data, options);
}
}
google.visualization.events.addListener(chart, 'animationfinish', drawChart);
google.visualization.events.addListener(chart, 'animationfinish', drawChart1);
chart.draw(data, options);
drawChart();
drawChart1();
}
});
I figure out! Here is the code.
But another question, the code pass the http://jsfiddle.net and run very well, but when I copy paste it into the HTML why it doesn't work? Did I miss something?
Here is the structure of data1
var data1 = [{
"Date": "2016-07-09",
"StockList": [{"Name": "H1", "PNL2": 20, "NAV2" : 20}, {"Name": "H2", "PNL2": 20, "NAV2" : 20}]
"NAV": 26.28,
"PNL": 7.61
}, {
"Date": "2016-07-10",
"StockList": [{"Name": "H1", "PNL2": 20, "NAV2" : 20}, {"Name": "H2", "PNL2": 20, "NAV2" : 20}]
"NAV": 27.55,
"PNL": 12.89
}];
since nested data is not allowed in the Amcharts(if there is a way to deal with the nested data, that is better), is it possible flat the into the top level object(I can not change the original inputed data). For example:
var data1 = [{
"Date": "2016-07-09",
"H1_PNL2": 20,
"H1_NAV2" : 20
"H2_PNL2": 20,
"H2_NAV2" : 20,
"NAV": 26.28,
"PNL": 7.61
}, {
"Date": "2016-07-10",
"H1_PNL2": 20,
"H1_NAV2" : 20
"H2_PNL2": 20,
"H2_NAV2" : 20,
"NAV": 27.55,
"PNL": 12.89
}];
In such Amcharts code:
var dataSet1 = new AmCharts.DataSet();
dataSet1.color = "#b0de09";
//create your field mappings for each valueField
dataSet1.fieldMappings = valueFields.map(function(valueField) {
return {
fromField: valueField,
toField: valueField
};
});
dataSet1.dataProvider = data;
dataSet1.categoryField = "Date";
chart.dataSets = [dataSet1];
// PANELS
var stockPanel = new AmCharts.StockPanel();
stockPanel.showCategoryAxis = true;
stockPanel.title = "PNL2";
stockPanel.eraseAll = false;
//stockPanel.addLabel(0, 100, "Click on the pencil icon on top-right to start drawing", "center", 16);
//create a graph for each valueField
valueFields.forEach(function(valueField) {
var graph = new AmCharts.StockGraph();
graph.title = valueField;
graph.valueField = valueField;
graph.bullet = "round";
graph.bulletColor = "#FFFFFF";
graph.bulletBorderColor = "#00BBCC";
graph.bulletBorderAlpha = 1;
graph.bulletBorderThickness = 2;
graph.bulletSize = 7;
graph.lineThickness = 2;
graph.lineColor = "#00BBCC";
graph.useDataSetColors = false;
stockPanel.addStockGraph(graph);
});
chart.addPanel(stockPanel);
chart.write("chartdiv");
}
createStockChart(data1);
Here is my data structure
[{,…}, {,…}, {,…}, {,…}, {,…}, {,…}, {,…}, {,…}, {,…}, {,…}, {,…}, {,…}, {,…}, {,…}, {,…}, {,…}, {,…},…]
[0 … 99]
0:{,…}
CashLeft:0
Commission:0
Date:"/Date(1454428800000)/"
NAV:0
PNL:0
Performance:[{
0:{Stock: {Symbol: "1044 HK", Close: 66.714, Date: "/Date(1454428800000)/"}, Position: 0,…}
1:{Stock: {Symbol: "1088 HK", Close: 10.9, Date: "/Date(1454428800000)/"}, Position: 0,…}
2:{Stock: {Symbol: "12 HK", Close: 35.955, Date: "/Date(1454428800000)/"}, Position: 0,…}
And here is the code I write down
function createStockChart(data) {
var chart = new AmCharts.AmStockChart();
data.forEach(function (data1) {
data1.Performance.forEach(function (stockItem) {
data1[stockItem.Symbol + "_PNL2"] = stockItem.PNL2;
});
//the following are completely optional - AmCharts won't look at StockList, but if you
//want to conserve memory and don't need the StockList for anything else, you can remove
//it
data1.StockList.length = 0; //delete the StockList Array. Not necessary if you need it for something else
delete data1.StockList; //remove the property from the object if you want. Also not necessary.
});
But when I see the data structure it does not change, Maybe here is the problem that the List of stock(I mean the name(Symbol)) will be changed some days later, that means the properties of data will changed periodically, I don't know whether it is the point?
Assuming your StockList will always have a Name, PNL2 and NAV2, you can just loop through your data and assign the properties and values to the object prior to the rest of your code.
data1.forEach(function(arrayElement) {
arrayElement.StockList.forEach(function(stockItem) {
arrayElement[stockItem.Name + "_PNL2"] = stockItem.PNL2;
arrayElement[stockItem.Name + "_NAV2"] = stockItem.NAV2;
});
//the following are completely optional - AmCharts won't look at StockList, but if you
//want to conserve memory and don't need the StockList for anything else, you can remove
//it
arrayElement.StockList.length = 0; //delete the StockList Array. Not necessary if you need it for something else
delete arrayElement.StockList; //remove the property from the object if you want. Also not necessary.
});
From there you can just run the rest of your code from my previous answer.
Demo:
var data1 = [{
"Date": "2016-07-09",
"StockList": [{
"Name": "H1",
"PNL2": 20,
"NAV2": 20
}, {
"Name": "H2",
"PNL2": 20,
"NAV2": 20
}],
"NAV": 26.28,
"PNL": 7.61
}, {
"Date": "2016-07-10",
"StockList": [{
"Name": "H1",
"PNL2": 20,
"NAV2": 20
}, {
"Name": "H2",
"PNL2": 20,
"NAV2": 20
}],
"NAV": 27.55,
"PNL": 12.89
}];
data1.forEach(function(arrayElement) {
arrayElement.StockList.forEach(function(stockItem) {
arrayElement[stockItem.Name + "_PNL2"] = stockItem.PNL2;
arrayElement[stockItem.Name + "_NAV2"] = stockItem.NAV2;
});
//the following are completely optional - AmCharts won't look at StockList, but if you
//want to conserve memory and don't need the StockList for anything else, you can remove
//it
arrayElement.StockList.length = 0; //delete the StockList Array. Not necessary if you need it for something else
delete arrayElement.StockList; //remove the property from the object if you want. Also not necessary.
});
console.log(data1);