質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
canvas

HTML5の<canvas>要素用のタグです。CanvasはHTML5から導入された、二次元の図形描写が可能な要素です。

CSS3

CSS(Cascading Style Sheet)の第3版です。CSS3と略されることが多いです。色やデザインを柔軟に変更することが可能になります。

HTML5

HTML5 (Hyper Text Markup Language、バージョン 5)は、マークアップ言語であるHTMLの第5版です。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

解決済

2回答

4984閲覧

canvasの重ね描画方法について

masahiro.o

総合スコア16

canvas

HTML5の<canvas>要素用のタグです。CanvasはHTML5から導入された、二次元の図形描写が可能な要素です。

CSS3

CSS(Cascading Style Sheet)の第3版です。CSS3と略されることが多いです。色やデザインを柔軟に変更することが可能になります。

HTML5

HTML5 (Hyper Text Markup Language、バージョン 5)は、マークアップ言語であるHTMLの第5版です。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

0グッド

0クリップ

投稿2017/05/15 08:31

編集2017/05/16 06:56

###前提・実現したいこと
メインのcanvasにchart.jsでグラフを描画しています。
このライブラリに自体にはスクロール機能がないので、divタグでラッパーを作成しcssで「overflow-x: scroll」を
指定する事で横スクロールは可能となります。
このままだとスクロール中は軸の目盛りが見えなくなってしまうので
軸を描画するcanvasを別に用意して元のグラフの左端に配置しスクロールしても左にY軸のスコアがついてくるようなサンプルを見つけて実現できました。

これが2軸グラフになったときに右側にも同じようにcanvasを用意して右側のY軸のスコアを常時表示したいと思っています。

html

