How to show all tooltip Text where line series circle bullets intersect Amcharts 4? - amcharts4

I am using a Amcharts4 Line series with valueX and valueY instead of categoryX.
Currently I am able to see the tooltip on a hover of bullet/bubble but I also want to see the tooltip of all bullets if they are intersecting and overlapping with each other.
It shows the tooltip if i hover on a single bullet/bubble but if you see the red and green line intersecting each other, it shows the tooltip of green bullet/bubble only, not the other which is hidden at its back.
Click here to see Line Series graph with ValueX and ValueY
This is my code where I am having 3 series and setup a tooltip for each bullet :
let series1 = chart.series.push(new am4charts.LineSeries());
series1.cursorTooltipEnabled = true;
series1.showTooltipOn = 'hover';
series1.dataFields.valueY = "compressorCap";
// series1.dataFields.categoryX = "evapDegC"; // If X-Axis is Category Axis
series1.dataFields.valueX = "evapDegC"; // If X-Axis is Value Axis
series1.name = "Compressor capacity";
let series1toolTip = series1.bullets.push(new am4charts.CircleBullet());
series1toolTip.tooltipText = "{name} in {valueX}°C => {valueY}";
series1.tooltip.getFillFromObject = false;
series1.tooltip.background.fill = am4core.color("#b9a9e6");
series1.legendSettings.valueText = "{valueY}";
series1.visible = false;
series1.stroke = am4core.color("#b9a9e6");
let series2 = chart.series.push(new am4charts.LineSeries());
series2.cursorTooltipEnabled = true;
series2.showTooltipOn = 'hover';
series2.dataFields.valueY = "evapCoilCap";
// series2.dataFields.categoryX = "evapDegC"; // If X-Axis is Category Axis
series2.dataFields.valueX = "evapDegC"; // If X-Axis is Value Axis
series2.name = 'Evaporator coil capacity';
let series2toolTip = series2.bullets.push(new am4charts.CircleBullet());
series2toolTip.tooltipText = "{name} in {valueX}°C => {valueY}";
series2.tooltip.getFillFromObject = false;
series2.tooltip.background.fill = am4core.color("red");
series2.legendSettings.valueText = "{valueY}";
series2.stroke = am4core.color("red");
let series3 = chart.series.push(new am4charts.LineSeries());
series3.cursorTooltipEnabled = true;
series3.showTooltipOn = 'hover';
series3.dataFields.valueY = "evapCoilSensibleCap";
// series3.dataFields.categoryX = "evapDegC"; // If X-Axis is Category Axis
series3.dataFields.valueX = "evapDegC"; // If X-Axis is Value Axis
series3.name = 'Evaporator sensible cooling capacity ';
let series3toolTip = series3.bullets.push(new am4charts.CircleBullet());
series3toolTip.tooltipText = "{name} in {valueX}°C => {valueY}";
series3.tooltip.getFillFromObject = false;
series3.tooltip.background.fill = am4core.color("#13bb37");
series3.legendSettings.valueText = "{valueY}";
series3.stroke = am4core.color("#13bb37");
// Add chart cursor
chart.cursor = new am4charts.XYCursor();
chart.cursor.behavior = "zoomY";

In order to display multiple tooltips, you need to set tooltipText directly on series, not on a bullet.
series.tooltipText = "{name} in {valueX}°C => {valueY}";
That's the first step, though. Since you are using all-ValueAxis scenario, you will also need to apply a workaround as stated in this tutorial.
am4charts.ValueAxis.prototype.getSeriesDataItem = function(series, position) {
var key = this.axisFieldName + this.axisLetter;
var value = this.positionToValue(position);
var dataItem = series.dataItems.getIndex(series.dataItems.findClosestIndex(value, function(x) {
return x[key] ? x[key] : undefined;
}, "any"));
return dataItem;
}
This will enable multi-cursors across all charts.
Or if you want to enable for just for a single axis:
valueAxisX.getSeriesDataItem = function(series, position) {
var key = this.axisFieldName + this.axisLetter;
var value = this.positionToValue(position);
var dataItem = series.dataItems.getIndex(series.dataItems.findClosestIndex(value, function(x) {
return x[key] ? x[key] : undefined;
}, "any"));
return dataItem;
}
If you don't want to show all tooltips for all the series all the time, you can set cursor's maxTooltipDistance to a small number so that multiple tooltips are shown only if target items are closely packged together, e.g.:
chart.cursor.maxTooltipDistance = 10;

