How do I add an image to a label in AmChart5? - amcharts

In data I have a am5.Picture object
icon = am5.Picture.new(root, {
height: 28,
src: src
});
The image fits on the text, is not inserted next to it
this doesn't work either
series.labels.template.set("text", "{icon} {name}") // return only name

Used Container
series.labels.values.forEach((label, index) => {
if (label.dataItem.dataContext.icon) {
let container = am5.Container.new(root, {
layout: root.horizontalLayout
})
container.children.push(label.dataItem.dataContext.icon)
container.children.push(
am5.Label.new(root, {
text: label.dataItem.dataContext.name,
fontSize: 10,
textAlign: "left",
centerY: am5.percent(50),
paddingLeft: 5,
})
)
label.children.clear()
label.children.push(container)
} else {
label.setAll({
fontSize: 10,
fontWeight: "300",
textAlign: "left",
maxWidth: 260,
oversizedBehavior: "wrap",
text: "{name}"
})
}
})

Related

amcharts5 - chart above another chart using same xaxis?

I am attempting to show a column chart (or a line chart would work too) above a gannt chart using the same xaxis (timestamp) and having trouble with spacing as well as getting any data to show in the column chart. I don't even know if this is possible to do, but the help docs made it sound like it was so I am more than likely missing quite a few things in the configuration or doing things wrong.
I've created a codepen with what I have so far. The original gannt chart shows fine, then I am able to get the column chart's yaxis to show (although it overlaps the gannt instead of being above it and does not show any data).
Any assistance/explanation with this would be appreciated.
// Set data
var data = [{
"State": "Idle",
"Start": 1424321864000,
"End": 1424321875000,
"Duration": 11
}, {
"State": "Idle",
"Start": 1424322649000,
"End": 1424322669000,
"Duration": 20
}, {
"State": "Idle",
"Start": 1424322970000,
"End": 1424322981000,
"Duration": 11
}, {
"State": "Idle",
"Start": 1424323093000,
"End": 1424323139000,
"Duration": 46
}, {
"State": "Active",
"Start": 1424323250000,
"End": 1424323268000,
"Duration": 18
}, {
"State": "Idle",
"Start": 1424323680000,
"End": 1424323703000,
"Duration": 23
}];
var mousekeys = [{
"Timestamp": 1424318400000,
"Clicks": "20",
"Keypresses": "30"
}];
/**
* ---------------------------------------
* This demo was created using amCharts 5.
*
* For more information visit:
* https://www.amcharts.com/
*
* Documentation is available at:
* https://www.amcharts.com/docs/v5/
* ---------------------------------------
*/
// Create root element
// https://www.amcharts.com/docs/v5/getting-started/#Root_element
var root = am5.Root.new("chartdiv");
//font size theme
var myTheme = am5.Theme.new(root);
myTheme.rule("Label").setAll({
fontSize: 12
});
root.setThemes([
am5themes_Animated.new(root),
myTheme
]);
root.locale = am5locales_en_US;
//chartReg['chart'].utc = true; //force chart to show in UTC instead of device timezone
root.timezone = am5.Timezone.new('UTC'); //user timezone
//duration format
root.durationFormatter.setAll({
baseUnit: "second",
durationFormat: "hh'h' mm'm' ss's'"
});
//create chart
var chart = root.container.children.push(am5xy.XYChart.new(root, {
panX: false,
panY: false,
wheelX: false,
wheelY: false,
layout: root.verticalLayout,
marginTop: 0,
marginRight: 0,
marginBottom: 0,
marginLeft: 0,
paddingTop: 0,
paddingRight: 20,
paddingBottom: 20,
paddingLeft: 10,
}));
//zoom button
//chart.zoomOutButton.setAll({
// forceHidden: true, //disables zoom button
//});
chart.zoomOutButton.get("background").setAll({
fill: am5.color("#BDBDBD"),
});
chart.zoomOutButton.get("background").states.create("hover", {}).setAll({
fill: am5.color("#8a8a8a"),
});
chart.zoomOutButton.get("background").states.create("down", {}).setAll({
fill: am5.color("#707070"),
});
chart.zoomOutButton.get("background").states.create("active", {}).setAll({
fill: am5.color("#707070"),
});
//create axes
var yAxis = chart.yAxes.push(am5xy.CategoryAxis.new(root, {
text: "State",
fontWeight: "500",
height: am5.percent(70),
categoryField: "State",
renderer: am5xy.AxisRendererY.new(root, {}),
tooltip: am5.Tooltip.new(root, {}),
}));
var yAxis2 = chart.yAxes.push(am5xy.ValueAxis.new(root, {
text: "Clicks",
fontWeight: "500",
height: am5.percent(30),
min: 0, //min 'hint', but not forced
//strictMinMax: true, //forces the min/max
//extraMax: 0.1, //extra 10% to the value range which acts as 'padding' to the yaxis
renderer: am5xy.AxisRendererY.new(root, {})
}));
//the order is top to bottom ends up bottom to top on the chart
yAxis.data.setAll([
{ State: "Idle" },
{ State: "Active" }
]);
//y-axis dash lines
var yRenderer = yAxis.get("renderer");
yRenderer.grid.template.setAll({
strokeDasharray: [6]
});
var xAxis = chart.xAxes.push(am5xy.DateAxis.new(root, {
baseInterval: { timeUnit: "second", count: 1 },
renderer: am5xy.AxisRendererX.new(root, {}),
tooltip: am5.Tooltip.new(root, {}),
tooltipDateFormat: "EEE, MMM dd # h:mm:ss a"
}));
//x-axis dash lines
var xRenderer = xAxis.get("renderer");
xRenderer.grid.template.setAll({
strokeDasharray: [6],
});
//series
var series = chart.series.push(am5xy.ColumnSeries.new(root, {
xAxis: xAxis,
yAxis: yAxis,
openValueXField: "Start",
valueXField: "End",
categoryYField: "State",
sequencedInterpolation: true,
tooltip: am5.Tooltip.new(root, {
//labelText: "[bold {Color} fontSize: 16px]{State}[/]\n[bold]Start :[/] {openValueX.formatDate(\"EEE',' MM'/'dd'/'yyyy '#' h':'mm':'ss a\")}\n[bold]End :[/] {valueX.formatDate(\"EEE',' MM'/'dd'/'yyyy '#' h':'mm':'ss a\")}\n[bold]Duration :[/] {Duration.formatDuration(\"hh'h' mm'm' ss's'\")}",
labelText: "[bold]Start :[/] {openValueX.formatDate(\"EEE',' MM'/'dd'/'yyyy '#' h':'mm':'ss a\")}\n[bold]End :[/] {valueX.formatDate(\"EEE',' MM'/'dd'/'yyyy '#' h':'mm':'ss a\")}\n[bold]Duration :[/] {Duration.formatDuration(\"hh'h' mm'm' ss's'\")}",
getFillFromSprite: false
})
}));
series.get("tooltip").get("background").setAll({
fill: am5.color("#ffffff"),
fillOpacity: 1,
strokeWidth: 2,
stroke: am5.color("#bbbbbb"),
});
//series columns
series.columns.template.setAll({
fillOpacity: 1,
stroke: 0,
strokeWidth: 0, //doesn't seem to work use 'stroke:0'
tooltipText: "{State}:\n[bold]{openValueX}[/] - [bold]{valueX}[/]"
});
series.columns.template.adapters.add("fill", function (text, target, key) {
//console.log(target);
//have to check for empty
//if(target.dataItem) {
if(target.dataItem.dataContext.State == "Active") {
return am5.color("#7bc07b"); //active
} else {
return am5.color("#55bfe6"); //idle
}
//} else {
// return null;
//}
});
//series
var series2 = chart.series.push(am5xy.ColumnSeries.new(root, {
name: "Clicks",
fill: am5.color("#679fd0"),
xAxis: xAxis,
yAxis: yAxis2,
valueYField: "Clicks",
valueXField: "Timestamp",
tooltip: am5.Tooltip.new(root, {
labelText: "{valueY}",
getFillFromSprite: false
})
}));
series2.get("tooltip").get("background").setAll({
fill: am5.color("#ffffff"),
fillOpacity: 1,
strokeWidth: 2,
stroke: am5.color("#bbbbbb"),
});
//series columns
series2.columns.template.setAll({
fillOpacity: 1,
stroke: 0,
strokeWidth: 0, //doesn't seem to work use 'stroke:0'
});
series2.get("tooltip").label.adapters.add("text", function (text, target, key) {
//console.log(target);
//have to check for empty
if(target.dataItem) {
return "Total : [bold]{Clicks}[/]\nTimestamp : [bold]{Timestamp}[/]";
} else {
return null;
}
});
//title
var title = chart.children.unshift(am5.Label.new(root, {
fontSize: 12,
textAlign: "left",
x: am5.percent(0),
y: am5.percent(0),
marginTop: 0,
marginRight: 0,
marginBottom: 30,
marginLeft: 0,
paddingTop: 0,
paddingRight: 0,
paddingBottom: 0,
paddingLeft: 0,
text: "some label"
}));
//cursor
var cursor = chart.set("cursor", am5xy.XYCursor.new(root, {
snapToSeries: [ series ],
snapToSeriesBy: "x",
behavior: "zoomX"
}));
cursor.lineX.set("visible", false);
cursor.lineY.set("visible", false);
//formatting
series.data.processor = am5.DataProcessor.new(root, {
dateFields: ["Start", "End"],
dateFormat: "xxxxxxxxxxxxx"
});
//formatting
series2.data.processor = am5.DataProcessor.new(root, {
numericFields: ["Clicks"],
dateFields: ["Timestamp"],
dateFormat: "xxxxxxxxxxxxx"
});
//scrollbar
chart.set("scrollbarX", am5.Scrollbar.new(root, {
orientation: "horizontal",
marginTop: 0,
marginRight: 0,
marginBottom: 30,
marginLeft: 0,
paddingTop: 0,
paddingRight: 0,
paddingBottom: 0,
paddingLeft: 0,
}));
//exporting
exporting = am5plugins_exporting.Exporting.new(root, {
dataSource: data,
dataFields: {
State: 'State', Start: 'Start', End: 'End', Duration: 'Duration'
},
dateFields: ["Start", "End"],
dateFormat: "MM/dd/yyyy hh:mm:ss a",
durationFields: ["Duration"],
durationFormat: "hh'h' mm'm' ss's'",
filePrefix: 'User Activity'
});
//add data
series.data.setAll(data);
series2.data.setAll(mousekeys);
//make stuff animate on load
series.appear(1000);
series2.appear(1000);
chart.appear(1000, 100);
yAxis and yAxis2 are not stacked. You have to be more explicit and add this line of code:
chart.leftAxesContainer.set("layout", root.verticalLayout);
If you want to place your column chart above, you need to push yAxis2 before yAxis or use unshift():
var yAxis2 = chart.yAxes.unshift(am5xy.ValueAxis.new(root, {
// ...
}));
I put your code below with these two little modifications:
// Set data
var data = [{
"State": "Idle",
"Start": 1424321864000,
"End": 1424321875000,
"Duration": 11
}, {
"State": "Idle",
"Start": 1424322649000,
"End": 1424322669000,
"Duration": 20
}, {
"State": "Idle",
"Start": 1424322970000,
"End": 1424322981000,
"Duration": 11
}, {
"State": "Idle",
"Start": 1424323093000,
"End": 1424323139000,
"Duration": 46
}, {
"State": "Active",
"Start": 1424323250000,
"End": 1424323268000,
"Duration": 18
}, {
"State": "Idle",
"Start": 1424323680000,
"End": 1424323703000,
"Duration": 23
}];
var mousekeys = [{
"Timestamp": 1424318400000,
"Clicks": "20",
"Keypresses": "30"
}];
/**
* ---------------------------------------
* This demo was created using amCharts 5.
*
* For more information visit:
* https://www.amcharts.com/
*
* Documentation is available at:
* https://www.amcharts.com/docs/v5/
* ---------------------------------------
*/
// Create root element
// https://www.amcharts.com/docs/v5/getting-started/#Root_element
var root = am5.Root.new("chartdiv");
//font size theme
var myTheme = am5.Theme.new(root);
myTheme.rule("Label").setAll({
fontSize: 12
});
root.setThemes([
am5themes_Animated.new(root),
myTheme
]);
root.locale = am5locales_en_US;
//chartReg['chart'].utc = true; //force chart to show in UTC instead of device timezone
root.timezone = am5.Timezone.new('UTC'); //user timezone
//duration format
root.durationFormatter.setAll({
baseUnit: "second",
durationFormat: "hh'h' mm'm' ss's'"
});
//create chart
var chart = root.container.children.push(am5xy.XYChart.new(root, {
panX: false,
panY: false,
wheelX: false,
wheelY: false,
layout: root.verticalLayout,
marginTop: 0,
marginRight: 0,
marginBottom: 0,
marginLeft: 0,
paddingTop: 0,
paddingRight: 20,
paddingBottom: 20,
paddingLeft: 10,
}));
chart.leftAxesContainer.set("layout", root.verticalLayout); // <--- HERE
//zoom button
//chart.zoomOutButton.setAll({
// forceHidden: true, //disables zoom button
//});
chart.zoomOutButton.get("background").setAll({
fill: am5.color("#BDBDBD"),
});
chart.zoomOutButton.get("background").states.create("hover", {}).setAll({
fill: am5.color("#8a8a8a"),
});
chart.zoomOutButton.get("background").states.create("down", {}).setAll({
fill: am5.color("#707070"),
});
chart.zoomOutButton.get("background").states.create("active", {}).setAll({
fill: am5.color("#707070"),
});
//create axes
var yAxis = chart.yAxes.push(am5xy.CategoryAxis.new(root, {
text: "State",
fontWeight: "500",
height: am5.percent(70),
categoryField: "State",
renderer: am5xy.AxisRendererY.new(root, {}),
tooltip: am5.Tooltip.new(root, {}),
}));
var yAxis2 = chart.yAxes.unshift(am5xy.ValueAxis.new(root, { // <--- HERE
text: "Clicks",
fontWeight: "500",
height: am5.percent(30),
min: 0, //min 'hint', but not forced
//strictMinMax: true, //forces the min/max
//extraMax: 0.1, //extra 10% to the value range which acts as 'padding' to the yaxis
renderer: am5xy.AxisRendererY.new(root, {})
}));
//the order is top to bottom ends up bottom to top on the chart
yAxis.data.setAll([
{ State: "Idle" },
{ State: "Active" }
]);
//y-axis dash lines
var yRenderer = yAxis.get("renderer");
yRenderer.grid.template.setAll({
strokeDasharray: [6]
});
var xAxis = chart.xAxes.push(am5xy.DateAxis.new(root, {
baseInterval: { timeUnit: "second", count: 1 },
renderer: am5xy.AxisRendererX.new(root, {}),
tooltip: am5.Tooltip.new(root, {}),
tooltipDateFormat: "EEE, MMM dd # h:mm:ss a"
}));
//x-axis dash lines
var xRenderer = xAxis.get("renderer");
xRenderer.grid.template.setAll({
strokeDasharray: [6],
});
//series
var series = chart.series.push(am5xy.ColumnSeries.new(root, {
xAxis: xAxis,
yAxis: yAxis,
openValueXField: "Start",
valueXField: "End",
categoryYField: "State",
sequencedInterpolation: true,
tooltip: am5.Tooltip.new(root, {
//labelText: "[bold {Color} fontSize: 16px]{State}[/]\n[bold]Start :[/] {openValueX.formatDate(\"EEE',' MM'/'dd'/'yyyy '#' h':'mm':'ss a\")}\n[bold]End :[/] {valueX.formatDate(\"EEE',' MM'/'dd'/'yyyy '#' h':'mm':'ss a\")}\n[bold]Duration :[/] {Duration.formatDuration(\"hh'h' mm'm' ss's'\")}",
labelText: "[bold]Start :[/] {openValueX.formatDate(\"EEE',' MM'/'dd'/'yyyy '#' h':'mm':'ss a\")}\n[bold]End :[/] {valueX.formatDate(\"EEE',' MM'/'dd'/'yyyy '#' h':'mm':'ss a\")}\n[bold]Duration :[/] {Duration.formatDuration(\"hh'h' mm'm' ss's'\")}",
getFillFromSprite: false
})
}));
series.get("tooltip").get("background").setAll({
fill: am5.color("#ffffff"),
fillOpacity: 1,
strokeWidth: 2,
stroke: am5.color("#bbbbbb"),
});
//series columns
series.columns.template.setAll({
fillOpacity: 1,
stroke: 0,
strokeWidth: 0, //doesn't seem to work use 'stroke:0'
tooltipText: "{State}:\n[bold]{openValueX}[/] - [bold]{valueX}[/]"
});
series.columns.template.adapters.add("fill", function (text, target, key) {
//console.log(target);
//have to check for empty
//if(target.dataItem) {
if(target.dataItem.dataContext.State == "Active") {
return am5.color("#7bc07b"); //active
} else {
return am5.color("#55bfe6"); //idle
}
//} else {
// return null;
//}
});
//series
var series2 = chart.series.push(am5xy.ColumnSeries.new(root, {
name: "Clicks",
fill: am5.color("#679fd0"),
xAxis: xAxis,
yAxis: yAxis2,
valueYField: "Clicks",
valueXField: "Timestamp",
tooltip: am5.Tooltip.new(root, {
labelText: "{valueY}",
getFillFromSprite: false
})
}));
series2.get("tooltip").get("background").setAll({
fill: am5.color("#ffffff"),
fillOpacity: 1,
strokeWidth: 2,
stroke: am5.color("#bbbbbb"),
});
//series columns
series2.columns.template.setAll({
fillOpacity: 1,
stroke: 0,
strokeWidth: 0, //doesn't seem to work use 'stroke:0'
});
series2.get("tooltip").label.adapters.add("text", function (text, target, key) {
//console.log(target);
//have to check for empty
if(target.dataItem) {
return "Total : [bold]{Clicks}[/]\nTimestamp : [bold]{Timestamp}[/]";
} else {
return null;
}
});
//title
var title = chart.children.unshift(am5.Label.new(root, {
fontSize: 12,
textAlign: "left",
x: am5.percent(0),
y: am5.percent(0),
marginTop: 0,
marginRight: 0,
marginBottom: 30,
marginLeft: 0,
paddingTop: 0,
paddingRight: 0,
paddingBottom: 0,
paddingLeft: 0,
text: "some label"
}));
//cursor
var cursor = chart.set("cursor", am5xy.XYCursor.new(root, {
snapToSeries: [ series ],
snapToSeriesBy: "x",
behavior: "zoomX"
}));
cursor.lineX.set("visible", false);
cursor.lineY.set("visible", false);
//formatting
series.data.processor = am5.DataProcessor.new(root, {
dateFields: ["Start", "End"],
dateFormat: "xxxxxxxxxxxxx"
});
//formatting
series2.data.processor = am5.DataProcessor.new(root, {
numericFields: ["Clicks"],
dateFields: ["Timestamp"],
dateFormat: "xxxxxxxxxxxxx"
});
//scrollbar
chart.set("scrollbarX", am5.Scrollbar.new(root, {
orientation: "horizontal",
marginTop: 0,
marginRight: 0,
marginBottom: 30,
marginLeft: 0,
paddingTop: 0,
paddingRight: 0,
paddingBottom: 0,
paddingLeft: 0,
}));
//exporting
exporting = am5plugins_exporting.Exporting.new(root, {
dataSource: data,
dataFields: {
State: 'State', Start: 'Start', End: 'End', Duration: 'Duration'
},
dateFields: ["Start", "End"],
dateFormat: "MM/dd/yyyy hh:mm:ss a",
durationFields: ["Duration"],
durationFormat: "hh'h' mm'm' ss's'",
filePrefix: 'User Activity'
});
//add data
series.data.setAll(data);
series2.data.setAll(mousekeys);
//make stuff animate on load
series.appear(1000);
series2.appear(1000);
chart.appear(1000, 100);
body {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
}
#chartdiv {
width: 100%;
height: 500px;
}
<script src="https://cdn.amcharts.com/lib/5/index.js"></script>
<script src="https://cdn.amcharts.com/lib/5/xy.js"></script>
<script src="https://cdn.amcharts.com/lib/5/themes/Animated.js"></script>
<script src="https://cdn.amcharts.com/lib/5/locales/en_US.js"></script>
<script src="https://cdn.amcharts.com/lib/5/plugins/exporting.js"></script>
<div id="chartdiv"></div>
You can see a column if you use the horizontal scrollbar and go completely to the left. The reason is there:
var xAxis = chart.xAxes.push(am5xy.DateAxis.new(root, {
baseInterval: { timeUnit: "second", count: 1 },
// ...
}));
Your interval is tiny (one second), so your column width is tiny. You have to tweak timeUnit or count in baseInterval if you want a wider column.

