fontello の利用でアイコンフォントを追加する時、

アイコンフォントを導入するのに便利な、http://fontello.com/ を利用した時、さらに使用するアイコンを追加する時、
どうしたら良いか?

最初にダウンロードした中に、config.json というファイルが含まれているはずなので、これをサイトにもう一度アップロードすると、
前回選択した状態になる。
f:id:posturan:20160828174809j:plain

このようにインポートをクリックしてアップロードをすると前回の選択状態になるので、これに追加して再度ダウンロードする。

config.json は、常に管理して、ダウンロードの度に、以下 css と font ファイルを上書きすれば良い。

animation.css
fontello.css
fontello-codes.css
fontello-embedded.css
fontello-ie7.css
fontello-ie7-codes.css

fontello.eot
fontello.svg
fontello.ttf
fontello.wof
fontello.woff2

   <i class="icon">&#xe842;</i>
@font-face{
	font-family: 'fontello';
	src: url('font/fontello.eot');
	src: url('font/fontello.eot#iefix') format('embedded-opentype'),
	     url('font/fontello.woff') format('woff'),
	     url('font/fontello.ttf') format('truetype'),
	     url('font/fontello.svg#fontello') format('svg');
	font-weight: normal;
	font-style: normal;
}
.icon{
	font-family: "fontello";
	font-style: normal;
	font-weight: normal;
	font-size: 24px;
	display: inline-block;
	text-decoration: inherit;
}

さらに、色やマスクによるグラデーションなら、この .icon 属性に、

color: #00b0ff;
-webkit-mask-image: -webkit-linear-gradient(top, rgba(0,0,0,0), rgba(0,0,0,24));

のように追加する。

プログレスバー、画像を使わずに。

画像を使わないでCSSで描画させるプログレスバーを探したらありました。

red-team-design.com

これを jQuery の $.ajax で通信した時に、進捗率を表示させます。

これに、バーの中央に(%)進捗率を表示させたいので、以下のようにHTMLを書いて、

	<div id="preogress_bar" class="progress-bar stripes">
		<span style="width: 0%"></span><p>0 %</p>
	</div>

次のCSSスタイルを追加します。

div.progress-bar{
	position: relative;
	margin: 20px 10px;
	display: none;		/* 初期表示は隠す */
}
.progress-bar p{
	position: absolute;
	top: 6px;		/* font-size 考慮して調整 */
	left: 250px;	/* .progress-bar  width → 半分程度に調整 */
	margin: 0px;
	color: #ffffff;
	font-size: 12px;
	text-align: center;
}

jQuery は、以下の様に用意します。

$.ajax({ url: "/hoge/upload",
	type: 'POST',
	data : formdata,
	dataType: 'json',
	contentType: false,
	processData: false,
	async: true,
	xhr : function(){
		XHR = $.ajaxSettings.xhr();
		if(XHR.upload){
			XHR.upload.addEventListener('progress', function(e){
				var progress = parseInt(e.loaded/e.total*10000)/100;
				console.log(progress+"%");
				$('#preogress_bar').children("span").css('width', progress + "%");
				$('#preogress_bar').children("p").html(progress + " %")
			}, false);
		}
		return XHR;
	},
	success: function(data, textStatus, jqXHR){
	},
	error: function(jqXHR, textStatus, errorThrown){
		alert('error');
	}
});

以下のように表示されます。

f:id:posturan:20160822215441j:plain

groupingBy で chunk

grouping by のメモ

Map<String, Long> countmap = authors.stream().collect(Collectors.groupingBy(t->t.level, Collectors.counting()));
Map<String, List<Author>> mapAuthors = authors.stream().collect(Collectors.groupingBy(t->t.level, Collectors.mapping(u->u, Collectors.toList())));

Stream の grouping by は、chunk リストを作るの役立つ

AtomicInteger を利用して、3個ずつに分けたリストのコレクションを生成

