d3-csv-barchart-button
テーブル記法で書かれたデータを取得し、棒グラフを描く
サンプルデータ
りんごの生産量 2019年産
table:data
name value
青森県 409800
長野県 127600
岩手県 45900
山形県 40500
福島県 23200
秋田県 23100
北海道 8050
群馬県 8040
宮城県 2590
岐阜県 1590
↓アイコン用画像
https://gyazo.com/6a10aca8b5c9e7aa0f1ffebad7c1b10d
https://gyazo.com/74e3b3d329673588a283bce4553163d8
code:button.js
(function () {
let D3js = document.getElementById('__D3js__')
if (!D3js) {
D3js = document.createElement("script");
D3js.id = '__D3js__'
D3js.src = '//cdnjs.cloudflare.com/ajax/libs/d3/6.2.0/d3.min.js'
document.head.appendChild(D3js);
}
let chart = document.getElementById('__bar__')
if (chart){
//console.log("nop")
// リロードしてリセット
location.reload(false)
} else {
chart = document.createElement("script");
chart.id = '__bar__'
chart.src = '/api/code/villagepump/d3-csv-barchart-button/d3script.js'
//console.log("chart")
document.body.appendChild(chart);
}
})()
code:d3script.js
const width = 800;
const height = 500;
const margin = 5;
const padding = 40;
const adj = 10;
const svg = d3.select("#editor").append("svg")
.attr("preserveAspectRatio", "xMinYMin meet")
.attr("viewBox", "-" + adj + " -"+ adj + " " + (width + adj) + " " + (height + adj*2))
.style("padding", padding)
.style("margin", margin)
const dataset = d3.csv(/api/table/${scrapbox.Project.name}/${encodeURIComponent(scrapbox.Page.title)}/data.csv)
dataset.then((data)=> {
data.map((d)=> {
d.value = +d.value
return d
})
})
dataset.then((data)=> {
const xScale = d3.scaleBand()
.padding(0.1)
.domain(data.map((d)=> d.name))
const yScale = d3.scaleLinear()
//console.log(dataset)
svg.append("g")
.attr("class", "axis")
.attr("transform", "translate(" + 0 + "," + (height - padding) + ")")
.call(d3.axisBottom(xScale));
svg.append("g")
.attr("class", "axis")
.attr("transform", "translate(" + padding + "," + 0 + ")")
.call(d3.axisLeft(yScale));
dataset.then((data)=> {
svg.append("g")
.selectAll("rect")
.data(data)
.enter().append("rect")
.attr("class", "bar")
.attr("x", (d)=> xScale(d.name))
.attr("y", (d)=> yScale(d.value))
.attr("width", xScale.bandwidth())
.attr("height", (d)=> height - padding - yScale(d.value))
.attr("fill", "steelblue")
})
})
code:button2.js
import {installCDN} from '/api/code/villagepump/install-CDN/script.js';
export async function execute() {
//const promise = fetch(/api/table/${scrapbox.Project.name}/${encodeURIComponent(scrapbox.Page.title)}/data.csv);
await installCDN({id: '__D3js__', src: '//cdnjs.cloudflare.com/ajax/libs/d3/6.2.0/d3.min.js'});
const {BarChart} = await import('/api/code/villagepump/d3-csv-barchart-button/barChart.js');
//const csv = await promise;
//const barChart = new BarChart({id: '__bar__', csv: csv});
const barChart = new BarChart({id: '__bar__'});
if (barChart.remove()) {
return;
}
barChart.draw();
}
途中まで書いて放置してあります
d3.jsの使い方がよくわからない
動くようにした
ありがとうございます
CSVファイルはd3.jsの方法で読み込む
CSV fileはBarChartから分離させてとっかえひっかえできるようにしたほうが取り回しがしやすいと思ったのですが、どうでしょうか?
csv_data.map((csv, i) => new BarChart({id: \`__bar__${i}\`, csv: csv}))).draw()みたいなことができる
まあそこを中途半端に外部から指定できるようにするなら、width,heightなんかも外部から指定できるようにして汎用性を高めたほうが設計としてまともなのでしょうが……
code:barChart.js
const width = 800;
const height = 500;
const margin = 5;
const padding = 40;
const adj = 10;
export class BarChart {
constructor({id}) {
this.id = id;
}
async draw() {
const svg = d3.select("#editor").append("svg")
.attr("id", this.id)
.attr("preserveAspectRatio", "xMinYMin meet")
.attr("viewBox", -${adj} -${adj} ${width + adj} ${height + adj*2})
.style("padding", padding)
.style("margin", margin)
const data = await d3.csv(/api/table/${scrapbox.Project.name}/${encodeURIComponent(scrapbox.Page.title)}/data.csv)
data.forEach(d => {
d.value = +d.value;
})
const xScale = d3.scaleBand()
.padding(0.1)
.domain(data.map(d => d.name))
const yScale = d3.scaleLinear()
svg.append("g")
.attr("class", "axis")
.attr("transform", translate(0, ${height - padding}))
.call(d3.axisBottom(xScale));
svg.append("g")
.attr("class", "axis")
.attr("transform", translate(${padding}, 0))
.call(d3.axisLeft(yScale));
svg.append("g")
.selectAll("rect")
.data(data)
.enter().append("rect")
.attr("class", "bar")
.attr("x", d => xScale(d.name))
.attr("y", d => yScale(d.value))
.attr("width", xScale.bandwidth())
.attr("height", d => height - padding - yScale(d.value))
.attr("fill", "steelblue")
}
remove() {
const chart = document.getElementById(this.id);
if (!chart) return false;
// 既にchartがある場合は削除する
console.log('The chart already exists. Removing it...');
$(chart).remove();
return true;
}
}
d3-csv-barchart-button.icon ←実行ボタン