How to customize or update the style of the Datagrid component?

I tried to change the header style of the Datagrid component based on material-ui style guide. Datagrid body content is updated based on custom style but the header is not reflected the custom style changes.
the code snippet is below:
export const TableStyleProp = {
style: {
color: "#ff0000"
},
selectable: true,
headerStyle: {
color: "#ff0000"
},
bodyStyle: {}
};
const muiTheme = getMuiTheme({
table: {
backgroundColor: "#FF0000 !important"
},
thead: {
backgroundColor: "#b7cbfb"
},
tableHeader: {
borderColor: "#FF0000",
backgroundColor: "#FF0000"
},
tableHeaderColumn: {
textColor: "#FF0000",
height: 56,
spacing: 24
},
tableRow: {
hoverColor: "#FF0000",
stripeColor: "#FF0000",
selectedColor: "#FF0000",
textColor: "#FF00FF",
borderColor: "#FF0000",
height: 48
},
tableRowColumn: {
height: 48,
spacing: 24
}
});
<MuiThemeProvider muiTheme={muiTheme}>
This is described in the documentation: https://marmelab.com/admin-on-rest/List.html#custom-grid-style

fabric.js works with subclass

I try to create new class working with fabric.js framework. This class should consist of 3 simple objects: 2 text and 1 rectangle. One of text object should be updated by time, for example each second. The problem is new value does not appear on canvas as expected, but it updates every time when you select object. Here is my code. Could anyone explain me, what should I do to make it updates by time?
var canvas = new fabric.Canvas('c');
fabric.Tag = fabric.util.createClass(fabric.Group, {
type: 'PItag',
initialize: function() {
options = {};
options.top = 0;
options.left = 0;
var defaults = {
width: 100,
height: 40,
originX: 'center',
originY: 'center'
};
var defaults1 = {
width: 100,
height: 20,
originX: 'center',
originY: 'top',
top: -20,
backgroundColor: 'red'
};
var defaults2 = {
width: 100,
height: 20,
originX: 'center',
originY: 'top',
top: 0
};
var items = [];
items[0] = new fabric.Rect($.extend({}, defaults, {
fill: '#77AAFF',
}));
items[1] = new fabric.Textbox('PI tag name', $.extend({}, defaults1, {
textAlign: 'center',
fontSize: 14
}));
items[2] = new fabric.IText('####', $.extend({}, defaults2, {
textAlign: 'center',
fontSize: 16
}));
this.callSuper('initialize', items, options);
},
getTagName: function () {
return this._objects[1].text;
},
setTagName: function (value) {
this._objects[1].text = value;
},
getValue: function () {
return this._objects[2].text;
},
setValue: function (value) {
this._objects[2].text = value;
this.canvas.renderAll();
},
_render: function(ctx) {
this.callSuper('_render', ctx);
}
});
var pi = new fabric.Tag();
pi.setTagName("Unix time");
canvas.add(pi);
setInterval(function() {
pi.setValue(Math.floor((new Date()).getTime() / 1000).toString());
canvas.renderAll();
}, 1000);
var canvas = new fabric.Canvas('c');
fabric.Tag = fabric.util.createClass(fabric.Group, {
type: 'PItag',
initialize: function() {
options = {};
options.left = 100;
options.top=100;
var defaults = {
width: 100,
height: 40,
originX: 'center',
originY: 'center'
};
var defaults1 = {
width: 100,
height: 20,
originX: 'center',
originY: 'top',
top: -20,
backgroundColor: 'red'
};
var defaults2 = {
width: 100,
height: 20,
originX: 'center',
originY: 'top',
top: 0
};
var items = [];
items[0] = new fabric.Rect($.extend({}, defaults, {
fill: '#77AAFF',
}));
items[1] = new fabric.Textbox('PI tag name', $.extend({}, defaults1, {
textAlign: 'center',
fontSize: 14
}));
items[2] = new fabric.IText('####', $.extend({}, defaults2, {
textAlign: 'center',
fontSize: 16
}));
this.callSuper('initialize', items, options);
},
getTagName: function () {
return this._objects[1].text;
},
setTagName: function (value) {
this._objects[1].text = value;
},
getValue: function () {
return this._objects[2].text;
},
setValue: function (value) {
this._objects[2].set({ text: value });
this.canvas.renderAll();
},
_render: function(ctx,noTransform) {
console.log('xs')
this.callSuper('_render', ctx);
//ctx._objects[1].text = this._objects[1].text;
}
});
var pi = new fabric.Tag();
// canvas.pi.async = true;
pi.setTagName("Unix time");
canvas.add(pi);
setInterval(function() {
pi.setValue(Math.floor((new Date()).getTime() / 1000).toString());
canvas.renderAll();
}, 1000);
<script src="http://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.7.9/fabric.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<canvas id="c" height="418" width="400" style="border: 1px solid rgb(170, 170, 170);"></canvas>
just change this function
setValue: function (value) {
this._objects[2].set({ text: value });
this.canvas.renderAll();
},