AtomicInteger counter = new AtomicInteger();
Collection<List<Author>> chunklist = authors.stream().collect(Collectors.groupingBy(t->counter.getAndIncrement() / 3 , Collectors.mapping(u->u, Collectors.toList()))).values();

mybatis foreach の index を使う

MyBatis の foreach の index を使えば、Multiple INSERT を実行するとき foreach のカウンタを挿入する行の
列の値にすることができる。

<insert id="insertEmployee" parameterType="map">
INSERT INTO employees ( employee_name , employee_no ) VALUES
<foreach collection="e_list" item="e"  separator="," index="index">
 ( #{e.dummy}, #{index} )
</foreach>
</insert>

これは、index="index" より #{index} が 0始まりで値が挿入される。0からでなく100から開始したければ、

<foreach collection="e_list" item="e"  separator="," index="index">
 ( #{e.dummy}, #{index} + 100 )
</foreach>

と書けば良い。

mybatis の SQLMap ステートメントとして、このように固定ではなく、foreach に渡すリストObject以外のものを
渡して foreach に書いて動的にすることもできる。

<foreach collection="e_list" item="e"  separator="," index="index">
 ( #{e.dummy}, #{index} + #{level} )
</foreach>

省略はするが、Map に渡して実行するサンプル

Map<String, Object> map = new HashMap<String, Object>();

map.put("e_list", employees_list);
map.put("level", 100);

SqlSession sesssion;

session.insert("org.sample.insertTest"), map);

リストから順序を維持した Pair を作成する

文字列でもなんでも良いのだが、"a","b","c"... リストの順序に従った「ペア」を順序にしたがって作りたい要求があったとする。

"a" と "b"
"b" と "c"
"c" と "d"

のように順にペアを作る。ペアは、AbstractMap.SimpleEntry を継承したクラスとする。

public class Pair<K, V> extends AbstractMap.SimpleEntry<K, V> implements Serializable{
   public Pair(final K key, final V value){
      super(key, value);
   }
}

以下リストに対して Pairのリストを作るのが目的

     List<String> list = Arrays.asList("a","b","c","d","e","f","g","h");

これから作るのに悩んだあげく ListIterator を使用し最初のイテレータを2番目に置く方法だ。
リストが1個しかない時は、作らない。ListIteratorだから、空リストは処理できない。

List<Pair> plist = new ArrayList<>();
for(ListIterator<String> it=list.listIterator(1);it.hasNext();){
   plist.add(new Pair<String, String>(list.get(it.nextIndex()-1), it.next()));
}

plist.stream().forEach(p->{
   System.out.println( "key=" + p.getKey() + " value=" + p.getValue() );
});

結果は println の結果はこうなる。

key=a value=b
key=b value=c
key=c value=d
key=d value=e
key=e value=f
key=f value=g
key=g value=h

もっと良い方法があればいいのに。

コレクションの比較→ BiConsumer に index と比較結果

先日、2つのオブジェクトの比較、equals がそのまま使えること、"" 空文字=すなわち存在しないことと
null を同義とみた処理で書いてた。
・・・・実質、String と Integer にしかそのまま使えないけど、それしか目的にしてなかったのでそういうつもりで
使えばいいと安易な考え、自分勝手なものだけど。

この勢いで作ったのが、コレクションの比較

public static <T, U, R> Collection<R> parse(Collection<T> tcol, Collection<U> ucol, BiConsumer<Integer, T> tonly, BiConsumer<Integer, U> uonly){
   AtomicInteger index = new AtomicInteger(0);
   tcol.stream().forEach(t->{
      int i = index.getAndIncrement();
      if (ucol.stream().noneMatch(u->u.equals(t))){
         tonly.accept(i, t);
      }
   });
   index.set(0);
   return ucol.stream().<R>map(u->{
      int i = index.getAndIncrement();
      if (tcol.stream().noneMatch(t->t.equals(u))){
         uonly.accept(i, u);
         return null;
      }else{
         return (R)u;
      }
   }).filter(r->r != null).collect(Collectors.toList());
}