Setting hover style in react-native-gifted-chat - react-native-gifted-chat

How do I set the styles for hovered links in react-native-gifted-chat?
For example, I've currently got
const renderBubble = (props) => {
return (
<Bubble
{ ...props }
linkStyle={ {
left: { color: 'gray', textDecorationLine: 'none' }
} }
textStyle={ {
left: { color: 'white' },
right: { color: 'white' },
} }
wrapperStyle={ {
left: { backgroundColor: '#8fafff', borderRadius: 5 },
right: { backgroundColor: '#2dc4b3', borderRadius: 5 },
} }
/>
)
}
but don't see in the source code or docs for the package where I can control the hover color for links.

Related

Attaching Index To List Item (string) [Flutter]

Instead of making isSelected bool variable, i'll like to make it as index of selected. then check for the index of selected in reportReasons list.
This is to know which reason is being selected. Also, how do I then make the selected container change color if isSelected is not a bool?
Thank you.
final List<String> reportReasons = [
'blah',
'blah blah',
'blah blah blah'
];
List<String> chosenReasonsToReport = [];
bool isSelected = false;
Container(
child: Wrap(
children: reportReasons
.map((reportReason) => GestureDetector(
onTap: () {
setState(() { if (isSelected = false) {
isSelected = true;
} else {
isSelected = false;
}});
if (reportReason.isSelected && chosenReasonsToReport.length < 3) {
chosenReasonsToReport.add('${reportReason}');
print(chosenReasonsToReport);
} else {
chosenReasonsToReport.remove('${reportReason}');
print(chosenReasonsToReport);
}
},
child: Container(
margin: EdgeInsets.only(
right:
MediaQuery.of(context).size.width * 0.021,
bottom: MediaQuery.of(context).size.height *
0.009,
),
decoration: BoxDecoration(
color: isSelected
? Color(0xff4aa3f8)
: Color(0xff3a327f),
borderRadius: BorderRadius.circular(12),
border: Border.all(
color:
Colors.grey[50].withOpacity(0.60))),
padding: EdgeInsets.symmetric(
horizontal:
MediaQuery.of(context).size.width *
0.027,
vertical:
MediaQuery.of(context).size.height *
0.0045),
child: Text(
reportReason,
style: TextStyle(
fontSize: 13.5,
color: isSelected
? Color(0xff231b6a)
: null),
),
),
))
.toList()),
You can use a couple of approaches:
A set of indexes:
class _MyScreenState extends State<MyScreen> {
static const List<String> _reportReasons = [
'blah',
'blah blah',
'blah blah blah'
];
Set<int> _chosenIndexes = {};
#override
Widget build(BuildContext context) {
return ListView(
children: List.generate(_reportReasons.length, (i) {
return Container(
// Change property based on report selection
color: _chosenIndexes.contains(i)
? Colors.green
: Colors.red,
child: CheckboxListTile(
// Accessing report name
title: Text(_reportReasons[i]),
// Accessing if report is selected
value: _chosenIndexes.contains(i),
// Selecting and unselecting report
onChanged: (v) {
setState(() {
if (v) {
_chosenIndexes.add(i);
} else {
_chosenIndexes.remove(i);
}
});
}
),
);
}),
);
}
}
A map of String and booleans:
class _MyScreenState extends State<MyScreen> {
final Map<String, bool> _reports = {
'blah': false,
'blah blah': false,
'blah blah blah': false,
};
#override
Widget build(BuildContext context) {
return ListView(
children: _reports.keys.map((report) {
return Container(
// Change property based on report selection
color: _reports[report]
? Colors.green
: Colors.red,
child: CheckboxListTile(
// Accessing report name
title: Text(report),
// Accessing if report is selected
value: _reports[report],
// Selecting and unselecting report
onChanged: (v) {
setState(() => _reports[report] = v);
}
),
);
}).toList(),
);
}
}

Change Colors of Selected Containers and Unselect? [Flutter]

They are containers filled with reasons to report a user.
How to change the code so that each individual container will change color upon tab on/off?
And also limit the selected reasons to 3 while printing the reasons to the chosenReportReasons list?
Attached is the truncated code:
final List<String> reportReasons = [
'blah',
'blah blah',
'blah blah blah'
];
List<String> chosenReasonsToReport = [];
bool isSelected = false;
Container(
child: Wrap(
children: reportReasons
.map((reportReason) => GestureDetector(
onTap: () {
if (isSelected = false) {
isSelected = true;
} else {
isSelected = false;
}
setState(() {});
if (reportReason.isSelected && chosenReasonsToReport.length < 3) {
chosenReasonsToReport.add('${reportReason}');
print(chosenReasonsToReport);
} else {
chosenReasonsToReport.remove('${reportReason}');
print(chosenReasonsToReport);
}
},
child: Container(
margin: EdgeInsets.only(
right:
MediaQuery.of(context).size.width * 0.021,
bottom: MediaQuery.of(context).size.height *
0.009,
),
decoration: BoxDecoration(
color: isSelected
? Color(0xff4aa3f8)
: Color(0xff3a327f),
borderRadius: BorderRadius.circular(12),
border: Border.all(
color:
Colors.grey[50].withOpacity(0.60))),
padding: EdgeInsets.symmetric(
horizontal:
MediaQuery.of(context).size.width *
0.027,
vertical:
MediaQuery.of(context).size.height *
0.0045),
child: Text(
reportReason,
style: TextStyle(
fontSize: 13.5,
color: isSelected
? Color(0xff231b6a)
: null),
),
),
))
.toList()),
Updated error of code
Further Updated:
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
home: ReportPage(),
);
}
}
class RemarksModel {
bool isSelected;
String reason;
RemarksModel({this.isSelected, this.reason});
}
class ReportPage extends StatefulWidget {
List<RemarksModel> reportReasons;
#override
void initState() {
super.initState();
reportReasons = [
RemarksModel(isSelected: false, reason: 'Sexually Harassing'),
RemarksModel(isSelected: false, reason: 'Racially Discriminative'),
RemarksModel(isSelected: false, reason: 'Shouting'),
RemarksModel(isSelected: false, reason: 'Prank Calling'),
RemarksModel(isSelected: false, reason: 'Scam Bots'),
RemarksModel(isSelected: false, reason: 'Vulgarities Abusing'),
RemarksModel(isSelected: false, reason: 'No Sound')
];
}
#override
_ReportPageState createState() => _ReportPageState();
}
class _ReportPageState extends State<ReportPage> {
#override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
...
For the ease create a Model class for Reasons
class RemarksModel {
bool isSelected;
String reason;
RemarksModel({this.isSelected, this.reason});
}
and can be initialized as
List<RemarksModel> reportReasons;
#override
void initState() {
super.initState();
reportReasons = [
RemarksModel(isSelected: false, reason: 'blah'),
RemarksModel(isSelected: false, reason: 'blah blah'),
RemarksModel(isSelected: false, reason: 'blah blah blah')
];
}
then you can easily know whether the item is selected or not, and you can make an item select and deselect on the tap callback
onTap: () {
setState(() {
reportReason.isSelected = !reportReason.isSelected;
});
},
Full code
#override
Widget build(BuildContext context) {
return Container(
child: Wrap(
children: reportReasons
.map((reportReason) => GestureDetector(
onTap: () {
setState(() {
reportReason.isSelected = !reportReason.isSelected;
});
},
child: Container(
margin: EdgeInsets.only(
right: MediaQuery.of(context).size.width * 0.021,
bottom: MediaQuery.of(context).size.height * 0.009,
),
decoration: BoxDecoration(
color: reportReason.isSelected
? Color(0xff4aa3f8)
: Color(0xff3a327f),
borderRadius: BorderRadius.circular(12),
border: Border.all(
color: Colors.grey[50].withOpacity(0.60))),
padding: EdgeInsets.symmetric(
horizontal: MediaQuery.of(context).size.width * 0.027,
vertical:
MediaQuery.of(context).size.height * 0.0045),
child: Text(
reportReason.reason,
style: TextStyle(
fontSize: 13.5,
color: reportReason.isSelected
? Color(0xff231b6a)
: null),
),
),
))
.toList()),
);
}
if you need a list of selected reasons only,
List<RemarksModel> getSelectedReasons() {
return reportReasons.where((reason) => reason.isSelected).toList();
}
try wrap these lines inside a setState:
if (isSelected = false) {
isSelected = true;
} else {
isSelected = false;
}
and remove the setState below.

how to fix this google charts bar chart error

same data are used to draw line chart and bar chart. it works fine for drawing line. but there is an error for drawing bar chart. the error is "a.getTime is not a function×". any suggestions are appreciated.
here is my code:
datasource.addColumn('date', 'Date');
datasource.addColumn('number', 'quantity');
datasource.addColumn('number', 'quantity');
datasource.addColumn('number', 'quantity');
for (n = 0; n < tem.length; n++) {
datasource.addRows([[new Date(tem[n][0]), tem[n][1], tem[n][2], tem[n][3]]]);
}
*********line chart ***********
chart = new google.visualization.LineChart(document.getElementById('chart_div'));
var options = {
actions: ['dragToZoom', 'rightClickToReset'],
interpolateNulls: true, //bypass null
legend: 'none',
crosshair: { trigger: 'both', opacity: 0.5 }, // Display crosshairs on focus and selection.
title: 'Company Performance',
hAxis: { title: 'Year', titleTextStyle: { color: 'red' }, format: "YY.MM.dd", slantedText: true, slantedTextAngle: 30 },
vAxis: {
viewWindowMode: 'explicit',
viewWindow: {
max: maxy,
min: 0
}
},
explorer: { axis: 'horizontal', maxZoomOut: 1 } //wheel zoom
};
chart.draw(datasource, options);
***********bar chart*************
chart = new google.visualization.BarChart(document.getElementById('chart_div'));
var options = {
title: 'Company Performance',
hAxis: { title: 'Number', titleTextStyle: { color: 'red' } },
vAxis: { minValue: 0 },
explorer: { axis: 'horizontal', maxZoomOut: 1 }
};
chart.draw(datasource, options);*

Include Percentage In Legend

How would I add the segments percentage to the charts label?
Example
(Percentage values dont reflect the actual chart this is just an example.)
Here's my current template.
<ul class=\"<%=name.toLowerCase()%>-legend\"><% for (var i=0; i<segments.length; i++){%><li><span style=\"background-color:<%=segments[i].fillColor%>\"></span><%if(segments[i].label){%><%=segments[i].label%><%}%></li><%}%></ul>
You could update the template to do a couple of extra things. 1 get the total number being represented and then in the loop which displays the label print the result of that labels value as a percentage of the total.
ugly string
legendTemplate: "<ul class=\"<%=name.toLowerCase()%>-legend\"><% var total = segments.reduce(function(previousValue, currentValue){ return previousValue + currentValue.value;},0); for (var i=0; i<segments.length; i++){%><li><span style=\"background-color:<%=segments[i].fillColor%>\"></span><%if(segments[i].label){%><%=segments[i].label%> <%=Math.floor((segments[i].value/total)*100)%>%<%}%></li><%}%></ul>"
broken down
first get the total (here using reduce)
var total = segments.reduce(function(previousValue, currentValue){
return previousValue + currentValue;
},0);
and then when displaying use the total to work out the percentage (used floor here to just make sure we don't end up with a horrible number, could even add 0.5 to it before we floor to round to the nearest percent)
Math.floor((segments[i].value/total)*100)
Example (also fiddle)
$(function() {
var pieChartCanvas = $("#pieChart").get(0).getContext("2d");
var PieData = [{
value: 70000,
color: "#f56954",
highlight: "#f56954",
label: "Chrome"
}, {
value: 6000,
color: "#00a65a",
highlight: "#00a65a",
label: "IE"
}, {
value: 4000,
color: "#f39c12",
highlight: "#f39c12",
label: "FireFox"
}, {
value: 4000,
color: "#00c0ef",
highlight: "#00c0ef",
label: "Safari"
}, {
value: 3000,
color: "#3c8dbc",
highlight: "#3c8dbc",
label: "Opera"
}];
var pieOptions = {
segmentShowStroke: true,
segmentStrokeColor: "#fff",
segmentStrokeWidth: 2,
percentageInnerCutout: 50,
animationSteps: 100,
animationEasing: "easeOutBounce",
animateRotate: true,
animateScale: false,
responsive: true,
maintainAspectRatio: true,
legendTemplate: "<ul class=\"<%=name.toLowerCase()%>-legend\"><% var total = segments.reduce(function(previousValue, currentValue){ return previousValue + currentValue.value;},0); for (var i=0; i<segments.length; i++){%><li><span style=\"background-color:<%=segments[i].fillColor%>\"></span><%if(segments[i].label){%><%=segments[i].label%> <%=Math.floor((segments[i].value/total)*100)%>%<%}%></li><%}%></ul>"
};
var pieChart = new Chart(pieChartCanvas).Doughnut(PieData, pieOptions);
var helpers = Chart.helpers;
var legendHolder = document.getElementById('graph-legend');
legendHolder.innerHTML = pieChart.generateLegend();
// Include a html legend template after the module doughnut itself
helpers.each(legendHolder.firstChild.childNodes, function(legendNode, index) {
helpers.addEvent(legendNode, 'mouseover', function() {
var activeSegment = pieChart.segments[index];
activeSegment.save();
pieChart.showTooltip([activeSegment]);
activeSegment.restore();
});
});
helpers.addEvent(legendHolder.firstChild, 'mouseout', function() {
pieChart.draw();
});
document.getElementById('graph-legend').appendChild(legendHolder.firstChild);
});
#graph-legend ul {
list-style: none;
}
#graph-legend ul li {
display: block;
padding-left: 30px;
position: relative;
margin-bottom: 4px;
border-radius: 5px;
padding: 2px 8px 2px 28px;
font-size: 14px;
cursor: default;
-webkit-transition: background-color 200ms ease-in-out;
-moz-transition: background-color 200ms ease-in-out;
-o-transition: background-color 200ms ease-in-out;
transition: background-color 200ms ease-in-out;
}
#graph-legend li span {
display: block;
position: absolute;
left: 0;
top: 0;
width: 20px;
height: 100%;
border-radius: 5px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/1.0.2/Chart.js"></script>
<div class="box-body">
<canvas id="pieChart" width="787" height="300"></canvas>
</div>
<div id="graph-legend"></div>
In Chart.js V3 you can use a custom generateLabels function for this:
const options = {
type: 'pie',
data: {
labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
datasets: [{
label: '# of Votes',
data: [12, 19, 3, 5, 2, 3],
backgroundColor: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"]
}, ]
},
options: {
plugins: {
legend: {
labels: {
generateLabels: function(chart) {
const data = chart.data;
if (data.labels.length && data.datasets.length) {
const {
labels: {
pointStyle
}
} = chart.legend.options;
const max = data.datasets[0].data.reduce((a, b) => (a + b), 0);
return data.labels.map((label, i) => {
const meta = chart.getDatasetMeta(0);
const style = meta.controller.getStyle(i);
return {
text: `${label} (${(data.datasets[0].data[i] * 100 / max).toFixed(2)}%)`,
fillStyle: style.backgroundColor,
strokeStyle: style.borderColor,
lineWidth: style.borderWidth,
pointStyle: pointStyle,
hidden: !chart.getDataVisibility(i),
// Extra data used for toggling the correct item
index: i
};
});
}
return [];
}
},
}
}
}
}
const ctx = document.getElementById('chartJSContainer').getContext('2d');
new Chart(ctx, options);
<body>
<canvas id="chartJSContainer" width="600" height="400"></canvas>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.7.0/chart.js"></script>
</body>