Animation - How to turn animated values into real values via interpolate

I'm trying to simultaneously restrict the values of my animation (using clamp as well as interpolate) but also get the values out of the interpolation so I can use them. Specifically because I want to update a piece of state with them and create an observable from that. I just can't figure out how to extract the 'real' value out of the AnimatedValue that is produced by the interpolation (in this case state.panValue). I've tried
this.state.panValue.value
and
this.state.panValue._value
and they come back as undefined. If anyone could help me out would be amazing!
EDIT: I'd also be really happy to just have the
this.state.pan.x
variable updated within the limits so I can skip the whole updating the state variable 'panValue' thing. A nice guy on Facebook suggested that I could implement this limit somehow inside the onPanResponderMove by switching the variable to a function or something but I've tried several things and all I get are errors, I guess because I don't really know how to 'safely' amend these animated values.
onPanResponderMove: Animated.event([
null,
{ dx: this.state.pan.x },
]),
Original Code:
import React, { Component } from 'react';
import {
View,
Animated,
PanResponder,
Text,
} from 'react-native';
import styles from './styles';
class ClockInSwitch extends Component {
constructor(props) {
super(props);
this.state = {
pan: new Animated.ValueXY(),
panValue: 0,
};
}
componentWillMount() {
this._animatedValueX = 0;
this._animatedValueY = 0;
this.state.pan.x.addListener((value) => {
this._animatedValueX = value.value;
this.setState({
panValue: this.state.pan.x.interpolate({
inputRange: [-30, 0, 120,],
outputRange: [-10, 0, 120,],
extrapolate: 'clamp',
}),
});
});
this._panResponder = PanResponder.create({
// Ask to be the responder:
onStartShouldSetPanResponder: (evt, gestureState) => true,
onStartShouldSetPanResponderCapture: (evt, gestureState) => true,
onMoveShouldSetPanResponder: (evt, gestureState) => true,
onMoveShouldSetPanResponderCapture: (evt, gestureState) => true,
onPanResponderGrant: (evt, gestureState) => {
this.state.pan.setOffset({
x: this._animatedValueX,
});
this.state.pan.setValue({ x: 0, y: 0 });
},
onPanResponderMove: Animated.event([
null,
{ dx: this.state.pan.x },
]),
onPanResponderTerminationRequest: (evt, gestureState) => true,
onPanResponderRelease: (evt, gestureState) => {
this.state.pan.flattenOffset();
Animated.timing(this.state.pan, {
toValue: 0,
duration: 500,
}).start();
},
onPanResponderTerminate: (evt, gestureState) => {
},
onShouldBlockNativeResponder: (evt, gestureState) => {
return true;
},
});
}
componentWillUnMount() {
this.state.pan.x.removeAllListeners();
}
render() {
const animatedStyle = {
transform: [{
translateX: this.state.panValue,
},
],
};
return (
<View>
<Text>{this.state.pan.x._value}</Text>
<View style={styles.buttonStyle}>
<Animated.View
style={[styles.sliderButtonStyle, animatedStyle]}
{...this._panResponder.panHandlers}
/>
</View>
</View>
);
}
}
export default ClockInSwitch;
I think this is what you're looking for. I'm using exponent so your declaration for vector icons would probably need to be changed. Cheers!
/**
* #providesModule ClockInSwitch
* #flow
*/
import React, {Component} from 'react';
import {View, Animated, StyleSheet, PanResponder, Text} from 'react-native';
import {FontAwesome} from '#exponent/vector-icons';
export class ClockInSwitch extends Component {
constructor(props) {
super(props);
this.state = {
pan: new Animated.ValueXY(),
panValue: 0
};
}
componentWillMount() {
this._panResponder = PanResponder.create({
onMoveShouldSetResponderCapture: () => true,
onMoveShouldSetPanResponderCapture: () => true,
onPanResponderGrant: (e, gestureState) => {
this
.state
.pan
.setValue({x: 0, y: 0});
},
//here's where you can check, constrain and store values
onPanResponderMove: (evt, gestureState) => {
// 300 is the width of the red container (will leave it to you to calculate this
// dynamically) 100 is the width of the button (90) plus the 5px margin on
// either side of it (10px total)
var newXVal = (gestureState.dx < 300 - 100)
? gestureState.dx
: 300 - 100;
this
.state
.pan
.x
.setValue(newXVal);
//set this state for display
this.setState({panValue: newXVal});
},
onPanResponderRelease: (e, {vx, vy}) => {
this
.state
.pan
.flattenOffset();
Animated
.spring(this.state.pan, {
toValue: 0,
duration: 400,
overshootClamping: true
})
.start();
this.setState({panValue: 0});
}
});
}
componentWillUnMount() {
this
.state
.pan
.x
.removeAllListeners();
}
render() {
//decouple the value from the state object
let {pan} = this.state;
let [translateX,
translateY] = [pan.x, pan.y];
let translateStyle = {
transform: [{
translateX
}, {
translateY
}]
};
return (
<View>
<Text style={styles.leftText}>Power Button Demo</Text>
<View style={styles.buttonStyle}>
<Animated.View
style={[styles.sliderButtonStyle, translateStyle]}
{...this._panResponder.panHandlers}>
<FontAwesome
name="power-off"
color="#EA2E49"
style={{
alignSelf: "center",
marginHorizontal: 10
}}
size={36}/>
</Animated.View>
</View>
<Text style={styles.rightText}>{this.state.panValue}: x value</Text>
</View>
);
}
}
export default ClockInSwitch;
const styles = StyleSheet.create({
sliderButtonStyle: {
borderColor: '#FCFFF5',
borderStyle: 'solid',
borderWidth: .5,
backgroundColor: '#FCFFF5',
borderRadius: 45,
height: 90,
width: 90,
justifyContent: 'center',
textAlign: 'center',
marginHorizontal: 5,
shadowColor: '#333745',
shadowOffset: {
width: 2,
height: 2
},
shadowOpacity: .6,
shadowRadius: 5
},
buttonStyle: {
borderColor: '#FCFFF500',
backgroundColor: '#DAEDE255',
borderStyle: 'solid',
borderWidth: 1,
height: 100,
width: 300,
justifyContent: 'center',
borderRadius: 50,
margin: 5,
flexDirection: 'column'
},
rightText: {
justifyContent: 'center',
textAlign: 'right',
fontWeight: '100',
marginHorizontal:15,
fontSize: 20,
color: '#FCFFF5',
marginVertical:25,
flexDirection: 'column'
},
leftText: {
justifyContent: 'center',
textAlign: 'left',
fontWeight: '100',
marginHorizontal:15,
fontSize: 24,
color: '#FCFFF5',
marginVertical:25,
flexDirection: 'column'
}
});