Related

How to Add Image/Shape with chart data label in ASPOSE Slide

Can we add any shape/image with chart data labels in ASPOSE .I need to show one arrow with different colors according to certain values with each data labels in the chart. i am using ASPOSE to generate my ppt. Or there is any way to find the data label positions in ASPOSE.
I have observed your requirements and like to share that MS PowerPoint supports LineWithMarker chart that can display different predefined or custom marker symbols(in the form of image) for different series data points. Please try using following sample code for possible options using Aspose.Slides and MSO charts.
public static void TestScatter()
{
var location = System.Reflection.Assembly.GetExecutingAssembly().Location;
//Open a presentation
Presentation pres = new Presentation();
IChart chart = pres.Slides[0].Shapes.AddChart(ChartType.StackedLineWithMarkers, 10, 10, 400, 400);
//populating cycle
var serie = chart.ChartData.Series[0];
var wbk = chart.ChartData.ChartDataWorkbook;
chart.ChartData.Series.RemoveAt(1);
chart.ChartData.Series.RemoveAt(1);
serie.Marker.Format.Fill.FillType = FillType.Picture;
serie.Marker.Size = 20;
// Set the picture
System.Drawing.Image img = (System.Drawing.Image)new Bitmap(#"C:\Users\Public\Pictures\Sample Pictures\Tulips.jpg");
IPPImage imgx = pres.Images.AddImage(img);
serie.Marker.Format.Fill.PictureFillFormat.Picture.Image = imgx;
//For individual data point
serie.DataPoints[0].Marker.Format.Fill.FillType = FillType.Solid;
serie.DataPoints[0].Marker.Format.Fill.SolidFillColor.Color = Color.Red;
serie.DataPoints[0].Marker.Size = 20;
serie.DataPoints[0].Marker.Symbol = MarkerStyleType.Triangle;
serie.DataPoints[0].Label.DataLabelFormat.ShowValue = true;
serie.DataPoints[1].Label.DataLabelFormat.ShowValue = true;
serie.DataPoints[2].Label.DataLabelFormat.ShowValue = true;
serie.DataPoints[3].Label.DataLabelFormat.ShowValue = true;
pres.Save(Path.Combine(Path.GetDirectoryName(location), "Result2.pptx"), SaveFormat.Pptx);
}
I am working as Support developer/ Evangelist at Aspose.
Many Thanks,
I have further observed your requirements and have observed that you have also posted the similar requirements in Aspose.Slides official support forum as well. Please try using following sample code on your end to serve the purpose.
public static void TestLineChart()
{
var location = System.Reflection.Assembly.GetExecutingAssembly().Location;
//Open a presentation
Presentation pres = new Presentation();
IChart chart = pres.Slides[0].Shapes.AddChart(ChartType.StackedLineWithMarkers, 10, 10, 400, 400);
//populating cycle
var serie = chart.ChartData.Series[0];
var wbk = chart.ChartData.ChartDataWorkbook;
chart.ChartData.Series.RemoveAt(1);
chart.ChartData.Series.RemoveAt(1);
serie.Marker.Format.Fill.FillType = FillType.Picture;
serie.Marker.Size = 20;
serie.Marker.Symbol = MarkerStyleType.Diamond;
serie.Marker.Format.Fill.FillType = FillType.Solid;
serie.Marker.Format.Fill.SolidFillColor.Color=Color.Orange;
serie.Marker.Format.Line.FillFormat.FillType = FillType.Solid;
serie.Marker.Format.Line.FillFormat.SolidFillColor.Color=Color.Red;
serie.Marker.Format.Line.Width=1.0F;
serie.Format.Line.Width = 3.0f;
serie.Format.Line.FillFormat.FillType=FillType.Solid;
serie.Format.Line.FillFormat.SolidFillColor.Color = Color.FromArgb(209,225,91) ;
for(int i=0;i<serie.DataPoints.Count;i++)
{
serie.DataPoints[i].Label.DataLabelFormat.ShowValue = true;
IDataLabel label=serie.Labels[i];
chart.ValidateChartLayout();
IAutoShape ashp=chart.UserShapes.Shapes.AddAutoShape(ShapeType.Triangle,chart.X + label.ActualX + 5, chart.Y + label.ActualY + 5, 20,20);
ashp.FillFormat.FillType = FillType.Solid;
ashp.LineFormat.FillFormat.FillType = FillType.NoFill;
if (i % 2 == 0)//even data points
{
ashp.FillFormat.SolidFillColor.Color = Color.Green;
}
else
{
ashp.Rotation = 180;
ashp.FillFormat.SolidFillColor.Color = Color.Red;
}
}
pres.Save(Path.Combine(Path.GetDirectoryName(location), "Result2.pptx"), Aspose.Slides.Export.SaveFormat.Pptx);
}
I am working as Support developer/ Evangelist at Aspose.
Many Thanks,

changing sprite frame depending on random value

I have a list of buttons(currently images) and i want to change the image color depending on the value that is taken from the list
buttons = {"btn1","btn2","btn3","btn4"}
local buttonSheetData = {
width = 150,
height = 150,
numFrames = 2,
sheetContentWidth = 300,
sheetcontentheight = 150,
}
local buttonSheet = graphics.newImageSheet("image/buttonSS.png", buttonSheetData)
local sequenceData = {
{name = "black", start = 1, count = 1},
{name = "red", start = 2, count = 1}
}
local btn1 = display.newSprite(buttonSheet, sequenceData)
btn1.x = 100
btn1.y = 90
local btn2 = display.newSprite(buttonSheet, sequenceData)
btn2.x = 200
btn2.y = 230
local btn3 = display.newSprite(buttonSheet, sequenceData)
btn3.x = 300
btn3.y = 90
local btn4 = display.newSprite(buttonSheet, sequenceData)
btn4.x = 400
btn4.y = 230
x = buttons[math.random(#buttons)]
x:setFrame(2)
The circles are currently black. every time i run the code i want it to take a random value from the list and change the color to red. so there is a different red circle when i run the code
I keep getting the error:
"Attemp to call method 'setSequence' (a nill value)"
You're code is treating strings and variable names as if they are interchangeable. The first line:
buttons = {"btn1","btn2","btn3","btn4"}
creates a table of strings, so the line:
x = buttons[math.random(#buttons)]
will set x to be a random entry of buttons which are strings so the next line (x:setFrame(2)) is calling a method that doesn't exist on a string.
Instead, create a table of your buttons:
buttons = {btn1,btn2,btn3,btn4} -- creates a table of buttons
x = buttons[math.random(#buttons)] -- x is a random entry of buttons (a button)

Photoshop CS4 Script or Action to: Write 0 to 100 on separate text layers

My goal is to create 101 separate text layers containing 0-100 (i.e. 1, 2, 3...100) I know I can mass change the attributes but cant write or alter the containing text.
What you want can easily be done with a script (easier than renaming 100 layers in all the right order and record an action for it) This script will create 100 layers of text, each layer will be named 1,2,3..etc and the text will be the same. I think that's waht you are after, your description was rather short.
// call the source document
var srcDoc = app.activeDocument;
var numOfLayers = 100;
//var numOfLayers = srcDoc.layers.length;
var numPadding = "0";
var layerNum = 1; // change this to 0 to start layers at 0
var w = Math.floor(srcDoc.width.value/2);
var h = Math.floor(srcDoc.height.value/2);
// main loop starts here
for (var i = numOfLayers -1; i >= 0 ; i--)
{
if (layerNum < 10) numPadding = "0";
else numPadding ="";
createText("Arial-BoldMT", 20.0, 0,0,0, layerNum, w, h);
var currentLayer = srcDoc.activeLayer;
currentLayer.name = numPadding + layerNum;
layerNum +=1;
}
// function CREATE TEXT(typeface, size, R, G, B, content, Xpos, Ypos)
// --------------------------------------------------------
function createText(fface, size, colR, colG, colB, content, tX, tY)
{
var artLayerRef = srcDoc.artLayers.add()
artLayerRef.kind = LayerKind.TEXT
textColor = new SolidColor();
textColor.rgb.red = colR;
textColor.rgb.green = colG;
textColor.rgb.blue = colB;
textItemRef = artLayerRef.textItem
textItemRef.font = fface;
textItemRef.contents = content;
textItemRef.color = textColor;
textItemRef.size = size
textItemRef.position = new Array(tX, tY) //pixels from the left, pixels from the top
activeDocument.activeLayer.textItem.justification.CENTER
}
Save this out as numberLayers1-100.jsx and then reun it from Photoshop via the Files -> Scripts menu.

Visualisation table color formatting for complete row based a cell value

I have a Visualisation table with server side constructed JSON.When I try to use color formatting based on cell value, it applies for particular only. I need to apply color for complete row based on the single cell value.
For Example,
C1 C2 C3 C4
R1 - - - 0 // This row should be "red"
R2 - - - 1 // This row should be "green"
R3 - - - 0
R4 - - - 1
But the color applies for C4 only.
MyCode :
var dataTable = new google.visualization.DataTable(data, 0.5);
var formatter_short1 = new google.visualization.DateFormat({pattern:'h:mm aa'});
formatter_short1.format(dataTable,1);
formatter_short1.format(dataTable,2);
var view = new google.visualization.DataView(dataTable);
view.hideColumns([0,3,4,5,8,9,14]);
var color_formatter = new google.visualization.ColorFormat();
color_formatter.addRange(0,1, 'green', 'orange');
color_formatter.addRange(1,null, 'orange', 'green');
//color_formatter.format(dataTable, 1,2,6,7,9,11,12,13); // Apply formatter to 10 column
color_formatter.format(dataTable, 10); // Apply formatter to 10 column
I didn't find answer on this question, so I'll post my solution for this old question here.
Looks like Google doesn't support such behaviour out of box, but you can achieve it with custom formatter. This one works in my case:
function RowColorFormat() {
var colorFormat = new google.visualization.ColorFormat();
this.addRange = function(from, to, color, bgcolor) {
colorFormat.addRange(from, to, color, bgcolor);
};
this.addGradientRange = function(from, to, color, fromBgColor, toBgColor) {
colorFormat.addGradientRange(from, to, color, bgcolor);
};
this.format = function(dataTable, column) {
dataTable.setPropertyOverriden = dataTable.setProperty;
dataTable.setProperty = function (row, column, name, value) {
var length = this.getNumberOfColumns();
for (var i = 0; i < length; i++) {
this.setPropertyOverriden(row, i, name, value);
}
};
colorFormat.format(dataTable, column);
dataTable.setProperty = dataTable.setPropertyOverriden;
delete dataTable.setPropertyOverriden;
};
}
and use it like google.visualization.ColorFormat

How do I render a Dundas bar chart from most to least?

How does one order the bar chart series to render from most to least? Ordering the data before binding does not seem to help.
My code:
chart.Series.Add("port");
chart.Series["port"].Type = SeriesChartType.Bar;
chart.Series["port"]["PointWidth"] = "0.6";
chart.Series["port"]["BarLabelStyle"] = "Center";
chart.Series["port"].ShowLabelAsValue = true;
chart.Series["port"].Points.DataBind(myData, "Key", "Value", "Label=Value{p2}");
chart.Series["port"].BorderStyle = ChartDashStyle.Solid;
chart.Series["port"].BorderColor = Color.White;
chart.Series["port"].BorderWidth = 1;
chart.Series["port"].ShowLabelAsValue = true;
chart.Series["port"].Font = myfont;
chart.ChartAreas.Add("Default");
chart.ChartAreas["Default"].BackColor = Color.Transparent;
foreach (var axis in chart.ChartAreas["Default"].Axes)
{
axis.LabelStyle.Font = myfont;
axis.MajorGrid.Enabled = false;
}
chart.ChartAreas["Default"].AxisX.Interval = 1;
chart.ChartAreas["Default"].AxisY.LabelStyle.Format = "p0";
You need to call Sort() on the series, see http://msdn.microsoft.com/en-us/library/dd455394.aspx. So to sort the points from most to least you'd do
chart.Series["port"].Sort(PointSortOrder.Descending);
There are two other sort methods incase you need to sort by something other than the point value.