Merge Jquery Knob Functionality in Chart Js

I am using Doughnut Chart of ChartJS, and here is my code
<!doctype html>
<html>
<head>
<title>Doughnut Chart</title>
<script src="jquery-1.11.3.min.js"></script>
<script src="jquery.knob.js"></script>
<script src="../Chart.js"></script>
<style>
body{
padding: 0;
margin: 0;
}
#canvas-holder{
width:30%;
}
</style>
</head>
<body>
<div id="canvas-holder">
<canvas id="chart-area" width="250" class="knob" height="250"/>
</div>
<script>
var doughnutData = [
{
value: 200,
color:"#F7464A",
highlight: "#FF5A5E",
label: "Red"
},
{
value: 200,
color: "#46BFBD",
highlight: "#5AD3D1",
label: "Green"
},
{
value: 200,
color: "#FDB45C",
highlight: "#FFC870",
label: "Yellow"
},
{
value: 200,
color: "#949FB1",
highlight: "#A8B3C5",
label: "Grey"
},
{
value: 200,
color: "#4D5360",
highlight: "#616774",
label: "Dark Grey"
},
{
value: 200,
color: "#949FB1",
highlight: "#A8B3C5",
label: "Grey"
},
{
value: 200,
color: "#949FB1",
highlight: "#A8B3C5",
label: "Grey"
},
{
value: 200,
color: "#949FB1",
highlight: "#A8B3C5",
label: "Grey"
},
{
value: 200,
color: "#949FB1",
highlight: "#A8B3C5",
label: "Grey"
},
{
value: 200,
color: "#949FB1",
highlight: "#A8B3C5",
label: "Grey"
},
{
value: 200,
color: "#949FB1",
highlight: "#A8B3C5",
label: "Grey"
},
{
value: 200,
color: "#949FB1",
highlight: "#A8B3C5",
label: "Grey"
}
];
var options = {
//Boolean - Whether we should show a stroke on each segment
segmentShowStroke : true,
//String - The colour of each segment stroke
segmentStrokeColor : "#fff",
//Number - The width of each segment stroke
segmentStrokeWidth : 0,
//Number - The percentage of the chart that we cut out of the middle
percentageInnerCutout : 80, // This is 0 for Pie charts
//Number - Amount of animation steps
animationSteps : 100,
//String - Animation easing effect
animationEasing : "easeOutBounce",
//Boolean - Whether we animate the rotation of the Doughnut
animateRotate : true,
//Boolean - Whether we animate scaling the Doughnut from the centre
animateScale : false,
showTooltips: false
}
window.onload = function(){
var ctx = document.getElementById("chart-area").getContext("2d");
var myDoughnut = new Chart(ctx).Doughnut(doughnutData, options);
$("#chart-area").click( function(evt){
var activePoints = myDoughnut.getSegmentsAtEvent(evt);
/* do something */
}
);
};
</script>
</body>
</html>
There is a requirement to update the value while clicking on the canvas, in the middle of doughnut chart (Just like in Jquery Knob http://anthonyterrien.com/knob/) i.e the value updates on sliding as well as clicking on the canvas. Is there any way to merge the functionality of these two libraries
It would be better to use that control. That said, you could do it Chart.js too. Here is a fair approximation (note that I've used jQuery for some parts, but you could do the same using plain javascript).
CSS
<style>
.myChartWrapper {
position: relative;
display: inline-block;
}
.myChartValue {
border: none;
font-family: 'Helvetica';
font-size: 20px;
overflow: visible;
width: 2em;
white-space: nowrap;
text-align: center;
position: absolute;
background-color: transparent;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
}
.myChartValue::-ms-clear {
display: none;
}
</style>
HTML
<div class="myChartWrapper">
<canvas id="myChart"></canvas>
<input id="myChartValue" class="myChartValue" />
</div>
Javascript
var value = 20;
var MAX = 200;
var STEP = 1;
var HALFSETCOLOR = "rgba(154, 225, 254, 1)";
var SETCOLOR = "rgba(134, 205, 234, 1)";
var UNSETCOLOR = "rgba(237, 237, 237, 1)";
var data = [];
for (var i = 0; i < MAX; i = i + STEP) {
data.push({
value: STEP,
color: (i < value) ? SETCOLOR : UNSETCOLOR,
label: i
})
}
var canvas = document.getElementById("myChart");
var ctx = canvas.getContext("2d");
var myDoughnutChart = new Chart(ctx).Doughnut(data, {
animation: false,
segmentShowStroke: false,
showTooltips: false
});
$("#myChartValue").val(value);
// half set the sectors
canvas.onmousedown = function (evt) {
var activeSegments = myDoughnutChart.getSegmentsAtEvent(evt);
if (activeSegments.length) {
var value = Number(activeSegments[0].label);
var crossed = false;
myDoughnutChart.segments.forEach(function (segment) {
if (Number(segment.label) >= value)
crossed = true;
if (!crossed && segment.fillColor !== SETCOLOR)
segment.fillColor = HALFSETCOLOR;
else if (crossed && segment.fillColor !== UNSETCOLOR)
segment.fillColor = HALFSETCOLOR;
})
myDoughnutChart.update()
myDoughnutChart.value = value;
$("#myChartValue").val(value);
}
};
canvas.onmousemove = function (evt) {
if (myDoughnutChart.value !== undefined) {
canvas.onmousedown(evt)
}
}
// set / unset sectors
canvas.onmouseup = function () {
var value = myDoughnutChart.value;
if (value !== undefined) {
var crossed = false;
myDoughnutChart.segments.forEach(function (segment, i) {
if (Number(segment.label) >= value)
crossed = true;
if (!crossed)
segment.fillColor = SETCOLOR;
else if (crossed)
segment.fillColor = UNSETCOLOR;
})
myDoughnutChart.value = undefined;
myDoughnutChart.update()
}
};
$("#myChartValue").on("change", function () {
myDoughnutChart.value = Number($("#myChartValue").val());
canvas.onmouseup();
})
It could do with a bit of cleanup (like handling change in direction without lifting the mouse), but comes pretty close to the knob functionality without too much effort.
Fiddle - http://jsfiddle.net/rxrxLo33/