Legend does not come in bold in firefox and chrome for highcharts with pie

Below is my code for a pie chart:
legend: { margin: 1, padding: 4, layout: 'horizontal', align: 'center', verticalAlign: 'bottom', itemWidth: 189, borderWidth: 0, enabled: true, useHTML: false, labelFormatter: function () { return (this.y == 0 || this.y == null || this.y == '') ? "" : (this.name); }, itemMarginBottom: 8, itemStyle: { color: '#333333', fontWeight: 'bold', fontFamily: 'Arial', fontSize: '10px', lineHeight: '15px' }, symbolWidth: 11, x: -7, symbolPadding: 8 }
However the legend text is not bold till i change the font to 10.5 which i think is too big.
Below is the html generated in FF:THis happens in both Chrome and Firefox. IE is working fine.
<text x="19" y="13" style="font-family:Arial;font-size:10.4px;cursor:pointer;color:#333333;font-weight:bold;line-height:15px;fill:#333333;" text-anchor="start" zIndex="2">
Is there something I can do about this?
For me it is bolded, compare: http://jsfiddle.net/3bQne/233/
var chart = new Highcharts.Chart({
chart: {
renderTo: 'container2'
},
legend: {
margin: 1,
padding: 4,
layout: 'horizontal',
align: 'center',
verticalAlign: 'bottom',
itemWidth: 189,
borderWidth: 0,
enabled: true,
useHTML: false,
labelFormatter: function () {
return (this.y == 0 || this.y == null || this.y == '') ? "" : (this.name);
},
itemMarginBottom: 8,
itemStyle: {
color: '#333333',
//fontWeight: 'bold',
fontFamily: 'Arial',
fontSize: '10px',
lineHeight: '15px'
},
symbolWidth: 11,
x: -7,
symbolPadding: 8
},
series: [{
showInLegend: true,
type: 'pie',
data: [3.45, 4.21, 5.11]
}]
});
And image:

Resources