<!DOCTYPE html> <html lang="ja"> <head> <title>MIX Chart Test</title> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <style type="text/css"> .chartWrapper { position: relative; } .chartWrapper > canvas { position: absolute; left: 0; top: 0; pointer-events:none; } .chartAreaWrapper { width: 600px; overflow-x: scroll; </style> </head> <body> <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.3.0/Chart.bundle.min.js"></script> <div class="chartWrapper"> <div class="chartAreaWrapper"> <!-- chart.jsでグラフを描画しているcanvasです --> <canvas id="myChart" height="300" width="1200"></canvas> </div> <!-- グラフの左目盛りを描画しているcanvasです --> <canvas id="myChartAxis" height="300" width="0"></canvas> </div> <script> // canvas(myChart)にグラフを描画しています。 window.onload = function() { ctx = document.getElementById("myChart").getContext("2d"); window.myBar = new Chart(ctx, { type: 'bar', data: barChartData, options: complexChartOption, }); }; // グラフのデータ定義です。 var barChartData = { labels: ['8/26','8/27','8/28','8/29','8/30','8/31','9/1', '9/2','9/3','9/4','9/5','9/6','9/7','9/8', '9/9','9/10','9/11','9/12','9/13','9/14', '9/15','9/16','9/17','9/18','9/19','9/20','9/21','9/22' ], datasets: [ { type: 'line', label: 'sample-line', data: ['0.155','0.118','0.121','0.068','0.083','0.060','0.067', '0.121','0.121','0.150','0.118','0.097','0.078','0.127', '0.155','0.140','0.101','0.140','0.041','0.093','0.189', '0.146','0.134','0.127','0.116','0.111','0.125','0.116' ], borderColor : "rgba(254,97,132,0.8)", pointBackgroundColor : "rgba(254,97,132,0.8)", fill: false, yAxisID: "y-axis-1", xAxisID: "x-axis-1", }, { type: 'bar', label: 'sample-bar', data: ['0.3','0.1','0.1','0.3','0.4','0.2','0.0', '0.2','0.3','0.11','0.5','0.2','0.5','0.4', '0.0','0.3','0.7','0.3','0.6','0.4','0.9', '0.7','0.4','0.8','0.7','0.4','0.7','0.8' ], borderColor : "rgba(54,164,235,0.8)", backgroundColor : "rgba(54,164,235,0.5)", yAxisID: "y-axis-2", }, ], }; // グラフのオプションです。 var complexChartOption = { responsive: false, scales: { yAxes: [{ id: "y-axis-1", type: "linear", position: "left", ticks: { max: 0.2, min: 0, stepSize: 0.1 }, }, { id: "y-axis-2", type: "linear", position: "right", ticks: { max: 1.5, min: 0, stepSize: .5 }, gridLines: { drawOnChartArea: false, }, }], xAxes: [{ id: "x-axis-1", barThickness: 30 }] }, animation: { // グラフの描画が完了したときに呼び出される関数です。 onComplete: function(data) { // グラフの左端にcanvasを配置し、グラフの左側の目盛りを描画しています。 var sourceCanvas = this.chart.ctx.canvas; var getParentIdName = this.chart.canvas.attributes.id.value, targetElement = document.getElementById("myChartAxis"), sourceElement = document.getElementById("myChart"), copyWidth = this.scales["y-axis-1"].width - 10, copyHeight = this.chart.height + 5, targetElementWidth = sourceElement.getContext("2d").canvas.clientWidth, targetElementHeight = sourceElement.getContext("2d").canvas.clientHeight, targetCtx = targetElement.getContext("2d"); targetCtx.canvas.width = copyWidth; targetCtx.canvas.height = copyHeight; targetCtx.drawImage(sourceCanvas, 0, 0, targetElementWidth, targetElementHeight); } } }; </script> </body> </html>

###やったこと
以下のようにcanvasを追加して、描画のロジックも書いてみたのですがダメでした。
現在もちょくちょくいじっているのですが、どうもうまくいきません。
私の知識がないのが最大の原因なのですが、以下のロジックだと新しく追加したcanvas(myChartAxis2)と
前からあったcanvas(myChartAxis)は同じ位置に同じものが描画されてしまいます。

  • スタイルの変更

右軸用のcanvas(id=myChartAxis2)定義を追加しました。

<style type="text/css"> .chartWrapper { position: relative; } .chartWrapper > #myChart, #myChartAxis { position: absolute; left: 0; top: 0; pointer-events:none; } .chartWrapper > #myChartAxis2 { position: absolute; top: 0; left: 570; pointer-events:none; } .chartAreaWrapper { width: 600px; overflow-x: scroll; </style>
  • canvasの追加

右軸用のcanvas(id=myChartAxis2 )を追加しました。

<!-- グラフの左目盛りを描画しているcanvasです --> <canvas id="myChartAxis2" height="300" width="0"></canvas>
  • onCompleteにロジック追加
var targetElement2 = document.getElementById("myChartAxis2"), copyWidth2 = this.scales["y-axis-2"].width - 10, copyHeight2 = this.chart.height + 5, targetElementWidth2 = sourceElement.getContext("2d").canvas.clientWidth, targetElementHeight2 = sourceElement.getContext("2d").canvas.clientHeight, targetCtx2 = targetElement2.getContext("2d"); targetCtx2.canvas.top = 0; targetCtx2.canvas.left = this.scales["y-axis-2"].left; targetCtx2.canvas.width = copyWidth2; targetCtx2.canvas.height = copyHeight2; targetCtx2.drawImage(sourceCanvas, this.scales["y-axis-2"].left, 0, copyWidth2, copyHeight2, sourceCanvas.left - copyWidth2, 0, copyWidth2, copyHeight2);

###問題
恥ずかしながらhtml・cssの知識が薄く、もう一つcanvasを用意して(myChartAxis2のような)
canvas(id=myChart)の右軸を描画して配置する方法が分かりません。

ソースを張り付けただけの内容で申し訳ございませんが、ご教示頂けると幸いです。
不足事項があればコメント頂ければ追記いたします。

以上、よろしくお願いします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

自己解決

本当に質問したい内容と聞き方がかけ離れていましたので、一旦Closeしてソースを作り直して再質問します。
(読み返すとchart.jsの知識が必須に見えてしまいますが、聞きたいのはCanvasの配置方法だけです。)

見て頂いた方や検証して頂いた方がいらっしゃったら申し訳ございませんでした。

投稿2017/05/18 12:39

masahiro.o

総合スコア16

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

chart.jsの専門家が現れればよいのですが、現れなかったときの対応として、
0. 別のcanvasを右に配置し、自力で軸、目盛を描画する
0. 要件の機能を持ったグラフライブラリを使う
のいずれかと思います。
前者の案はとても難しく、元のライブラリをhackしないとできません。
むしろグラフを全く自力で書いたほうが楽かも知れません。
後者の案として以下をお勧めします。
http://nvd3.org/examples/lineWithFocus.html
ちょっと分かりにくいですが下段の小さなグラフをドラッグすると表示範囲を絞れます。
このサイトの別のサンプルに2軸グラフもありますので
組み合わせることで実現できると思います。
nvd3.jsはd3.jsのラッパーです。
d3.jsは結構書籍も出ているので入りやすいと思います。
書籍は「インタラクティブ・データビジュアライゼーション ―D3.jsによるデータの可視化」が基礎から解説してあるのでお勧めです。

投稿2017/05/16 03:22

yasushi_sapporo

総合スコア61

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

masahiro.o

2017/05/16 05:18

1の方を想定していました。 教えて頂いたライブラリいいですね。 しかしながら、今回は既存サイトの改修でしてchart.js以外は使えません… 自力で軸・目盛を描画するというよりは元のグラフ(myChart)の右目盛部分だけを切り取って 右側に配置したcavasにdrawImageするイメージだったのですが難しいですかね… 左のcanvas(myChartAxis)は元のグラフ(myChart)の左目盛部分だけを表示しているのですが 同じことを右側でもできないかと試行錯誤していました。
masahiro.o

2017/05/17 06:22

やっぱりできそうですよね。 質問もchart.jsに特化しているように見えてしまうので canvasの描画に絞って大幅に変更しようかと思っています。 引き続き自分でも調べてみます。ありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問