I've been working on PrimeFaces Bar chart model,and its getting on my nerves now,I just can't get how its setting chart series values.What expected result should be that One Open for say abc and one closed for xyz, But what It shows one open and one closed for xyz,ABC is Ignored. If I change the position of
barModel.addSeries(close);
barModel.addSeries(open);
to
barModel.addSeries(open);
barModel.addSeries(close);
Then It shows One open and one closed for only abc,Not xyz.
here's my getBarModel() first,
public BarChartModel getBarModel() {
barModel=new BarChartModel();
ChartSeries open = new ChartSeries();
open.setLabel("OPEN");
ChartSeries close = new ChartSeries();
close.setLabel("Close");
open.set("abc", 1);
close.set("xyz", 1);
barModel.addSeries(close);
barModel.addSeries(open);
barModel.setMouseoverHighlight(false);
barModel.setShowPointLabels(false);
barModel.setTitle("Incident_application");
barModel.setLegendPosition("ne");
barModel.setShowDatatip(false);
barModel.setShowPointLabels(true);
barModel.setExtender("chartExtender");
barModel.setSeriesColors("A2CC39,1B75BA");
Axis xAxis = barModel.getAxis(AxisType.X);
xAxis.setLabel("Applications");
barModel.setAnimate(true);
Axis yAxis = barModel.getAxis(AxisType.Y);
yAxis.setLabel("No. of Incident");
yAxis.setMin(0);
yAxis.setMax(20);
yAxis.setTickInterval("10");
return barModel;
}
and here is xhtml
<h:outputScript library="primefaces" name="jquery/jquery.js" target="head" />
<h:outputScript library="primefaces" name="jquery/jquery-plugins.js" target="head" />
<style type="text/css">
table.jqplot-table-legend {
border: none;
font-size: x-large;
}
div.jqplot-table-legend-swatch
{
width: 2vw;
height: 2vh;
}
div.jqplot-gridData{
display:none;
}
div.jqplot-xaxis-tick{
font-weight:bold !important;
}
.jqplot-axis.jqplot-xaxis{
font-weight:bold;
}
.jqplot-point-label {
font-size: 300%;
color: black;
font-weight: bold;
}
.jqplot-target{
color:black !important;
}
</style>
<script>
function chartExtender() {
this.cfg.grid = {
background: 'transparent',
gridLineColor: '#303030',
drawBorder: false,
};
}
</script>
<h:form id="barChart">
<p:chart id="bar" type="bar" model="#{incidentBarChartController.barModel}" />
<p:poll interval="10" global="false" update="barChart"/>
</h:form>
</h:body>
Snapshots of expected and Actual results are added below.
Expected Result
Actual Result
Edit
After adding
open.set("abc", 1);
open.set("xyz",0);
close.set("xyz", 1);
close.set("abc", 0);
I still get weird results i.e.
1 open and 1 closed for xyz and 0 open and 0 closed for xyz.
The only solution is that you as a developer make sure all series contains all keys and populate the keys which you do not have and make sure all keys in all series are in the same order.
The reason for this is that only you know the real order (that is why a LinkedHashMap is used in the series). jQplot or PrimeFaces cannot know this. If e.g. the first series misses a key and that series is used as the 'primary' to iterate over, where is the missing key going to put. And if e.g. at position 6, both have a key that is not in the other set, which one should be taken first? The jqPlot or PrimeFaces cannot know. All reasons that you as a developer should make sure it is explicit by putting all keys in all series.
Related
I am developing a Twilio Flex plugin using Flex Ui version 2 (beta.1 and beta.2).
I wanted to add multiple tabs to TaskCanvasTabs and tried to write the following code.
import React from 'react';
import { Tab } from '#twilio/flex-ui';
import { FlexPlugin } from '#twilio/flex-plugin';
import SmsPanel from './components/SmsPanel/SmsPanel';
import IncomingVideo from './components/IncomingVideo/IncomingVideo';
const PLUGIN_NAME = 'SendSmsV2Plugin';
export default class SendSmsV2Plugin extends FlexPlugin {
constructor() {
super(PLUGIN_NAME);
}
/**
* This code is run when your plugin is being started
* Use this to modify any UI components or attach to the actions framework
*
* #param flex { typeof import('#twilio/flex-ui') }
*/
async init(flex, manager) {
const options = {
align: 'end',
};
flex.TaskCanvasTabs.Content.add(
<Tab label='SMS' key='sms-panel-tab-key'>
<SmsPanel key='sms-panel-component' />
</Tab>,
options,
);
flex.TaskCanvasTabs.Content.add(
<Tab label='Video' key='video-panel-tab-key'>
<IncomingVideo key='incoming-video-component' />
</Tab>,
options,
);
}
}
When executed, the first Tab (SMS) added will be duplicated as shown below. Thereafter, each time I select the first Tab, Call tab, etc., the first Tab added will be increased.
Can someone please tell me if the specification does not allow adding multiple tabs to TaskCanvasTabs or how to solve this problem?
I also tried with Flex Ui version 2 (beta.3) but the behavior is the same.
It seems that this issue only happens when you try to add multiple tabs on TaskCanvasTabs
To resolve this issue you could add a Tab Group which contains Tabs
flex.TaskCanvasTabs.Content.add(
<Flex.Tabs key="custom-tabs-group">
<Flex.Tab key="conversation-note-tab" label="Conversation Notes">
<ConversationNote key="conversation-note" />
</Flex.Tab>
<Flex.Tab key="label-to-conversation" label="Conversation Label">
<AttachLabelToConversation key="add-label-to-conversation" />
</Flex.Tab>
</Flex.Tabs>,
{}
);
Use this css to adjust the tab group text
/* Added CSS for merged TaskCanvasTabs into Tabs group start */
.Twilio-TaskCanvas .Twilio-TaskCanvas-default .Twilio-TaskCanvasTabs div[data-test="customer-tab-header"]:has(> div > button) button {
width: 100%;
height: 100%;
}
.Twilio-TaskCanvas .Twilio-TaskCanvas-default .Twilio-TaskCanvasTabs div[data-test="customer-tab-header"]:has(> div > button) button:hover {
background-color: unset;
}
.Twilio-TaskCanvas .Twilio-TaskCanvas-default .Twilio-TaskCanvasTabs div[data-test="customer-tab-header"]:has(> div > button) button div svg {
display: none;
}
.Twilio-TaskCanvas .Twilio-TaskCanvas-default .Twilio-TaskCanvasTabs div[data-test="customer-tab-header"]:has(> div > button) button div:after {
content: "Conversation Actions";
font-size: 14px;
font-weight: 600;
color: rgb(96, 107, 133);
padding-bottom: 6px;
}
/* Added CSS for merged TaskCanvasTabs into Tabs group end */
I heard the best solution.
TabPros is using the optional uniqueName prop instead of the key for identifying the selected tab.
So, I changed my code below. It was fixed.
flex.TaskCanvasTabs.Content.add(
<Tab label='SMS' key='sms-panel-tab-key' uniqueName='sms-panel-tab'>
<SmsPanel key='sms-panel-component' />
</Tab>,
options,
);
flex.TaskCanvasTabs.Content.add(
<Tab label='Video' key='video-panel-tab-key' uniqueName='video-panel-tab'>
<IncomingVideo key='incoming-video-component' />
</Tab>,
options,
);
The link referenced is below.
https://github.com/twilio/flex-plugin-builder/issues/327
I can only find questions where people have the opposite problem.
I want my fixed content to go above the iOS keyboard.
Image of the problem:
I want iOS to behave like Android.
Is there a simple way to achieve this?
Parent element css:
.parent{
position:fixed;
top: 0;
left 0;
right: 0;
bottom: 0;
width: 100%;
height: 100%;
}
Button css:
.button{
position:fixed;
left 0;
right: 0;
bottom: 0;
width: 100%;
height: 5rem;
}
We can use VisualViewport to calculate keyboard height. So we can set fixed-content pos correct.
Small demo: https://whatwg6.github.io/pos-above-keyboard/index.html
Code snippet:
const button = document.getElementById("button");
const input = document.getElementById("input");
const height = window.visualViewport.height;
const viewport = window.visualViewport;
window.addEventListener("scroll", () => input.blur());
window.visualViewport.addEventListener("resize", resizeHandler);
function resizeHandler() {
if (!/iPhone|iPad|iPod/.test(window.navigator.userAgent)) {
height = viewport.height;
}
button.style.bottom = `${height - viewport.height + 10}px`;
}
function blurHandler() {
button.style.bottom = "10px";
}
html,
body {
margin: 0;
padding: 0;
}
#button {
position: fixed;
width: 100%;
bottom: 10px;
background-color: rebeccapurple;
line-height: 40px;
text-align: center;
}
<input type="text" inputmode="decimal" value="0.99" id="input" onblur="blurHandler()" />
<div id="button">Button</div>
Problems: https://developers.google.com/web/updates/2017/09/visual-viewport-api#the_event_rate_is_slow
Why not innerHeight?: Iphone safari not resizing viewport on keyboard open
Mobile Safari does not support position: fixed when an input focused and virtual keyboard displayed.
To force it work the same way as Mobile Chrome, you have to use position: absolute, height: 100% for the whole page or a container for your pseudo-fixed elements, intercept scroll, touchend, focus, and blur events.
The trick is to put the tapped input control to the bottom of screen before it activates focus. In that case iOS Safari always scrolls viewport predictably and window.innerHeight becomes exactly visible height.
Open https://avesus.github.io/docs/ios-keep-fixed-on-input-focus.html in Mobile Safari to see how it works.
Please avoid forms where you have several focusable elements because more tricks to fix position will be necessary, those were added just for demonstration purposes.
Note that for rotation and landscape mode, additional tricks are necessary. I'm working on a framework called Tuff.js which will provide a full-screen container helping mobile web developers to build web applications much faster. I've spend almost a year on the research.
By the way, to prevent scrolling of the whole window when virtual keyboard is active, you can use this super simple trick
var hack = document.getElementById('scroll-hack');
function addScrollPixel() {
if (hack.scrollTop === 0) {
// element is at the top of its scroll position, so scroll 1 pixel down
hack.scrollTop = 1;
}
if (hack.scrollHeight - hack.scrollTop === hack.clientHeight) {
// element is at the bottom of its scroll position, so scroll 1 pixel up
hack.scrollTop -= 1;
}
}
if (window.addEventListener) {
// Avoid just launching a function on every scroll event as it could affect performance.
// You should add a "debounce" to limit how many times the function is fired
hack.addEventListener('scroll', addScrollPixel, true);
} else if (window.attachEvent) {
hack.attachEvent('scroll', addScrollPixel);
}
body {
margin: 0 auto;
padding: 10px;
max-width: 800px;
}
h1>small {
font-size: 50%;
}
.container {
display: flex;
align-items: top;
justify-content: space-between;
}
.container>div {
border: #000 1px solid;
height: 200px;
overflow: auto;
width: 48%;
-webkit-overflow-scrolling: touch;
}
<h1>iOS Scroll Hack</h1>
<p>Elements with overflow:scroll have a slightly irritating behaviour on iOS, where when the contents of the element are scrolled to the top or bottom and another scroll is attempted, the browser window is scrolled instead. I hacked up a fix using minimal,
native JavaScript.</p>
<p>Both lists have standard scrolling CSS applied (<code>overflow: auto; -webkit-overflow-scrolling: touch;</code>), but the list on the right has the hack applied. You'll notice you can't trigger the browser to scroll whilst attempting to scroll the list
on the right.</p>
<p>The only very slight drawback to this is the slight "jump" that occurs when at the top or bottom of the list in the hack.</p>
<div class='container'>
<div id='scroll-orig'>
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li>6</li>
<li>7</li>
<li>8</li>
<li>9</li>
<li>10</li>
<li>11</li>
<li>12</li>
<li>13</li>
<li>14</li>
<li>15</li>
<li>16</li>
<li>17</li>
<li>18</li>
<li>19</li>
<li>20</li>
</ul>
</div>
<div id='scroll-hack'>
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li>6</li>
<li>7</li>
<li>8</li>
<li>9</li>
<li>10</li>
<li>11</li>
<li>12</li>
<li>13</li>
<li>14</li>
<li>15</li>
<li>16</li>
<li>17</li>
<li>18</li>
<li>19</li>
<li>20</li>
</ul>
</div>
</div>
Got this answer from here
This is a well known problem, and unfortunately one must resort to hacky tricks like the accepted answer for now. The W3C is however in the process of specifying The VirtualKeyboard API.
Note: At the time of writing, this answer is not yet ready for prime time. It's important to understand that this specification must also be forward looking, to adapt to the myriad possible virtual keyboards of the future. It may be a few years before reliable cross platform browser support begins to appear and this answer becomes the correct one.
I found an interesting solution to this problem.
The solution is to create a hidden input and focus on it on the touchstart event.
<input id="backinput" style="position:absolute;top:0;opacity:0;pointer-events: none;">
<input id="input" style="position:absolute;bottom:0;">
Using JQuery:
$('#backinput').on('focus',function(e)
{
e.preventDefault();
e.stopPropagation();
const input = document.getElementById('input');
input.focus({ preventScroll: true });
})
$('#input').on("touchstart", function (event) {
if(!$(this).is(":focus"))
{
event.stopPropagation();
event.preventDefault();
$('#backinput').focus();
}
})
Finally, resize the viewport so that the bottom input moves above the keyboard (if needed)
window.visualViewport.addEventListener("resize", (event) => {
$('body').height(parseInt(visualViewport.height));
});
For me it works perfect. I am building a messenger.
Alright, I'm launching this website (beta) in an hour but I've just noticed an ugly bug. I've added a new counter (1, 2, 3, etc..) was previously using <ol>.
Look at this picture the before:
everything was even, the vote up button, the text all the way down.
Now the live version after adding new counter: www.leapfm.com is un even. (when it becomes double digits)
Please use FireBug or Chrome Developer Tools, if you need any further code I will provide it ASAP.
original code:
.subtext1 {
font-family: Verdana;
font-size: 7pt;
color: #828282;
}
.song {
height: 42px;
}
.counter {
float: left;
margin-right: 2px;
font-size: 14px;
}
.subtext {
font-family: Verdana;
font-size: 7pt;
color: #828282;
}
.title {
font-family: Verdana;
font-size: 10.3pt;
color: #828282;
}
(I'm adding an answer because I can't preview my code with a comment and they're not giving me enough space.)
Yes, an ol (or table) would've worked. But a quick-fix solution would be to give the counter a fixed width (say 30px). The only problem with this would be if you started having a lot more digits.
If you wanted to fix this using JavaScript (which would work forever), use code like this (jQuery).
<script type="text/javascript">
var counters = $(".counter");
var counterLen = counters.length; //one based
//convert to zero based
var largestWidth = counters[counterLen - 1].offsetWidth + "px";
//WAY ONE: DO IT WITH A STYLESHEET (I recommend this)
var stylesheetDiv = $("<div>");
stylesheetDiv.html("<style type=\"text/css\">.counter{width: " + largestWidth + "}</style>");
$("head").append(stylesheetDiv);
//WAY TWO: DO IT WITH A JQUERY LOOP
counters.css({width: largestWidth});
</script>
I used way one before. I'm pretty sure I have to do the div with a stylesheet inside for IE8.
For .subtext1, give it a margin-left: 15px.
For .counter, give it a height of 100% or 22px.
And delete the multiple between .title and .subtext1.
I am pulling out information from the google places API I want to be able to show all the coordinates that I've pulled on one map v.s. having multiple maps on a page (as shown below). Does anyone have any suggestions?
Thank you in advance!
<%#c.each do |p|%>
<ul>
<li><%= image_tag("http://maps.googleapis.com/maps/api/staticmap?center=#{p.lat},#{p.lng}&zoom=15&size=600x300&maptype=roadmap
&markers=color:blue%7Clabel:S%7C#{p.lat},#{p.lng}&sensor=true")%></li>
<li><%=p.name%></li>
<li><%=p.rating%></li>
<li><%p.lat%></li>
<li><%p.lng%></li>
</ul>
<%end%>
If I understand you correctly you essentially need the multiple ul tags to align with each other.
Essentially you would need to give a fixed width to your ul element and apply a float. Here I have assumed that you would like three maps side-by-side.
The CSS code for it is:
* {
box-sizing:border-box;
-moz-box-sizing:border-box;
}
ul {
list-style: none;
width: 30%;
float: left;
margin: 0;
padding:1.5%;
}
ul img {
max-width:100%;
}
or if you prefer SCSS:
* {
box-sizing:border-box;
-moz-box-sizing:border-box;
}
ul {
list-style: none;
width: 30%;
float: left;
margin: 0;
padding:1.5%;
li {
img {
max-width:100%;
}
}
}
If you would like to see how this would look, check it out at http://jsfiddle.net/dheer/Ltxzj/2/
Note: If you are adding this to your rails app you may want to assign a new class to the ul tag as styling the current code may affect other design elements.
There's an answer made by Martin Bean in this thread:
How do I show multiple locations in Google Maps?
which uses the google maps javascript api. As seen in that example, you should just add Markers to the map from your coordinates (in that case he uses a bunch of coordinates that you should load from your model).
I am working on jqgrid with ASP.NET WEB API.
I want to add two rows in the footer of jqgrid.
So a little search on the net brought me to this link (2010) which says "It is not possible", I am thinking as the answer is of 2010, may be by now some thing / some workaround may have been made possible for this.
What do I want to show in footer ?
I want to show two rows
Total for data preset in current page
Grand total for data present in all of the pages
I am able to pass the data and read the data, the question is how to use this data and create two footer rows in jqgrid.
Any thoughts ?
I found the question interesting, so I created the demo which demonstrates one from the possible implementation of two-rows footer:
The main idea is to add the second row in the table where the standard footer already exist. To eliminate possible problems with other parts of jqGrid code I replaced footrow class name in the custom row to myfootrow. To have the same CSS settings for the second footer as the original tooter has I included the copy of .ui-jqgrid tr.footrow td from ui.jqgrid.css with the same definitions for .ui-jqgrid tr.myfootrow td:
.ui-jqgrid tr.myfootrow td {
font-weight: bold;
overflow: hidden;
white-space:nowrap;
height: 21px;
padding: 0 2px 0 2px;
border-top-width: 1px;
border-top-color: inherit;
border-top-style: solid;
}
The full code you will find below
footerrow: true,
loadComplete: function () {
var $this = $(this),
sum = $this.jqGrid("getCol", "amount", false, "sum"),
$footerRow = $(this.grid.sDiv).find("tr.footrow"),
localData = $this.jqGrid("getGridParam", "data"),
totalRows = localData.length,
totalSum = 0,
$newFooterRow,
i;
$newFooterRow = $(this.grid.sDiv).find("tr.myfootrow");
if ($newFooterRow.length === 0) {
// add second row of the footer if it's not exist
$newFooterRow = $footerRow.clone();
$newFooterRow.removeClass("footrow")
.addClass("myfootrow ui-widget-content");
$newFooterRow.children("td").each(function () {
this.style.width = ""; // remove width from inline CSS
});
$newFooterRow.insertAfter($footerRow);
}
$this.jqGrid("footerData", "set", {invdate: "Total (page):", amount: sum});
// calculate the value for the second footer row
for (i = 0; i < totalRows; i++) {
totalSum += parseInt(localData[i].amount, 10);
}
$newFooterRow.find(">td[aria-describedby=" + this.id + "_invdate]")
.text("Grand Total:");
$newFooterRow.find(">td[aria-describedby=" + this.id + "_amount]")
.text($.fmatter.util.NumberFormat(totalSum, $.jgrid.formatter.number));
}
In the code I set additional information in columns invdate and amount of the footer.